Berapa banyak karakter yang dapat dikodekan oleh UTF-8?

97

Jika UTF-8 adalah 8 bit, bukan berarti hanya boleh ada maksimal 256 karakter yang berbeda?

128 poin kode pertama sama seperti di ASCII. Tetapi dikatakan bahwa UTF-8 dapat mendukung hingga jutaan karakter?

Bagaimana cara kerjanya?

eMRe
sumber
2
jika Anda dapat mengevaluasi kembali pertanyaan ini karena semua jawaban salah. Baca jawaban saya: stackoverflow.com/a/45042566/124486
Evan Carroll
Dalam enkode UTF-8, UTF-16, UTF-32 dari Unicode, angka adalah jumlah bit dalam unit kodenya , satu atau lebih di antaranya menyandikan titik kode Unicode.
Tom Blodget
1
Saya menjawab pertanyaan ini beberapa waktu yang lalu dalam upaya untuk meluruskannya: alangkah baiknya jika Anda mempertimbangkannya dengan jawaban yang dipilih yang secara harfiah hanya satu kutipan wikipedia yang tidak menceritakan keseluruhan cerita (semoga pembaruan saya jauh lebih jelas)
Evan Carroll

Jawaban:

135

UTF-8 tidak menggunakan satu byte sepanjang waktu, ini 1 hingga 4 byte.

128 karakter pertama (US-ASCII) membutuhkan satu byte.

1.920 karakter berikutnya membutuhkan dua byte untuk dikodekan. Ini mencakup sisa hampir semua huruf Latin, dan juga huruf Yunani, Sirilik, Koptik, Armenia, Ibrani, Arab, Siria, dan Tāna, serta Menggabungkan Tanda Diakritik.

Tiga byte dibutuhkan untuk karakter dalam Basic Multilingual Plane, yang berisi hampir semua karakter yang umum digunakan [12] termasuk kebanyakan karakter China, Jepang dan Korea [CJK].

Empat byte diperlukan untuk karakter di bidang lain Unicode, yang mencakup karakter CJK yang kurang umum, berbagai skrip bersejarah, simbol matematika, dan emoji (simbol piktografik).

sumber: Wikipedia

zwippie
sumber
hai @zwippie saya baru dalam hal ini. Ada sesuatu yang saya tidak mengerti.! BMP menggunakan 2 byte yang Anda katakan adalah 3? Apakah aku salah?
chiperortiz
1
@chiperortiz, BMP memang 16 bit, sehingga dapat dikodekan sebagai UTF-16 dengan panjang konstan per karakter (UTF-16 juga mendukung melampaui 16 bit, tetapi ini adalah praktik yang sulit, dan banyak implementasi tidak mendukungnya). Namun, untuk UTF-8, Anda juga perlu menyandikan berapa lama, jadi Anda kehilangan beberapa bit. Itulah mengapa Anda membutuhkan 3 byte untuk menyandikan BMP lengkap. Ini mungkin tampak boros, tetapi ingat bahwa UTF-16 selalu menggunakan 2 byte, tetapi UTF-8 menggunakan satu byte per karakter untuk sebagian besar karakter bahasa berbasis latin. Membuatnya dua kali lebih kompak.
sanderd17
Inti dari pertanyaan OP terkait dengan mengapa disebut UTF- 8 - ini tidak benar-benar menjawabnya.
jbyrd
40

UTF-8 menggunakan 1-4 byte per karakter: satu byte untuk karakter ascii (128 nilai unicode pertama sama dengan ascii). Tapi itu hanya membutuhkan 7 bit. Jika bit tertinggi ("tanda") ditetapkan, ini menunjukkan awal dari urutan multi-byte; jumlah set bit tinggi berurutan menunjukkan jumlah byte, kemudian 0, dan bit yang tersisa berkontribusi pada nilai. Untuk byte lainnya, dua bit tertinggi adalah 1 dan 0 dan 6 bit sisanya untuk nilainya.

Jadi urutan empat byte akan dimulai dengan 11110 ... (dan ... = tiga bit untuk nilai) kemudian tiga byte dengan masing-masing 6 bit untuk nilai, menghasilkan nilai 21 bit. 2 ^ 21 melebihi jumlah karakter unicode, sehingga semua unicode dapat diekspresikan dalam UTF8.

CodeClown42
sumber
@Tokopedia Tidak, maksud saya 3 byte. Dalam contoh itu, jika byte pertama dari urutan multibyte dimulai 1111, 1 pertama menunjukkan bahwa itu adalah awal dari urutan multibyte, lalu jumlah 1 yang berurutan setelah itu menunjukkan jumlah byte tambahan dalam urutan (jadi yang pertama byte akan dimulai baik 110, 1110, atau 11110).
CodeClown42
Temukan bukti untuk kata-kata Anda di RFC 3629. tools.ietf.org/html/rfc3629#section-3 . Namun, saya tidak mengerti mengapa saya harus menempatkan "10" di awal byte kedua 110xxxxx 10xxxxxx? Mengapa tidak hanya 110xxxxx xxxxxxxx?
kolobok
3
Jawaban yang ditemukan di softwareengineering.stackexchange.com/questions/262227/… . Hanya untuk alasan keamanan (jika satu byte di tengah aliran rusak)
kolobok
@olobok Ah. Sans safety Anda kemudian dapat menyandikan nilai 21-bit dalam 3 byte (3 bit menunjukkan panjang, ditambah 21-bit). : D Mungkin itu tidak terlalu berarti, setidaknya WRT bahasa Barat.
CodeClown42
Saya menduga bahwa NickL menanyakan hal ini tetapi apa yang terjadi dengan sisa bit dalam byte pertama itu jika ... mewakili byte berikutnya, bukan bit?
c6754
27

Menurut tabel ini * UTF-8 harus mendukung:

2 31 = 2.147.483.648 karakter

Namun, RFC 3629 membatasi nilai yang mungkin, jadi sekarang kita dibatasi pada 4 byte , yang memberi kita

2 21 = 2.097.152 karakter

Perhatikan bahwa sebagian besar karakter tersebut "dicadangkan" untuk penggunaan khusus, yang sebenarnya cukup berguna untuk font ikon.

* Wikipedia digunakan menunjukkan tabel dengan 6 byte - mereka telah memperbarui artikel.

2017-07-11: Dikoreksi untuk penghitungan ganda titik kode yang sama yang dikodekan dengan beberapa byte

mpen
sumber
Jawaban ini menghitung dua kali jumlah penyandiaksaraan yang mungkin. Setelah Anda menghitung semua 2 ^ 7, Anda tidak dapat menghitungnya lagi dalam 2 ^ 11, 2 ^ 16, dll. Jumlah penyandiaksaraan yang benar adalah 2 ^ 21 (meskipun tidak semua yang sedang digunakan).
Jimmy
@Jimmy Anda yakin saya menghitung ganda? 0xxxxxxxmemberikan 7 bit yang dapat digunakan, 110xxxxx 10xxxxxxmemberikan 11 lebih - tidak ada tumpang tindih. Byte pertama dimulai dengan 0dalam kasus pertama, dan 1dalam kasus kedua.
mpen
@mpen jadi poin kode apa yang 00000001disimpan dan apa yang 11000000 100000001disimpan?
Evan Carroll
1
@EvanCarroll Uhh .... poin sudah diambil. Tidak menyadari bahwa ada banyak cara untuk menyandikan titik kode yang sama.
mpen
1
Saya terus mencoba menjawab ini sendiri, lihat apakah menurut Anda ini adalah penjelasan dan jawaban yang lebih baik untuk pertanyaan: stackoverflow.com/a/45042566/124486
Evan Carroll
21

Unicode vs UTF-8

Unicode menyelesaikan poin kode ke karakter. UTF-8 adalah mekanisme penyimpanan untuk Unicode. Unicode memiliki spesifikasi. UTF-8 memiliki spesifikasi. Keduanya memiliki batasan yang berbeda. UTF-8 memiliki ikatan ke atas yang berbeda.

Unicode

Unicode ditandai dengan "pesawat". Setiap pesawat membawa 2 16 poin kode. Ada 17 Pesawat di Unicode. Untuk total 17 * 2^16poin kode. Bidang pertama, bidang 0 atau BMP , khusus dalam berat dari apa yang membawa.

Daripada menjelaskan semua nuansa, izinkan saya mengutip artikel di atas tentang pesawat.

17 pesawat dapat menampung 1.114.112 poin kode. Dari jumlah tersebut, 2.048 pengganti, 66 non-karakter, dan 137.468 dicadangkan untuk penggunaan pribadi, menyisakan 974.530 untuk tugas publik.

UTF-8

Sekarang mari kembali ke artikel yang ditautkan di atas,

Skema pengkodean yang digunakan oleh UTF-8 dirancang dengan batas yang jauh lebih besar yaitu 2 31 titik kode (32.768 bidang), dan dapat menyandikan 2 21 titik kode (32 bidang) meskipun dibatasi hingga 4 byte. [3] Karena Unicode membatasi poin kode ke 17 bidang yang dapat dikodekan oleh UTF-16, poin kode di atas 0x10FFFF tidak valid di UTF-8 dan UTF-32.

Jadi Anda dapat melihat bahwa Anda dapat memasukkan barang ke UTF-8 yang bukan Unicode yang valid. Mengapa? Karena UTF-8 mengakomodasi titik kode yang bahkan tidak didukung oleh Unicode.

UTF-8, bahkan dengan batasan empat byte, mendukung 2 21 poin kode, yang jauh lebih dari17 * 2^16

Evan Carroll
sumber
19

2.164.864 "karakter" dapat berpotensi dikodekan oleh UTF-8.

Angka ini adalah 2 ^ 7 + 2 ^ 11 + 2 ^ 16 + 2 ^ 21 yang berasal dari cara kerja encoding:

  • Karakter 1-byte memiliki 7 bit untuk pengkodean 0xxxxxxx(0x00-0x7F)

  • Karakter 2-byte memiliki 11 bit untuk pengkodean 110xxxxx 10xxxxxx(0xC0-0xDF untuk byte pertama; 0x80-0xBF untuk yang kedua)

  • Karakter 3-byte memiliki 16 bit untuk encoding 1110xxxx 10xxxxxx 10xxxxxx(0xE0-0xEF untuk byte pertama; 0x80-0xBF untuk byte lanjutan)

  • Karakter 4-byte memiliki 21 bit untuk encoding 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(0xF0-0xF7 untuk byte pertama; 0x80-0xBF untuk byte lanjutan)

Seperti yang Anda lihat, ini jauh lebih besar dari Unicode saat ini (1.112.064 karakter).

MEMPERBARUI

Perhitungan awal saya salah karena tidak mempertimbangkan aturan tambahan. Lihat komentar untuk jawaban ini untuk lebih jelasnya.

Ruben Reyes
sumber
2
Matematika Anda tidak mematuhi aturan UTF-8 bahwa hanya urutan unit kode terpendek yang diizinkan untuk menyandikan titik kode. Jadi, 00000001 valid untuk U + 0001 tetapi 11110000 10000000 10000000 10000001 tidak. Ref: Tabel 3-7. Urutan Byte UTF-8 yang Dibentuk dengan Baik . Selain itu, pertanyaannya langsung dijawab oleh tabel: Anda tinggal menjumlahkan rentangnya. (Mereka terpisah untuk mengecualikan pengganti untuk UTF-16).
Tom Blodget
Tom - terima kasih atas komentar Anda! Saya tidak menyadari batasan tersebut. Saya melihat tabel 3-7 dan menjalankan angka dan sepertinya ada 1.083.392 kemungkinan urutan yang valid.
Ruben Reyes
6

UTF-8 adalah pengkodean panjang variabel dengan minimal 8 bit per karakter.
Karakter dengan poin kode lebih tinggi akan membutuhkan hingga 32 bit.

menipu
sumber
2
Ini menyesatkan. Titik kode terpanjang yang dapat Anda miliki adalah 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx, jadi hanya 21 bit yang dapat digunakan untuk menyandikan karakter sebenarnya.
Boris
5
Saya mengatakan poin kode dapat memakan waktu hingga 32 bit untuk dikodekan, saya tidak pernah mengklaim bahwa (dengan induksi) Anda dapat menyandikan 2 ^ 32 karakter dalam 32 bit UTF-8. Tapi itu agak diperdebatkan, karena Anda dapat menyandikan semua karakter Unicode yang ada dalam UTF-8, dan Anda dapat menyandikan lebih banyak lagi jika Anda meregangkan UTF-8 menjadi 48 bit (yang ada tetapi tidak digunakan lagi), jadi saya tidak yakin apa poin yang menyesatkan adalah.
menipu
2

Lihat Unicode Standard dan informasi terkait, seperti entri FAQ mereka, UTF-8 UTF-16, UTF-32 & BOM . Tidak semulus itu, tetapi ini adalah informasi yang berwibawa, dan banyak dari apa yang mungkin Anda baca tentang UTF-8 di tempat lain patut dipertanyakan.

"8" dalam "UTF-8" berhubungan dengan panjang unit kode dalam bit. Unit kode adalah entitas yang digunakan untuk menyandikan karakter, tidak harus sebagai pemetaan satu-ke-satu yang sederhana. UTF-8 menggunakan sejumlah variabel unit kode untuk menyandikan karakter.

Kumpulan karakter yang dapat dikodekan dalam UTF-8 sama persis dengan UTF-16 atau UTF-32, yaitu semua karakter Unicode. Mereka semua menyandikan seluruh ruang pengkodean Unicode, yang bahkan mencakup nonkarakter dan poin kode yang belum ditetapkan.

Jukka K. Korpela
sumber
1

Meskipun saya setuju dengan mpen pada kode UTF-8 maksimum saat ini (2.164.864) (tercantum di bawah, saya tidak dapat mengomentarinya), dia mati dengan 2 level jika Anda menghapus 2 batasan utama UTF-8: hanya 4 byte batas dan kode 254 dan 255 tidak dapat digunakan (dia hanya menghapus batas 4 byte).

Kode awal 254 mengikuti pengaturan dasar bit awal (flag multi-bit disetel ke 1, hitungan 6 1, dan terminal 0, tanpa bit cadangan) memberi Anda 6 byte tambahan untuk dikerjakan (6 grup 10xxxxxx, tambahan 2 ^ 36 kode).

Kode awal 255 tidak sepenuhnya mengikuti pengaturan dasar, tidak ada terminal 0 tetapi semua bit digunakan, memberi Anda 7 byte tambahan (bendera multi-bit disetel ke 1, hitungan 7 1, dan tidak ada terminal 0 karena semua bit digunakan ; 7 grup 10xxxxxx, kode tambahan 2 ^ 42).

Menambahkan ini dalam memberikan kumpulan karakter yang dapat ditampilkan maksimum akhir dari 4.468.982.745.216. Ini lebih dari semua karakter yang digunakan saat ini, bahasa lama atau bahasa mati, dan bahasa apa pun yang diyakini hilang. Naskah Angelic atau Celestial siapa?

Juga ada kode byte tunggal yang diabaikan / diabaikan dalam standar UTF-8 selain 254 dan 255: 128-191, dan beberapa lainnya. Beberapa digunakan secara lokal oleh keyboard, contoh kode 128 biasanya menghapus backspace. Kode awal lainnya (dan rentang terkait) tidak valid karena satu atau beberapa alasan ( https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences ).

James V. Fields
sumber
0

Unicode secara resmi menikah dengan UTF-8. Unicode secara khusus mendukung 2 ^ 21 titik kode (2.097.152 karakter) yang merupakan jumlah titik kode yang sama persis yang didukung oleh UTF-8. Kedua sistem mencadangkan ruang 'mati' dan zona terbatas yang sama untuk poin kode dll. ... per Juni 2018 versi terbaru, Unicode 11.0, berisi repertoar 137.439 karakter

Dari standar unicode. FAQ Unicode

Standar Unicode mengkodekan karakter dalam kisaran U + 0000..U + 10FFFF, yang berarti ruang kode 21-bit.

Dari halaman Wikipedia UTF-8. Deskripsi UTF-8

Sejak pembatasan ruang kode Unicode menjadi nilai 21-bit pada tahun 2003, UTF-8 didefinisikan untuk menyandikan titik kode dalam satu hingga empat byte, ...

Nama tampilan
sumber
21 bit dibulatkan. Unicode mendukung 1.114.112 titik kode (U + 0000 hingga U + 10FFFF) seperti yang dikatakannya. (Kadang-kadang digambarkan sebagai 17 pesawat 65536.)
Tom Blodget
@TomBlodget, Anda benar. Hal yang paling relevan dari diskusi ini adalah UTF-8 dapat menyandikan semua poin yang saat ini ditentukan dalam standar Unicode dan kemungkinan akan dapat melakukannya untuk beberapa waktu mendatang.
Nama tampilan