อักขระ Unicode หนึ่งตัวต้องใช้กี่ไบต์


239

ฉันสับสนเล็กน้อยเกี่ยวกับการเข้ารหัส เท่าที่ฉันรู้ว่าอักขระ ASCII เก่านั้นใช้อักขระหนึ่งไบต์ต่ออักขระ อักขระ Unicode ต้องการจำนวนไบต์?

ฉันสมมติว่าอักขระ Unicode หนึ่งตัวสามารถมีตัวละครที่เป็นไปได้ทุกภาษาจากทุกภาษาฉันจะแก้ไขไหม? ดังนั้นต้องมีกี่ไบต์ต่อตัวอักษร?

UTF-7, UTF-6, UTF-16 ฯลฯ หมายถึงอะไร? พวกเขาเป็นรุ่นที่แตกต่างกันของ Unicode หรือไม่?

ฉันอ่านบทความ Wikipedia เกี่ยวกับ Unicodeแต่มันค่อนข้างยากสำหรับฉัน ฉันรอคอยที่จะเห็นคำตอบง่ายๆ



15
ขออภัยไม่มีคำตอบง่ายๆ ฉันพบว่าสิ่งทั้งหมดเป็นระเบียบ Unicode ถูกเรียกเก็บเงินโดยใช้สองไบต์และสามารถแสดงอักขระทั้งหมด แต่ปรากฎว่ามีสองไบต์ไม่เพียงพอ
Jonathan Wood

12
"คำตอบง่าย ๆ ": อักขระ Unicode ใช้เวลา 1-4 ไบต์ Unicode ครอบคลุมภาษาจำนวนมาก แต่ไม่ใช่ทั้งหมด ครั้งสุดท้ายที่ฉันดูตัวอย่าง Klingon ไม่ใช่ชุดอักขระ Unicode อย่างเป็นทางการ
Peter G.

9
คลิงออนไม่ได้เป็นส่วนหนึ่งของมาตรฐานยูนิโคดนั่นเอง มันใช้พื้นที่ใช้งานส่วนตัวของ Uniode (U + F8D0 - U + F8FF) แทน
Remy Lebeau

1
คำถามของผู้ช่วยให้รอด - ขอบคุณ สถานการณ์ของฉันจัดเก็บข้อมูลผ่าน LMS ที่สอดคล้องกับ SCORM 1.2 มาตรฐานสำหรับ SCORM 1.2 'cmi.suspend_data' คือ 4096 ไบต์ของข้อมูลซึ่งนักพัฒนาคนก่อนสันนิษฐานว่าเราสามารถเก็บอักขระได้ถึง 4096 ตัว โอ้มนุษย์เขาผิด - ฉันเพิ่งค้นพบว่าทำไมการบุ๊คมาร์คของเราถึงล้มเหลวในหลักสูตรระยะยาว ตอนนี้ฉันรู้แล้วว่าเรากำลังใช้ UTF-8 มันใช้เวลา 4 ไบต์ต่อตัวละครซึ่งมี 1024 ตัวอักษร
danjah

คำตอบ:


147

คุณจะไม่เห็นคำตอบง่าย ๆ เพราะไม่มี

อันดับแรก Unicode ไม่มี "อักขระทุกตัวจากทุกภาษา" แม้ว่าจะแน่ใจว่าได้ลองแล้ว

Unicode ตัวเองเป็นการทำแผนที่จะกำหนด codepoints และ codepoint เป็นตัวเลขที่เกี่ยวข้องกับมักจะเป็นตัวละคร ฉันมักจะพูดเพราะมีแนวคิดเหมือนการรวมตัวละคร คุณอาจคุ้นเคยกับสิ่งต่าง ๆ เช่นสำเนียงหรือ umlauts สิ่งเหล่านั้นสามารถใช้กับตัวละครอื่นเช่นaa หรือ a uเพื่อสร้างตัวละครแบบลอจิคัลใหม่ ดังนั้นตัวละครอาจประกอบด้วย codepoints 1 ตัวขึ้นไป

เพื่อให้มีประโยชน์ในระบบคอมพิวเตอร์เราจำเป็นต้องเลือกตัวแทนสำหรับข้อมูลนี้ สิ่งเหล่านี้คือการเข้ารหัส Unicode ต่าง ๆ เช่น utf-8, utf-16le, utf-32 เป็นต้นพวกมันมีความแตกต่างกันอย่างมากจากขนาดของหน่วยโค้ด UTF-32 เป็นการเข้ารหัสที่ง่ายที่สุด แต่ก็มีโค้ดยูนิตที่ 32 บิตซึ่งหมายความว่ารหัสสมาชิกแต่ละรหัสพอดีกับโค้ดยูนิต การเข้ารหัสอื่นจะมีสถานการณ์ที่ codepoint ต้องการโค้ดยูนิตหลายอันหรือ codepoint นั้นไม่สามารถแสดงในการเข้ารหัสได้เลย (นี่เป็นปัญหาสำหรับอินสแตนซ์ของ UCS-2)

เนื่องจากความยืดหยุ่นในการรวมอักขระแม้ในการเข้ารหัสที่กำหนดจำนวนไบต์ต่ออักขระอาจแตกต่างกันไปขึ้นอยู่กับอักขระและรูปแบบการทำให้เป็นมาตรฐาน นี่คือโปรโตคอลสำหรับการจัดการกับตัวละครที่มีตัวแทนมากกว่าหนึ่ง (คุณสามารถพูดได้ว่า"an 'a' with an accent"เป็น 2 codepoints ซึ่งหนึ่งในนั้นคือการรวมถ่านหรือ"accented 'a'"ที่เป็นหนึ่ง codepoint)


1
ตกลง. จากนั้นมีกี่ไบต์ที่รับหนึ่งอักขระที่แสดงใน codepoint ตัวอย่างเช่นพื้นที่ไม่ทำลาย
Nicolas Barbulesco

อักขระที่รวมกันทำให้ชีวิตของโปรแกรมเมอร์เป็นนรกเมื่อพูดถึงการเขียน strlen (), substr () และฟังก์ชั่นการจัดการสตริงอื่น ๆ ในอาร์เรย์ UTF8 งานประเภทนี้จะไม่เสร็จสมบูรณ์และบั๊กกี้เสมอ
Nulik

ผมเขียนสาธิตที่แสดงให้เห็นว่าใช้ Windows 1252 UTF8 และ UTF8-BOM ไฟล์ที่เข้ารหัสตีความกับแต่ละการเข้ารหัสและเปรียบเทียบความเท่าเทียมกันระหว่างผล: github.com/vladyrn/encodings_demo
Vlad

195

น่าประหลาดใจที่ไม่มีใครชี้ให้เห็นว่าจะคำนวณจำนวนไบต์ที่ใช้กับอักขระ Unicode หนึ่งตัวได้อย่างไร นี่คือกฎสำหรับสตริงที่เข้ารหัส UTF-8:

Binary    Hex          Comments
0xxxxxxx  0x00..0x7F   Only byte of a 1-byte character encoding
10xxxxxx  0x80..0xBF   Continuation byte: one of 1-3 bytes following the first
110xxxxx  0xC0..0xDF   First byte of a 2-byte character encoding
1110xxxx  0xE0..0xEF   First byte of a 3-byte character encoding
11110xxx  0xF0..0xF7   First byte of a 4-byte character encoding

ดังนั้นคำตอบอย่างรวดเร็วคือ: ใช้เวลา 1 ถึง 4 ไบต์ขึ้นอยู่กับคำตอบแรกซึ่งจะระบุจำนวนไบต์ที่จะใช้


8
ฉันเชื่อว่าค่า Hex สูงสุดสำหรับอักขระ 4 ไบต์คือ 0xF7 (ไม่ใช่ 0xF4)
DJPJ

ขอบคุณมาก! ฉันแค่ควบคุม + f'ing ผ่านมาตรฐาน IETF และฉันไม่พบอะไรเกี่ยวกับการเข้ารหัสและบทความที่ฉันอ่านไม่ได้ลงรายละเอียดมากพอที่จะบอกได้ว่ามีการใช้บิตจำนวนเท่าใดเพื่อแสดงจำนวนรหัสต่อท้าย คะแนนต่อ "ตัวละคร"
MarcusJ

1
ตอนนี้อยู่ในหน้าสองของแผ่นชีท "การแนะนำสำหรับสมาชิกใหม่ของทีม" พร้อมกับความคิดเห็นสองข้อแรกที่เฮฮา
Cee McSharpface

1
0xF4 ไม่ใช่ข้อผิดพลาด แต่เป็นคำชี้แจง Unicode codepoints อยู่ในช่วง 0-0x10ffff ดังนั้น codepoint ล่าสุดจะถูกเข้ารหัสเป็น F4 8F BF BF
Frediano Ziglio

38

ฉันรู้ว่าคำถามนี้เก่าและมีคำตอบที่ยอมรับแล้ว แต่ฉันต้องการนำเสนอตัวอย่างเล็ก ๆ น้อย ๆ (หวังว่าจะเป็นประโยชน์กับใครบางคน)

เท่าที่ฉันรู้ว่าอักขระ ASCII เก่านั้นใช้อักขระหนึ่งไบต์ต่ออักขระ

ขวา. ที่จริงแล้วเนื่องจาก ASCII เป็นการเข้ารหัสแบบ 7 บิตจึงสนับสนุนรหัส 128 รหัส (95 รหัสสามารถพิมพ์ได้) ดังนั้นจึงใช้เพียงครึ่งไบต์ (หากมีเหตุผล)

อักขระ Unicode ต้องการจำนวนไบต์?

Unicode เพียงแมปอักขระกับ codepoints มันไม่ได้กำหนดวิธีการเข้ารหัส ไฟล์ข้อความไม่มีอักขระ Unicode แต่ไบต์ / octets ที่อาจแสดงถึงอักขระ Unicode

ฉันสมมติว่าอักขระ Unicode หนึ่งตัวสามารถมีตัวละครที่เป็นไปได้ทุกภาษาจากทุกภาษาฉันจะแก้ไขไหม?

เลขที่ แต่เกือบ ใช่แล้ว แต่ก็ยังไม่มี

ดังนั้นต้องมีกี่ไบต์ต่อตัวอักษร?

เช่นเดียวกับคำถามที่ 2 ของคุณ

UTF-7, UTF-6, UTF-16 ฯลฯ หมายถึงอะไร? พวกเขาบางรุ่น Unicode ชนิด?

ไม่พวกเขากำลังเข้ารหัส พวกเขากำหนดวิธีไบต์ / octets ควรเป็นตัวแทนของตัวละคร Unicode

ตัวอย่างบางส่วน หากบางรายการไม่สามารถแสดงในเบราว์เซอร์ของคุณ (อาจเป็นเพราะตัวอักษรไม่รองรับ) ให้ไปที่http://codepoints.net/U+1F6AA(แทนที่1F6AAด้วย codepoint เป็น hex) เพื่อดูภาพ

    • U + 0061 LATIN เล็กอักษร A: a
      • Nº: 97
      • UTF-8: 61
      • UTF-16: 00 61
    • เครื่องหมายลิขสิทธิ์ U + 00A9: ©
      • Nº: 169
      • UTF-8: C2 A9
      • UTF-16: 00 A9
    • เครื่องหมาย U + 00AE ที่ลงทะเบียน: ®
      • Nº: 174
      • UTF-8: C2 AE
      • UTF-16: 00 AE
    • U + 1337 ชาติพันธุ์ศรีวัฒน์ที่สลับซับซ้อน:
      • Nº: 4919
      • UTF-8: E1 8C B7
      • UTF-16: 13 37
    • U + 2014 EM DASH:
      • Nº: 8212
      • UTF-8: E2 80 94
      • UTF-16: 20 14
    • U + 2030 ต่อการเข้าสู่ระบบ MILLE:
      • Nº: 8240
      • UTF-8: E2 80 B0
      • UTF-16: 20 30
    • สัญญาณยูโร U + 20AC:
      • Nº: 8364
      • UTF-8: E2 82 AC
      • UTF-16: 20 AC
    • เครื่องหมายการค้าของ U + 2122:
      • Nº: 8482
      • UTF-8: E2 84 A2
      • UTF-16: 21 22
    • U + 2603 SNOWMAN:
      • Nº: 9731
      • UTF-8: E2 98 83
      • UTF-16: 26 03
    • U + 260E โทรศัพท์ดำ:
      • Nº: 9742
      • UTF-8: E2 98 8E
      • UTF-16: 26 0E
    • U + 2614 ร่มพร้อมกับ RAIN DROPS:
      • Nº: 9748
      • UTF-8: E2 98 94
      • UTF-16: 26 14
    • U + 263A หน้าขาวยิ้มแย้ม:
      • Nº: 9786
      • UTF-8: E2 98 BA
      • UTF-16: 26 3A
    • U + 2691 ธงดำ:
      • Nº: 9873
      • UTF-8: E2 9A 91
      • UTF-16: 26 91
    • สัญลักษณ์ U + 269B อะตอม:
      • Nº: 9883
      • UTF-8: E2 9A 9B
      • UTF-16: 26 9B
    • เครื่องบิน U + 2708:
      • Nº: 9992
      • UTF-8: E2 9C 88
      • UTF-16: 27 08
    • U + 271E SHADOWED LATIN LATIN CROSS:
      • Nº: 10014
      • UTF-8: E2 9C 9E
      • UTF-16: 27 1E
    • ใบหน้ามาร์ค POSTAL U + 3020:
      • Nº: 12320
      • UTF-8: E3 80 A0
      • UTF-16: 30 20
    • U + 8089 CJK UNIFIED IDEOGRAPH-8089:
      • Nº: 32905
      • UTF-8: E8 82 89
      • UTF-16: 80 89
    • U + 1F4A9 กอง POO: 💩
      • Nº: 128169
      • UTF-8: F0 9F 92 A9
      • UTF-16: D8 3D DC A9
    • U + 1F680 ROCKET: 🚀
      • Nº: 128640
      • UTF-8: F0 9F 9A 80
      • UTF-16: D8 3D DE 80

โอเคฉันถูกพาไป ...

ข้อเท็จจริงสนุก:

  • หากคุณกำลังมองหาตัวอักษรที่เฉพาะเจาะจงคุณสามารถคัดลอกและวางไว้บนhttp://codepoints.net/
  • ฉันเสียเวลาไปกับรายการที่ไร้ประโยชน์นี้ (แต่มันก็เรียงลำดับ!)
  • MySQL มีชุดอักขระที่เรียกว่า "utf8" ซึ่งจริงๆแล้วไม่รองรับอักขระที่ยาวเกิน 3 ไบต์ ดังนั้นคุณไม่สามารถแทรกกองปูได้สนามจะถูกตัดอย่างเงียบ ๆ ใช้ "utf8mb4" แทน
  • มีเป็นหน้าทดสอบมนุษย์หิมะ (unicodesnowmanforyou.com)

หน่วยรหัส UTF-16 16 บิตกว้าง คุณแสดงให้พวกเขาเห็นว่ามีช่องว่างตรงกลางซึ่งทำให้เข้าใจผิด UTF-16 เป็นตัวแทน©ค่อนข้างควรจะ00A9แทน00 A9(ซึ่งจะเป็น UTF-16BE)
Roland Illig

ความแตกต่างคืออะไร? ไม่สามารถทนกับคน Endian ใหญ่ ๆ ได้หรือ เขาเขียนมันใน endian ที่ยิ่งใหญ่และดังนั้นไฟล์ที่เขียนใน UTF-16 ใหญ่ก็จะเหมือนกับ UTF-16BE ใช่ไหม?
HappyPandaFace

6
การแก้ไข: 1) ASCII คือ 7 บิตไบต์เป็น 8 บิตดังนั้นมันจึงมากกว่าครึ่ง 2) Unicode จะกำหนดวิธีเข้ารหัสจุดรหัส UTF-8, UTF-16 และ UTF-32 ถูกกำหนดไว้ใน Unicode Standard
Jonathan Rosenne

3
@ JonathanRosenne ฉันคิดว่า s / เขาหมายถึงมันใช้เพียงครึ่งหนึ่งของค่าที่เป็นไปได้ที่สามารถแทนได้ด้วย 8 บิตไม่ใช่ว่าจะใช้ครึ่งหนึ่งของบิต
Aritz Lopez

2
ฉันชอบตัวอย่างมาก พวกเขาเน้นว่าทำไมบางคนอาจชอบ UTF-16 มากกว่า UTF-8 เป็นต้น ผู้พัฒนาซอฟต์แวร์ที่แตกต่างกันอาจเลือกการเข้ารหัสที่แตกต่างกันโดยขึ้นอยู่กับว่าอักขระ Unicode ใดมีแนวโน้มที่จะใช้ ในประเทศจีน / ญี่ปุ่นเช่น UTF-16 (2 ไบต์) ทำให้รู้สึกมากขึ้นกว่า UTF-8 สำหรับพวกเขาเพราะตัวอักษรเดียวกันมักจะต้องเป็นสองเท่าจำนวนไบต์ที่จะเข้ารหัส UTF-8
ไมค์

29

เพียงแค่พูดUnicodeเป็นมาตรฐานที่กำหนดหนึ่งหมายเลข (เรียกว่าจุดรหัส) กับตัวละครทุกตัวของโลก (ยังคงทำงานอยู่ในความคืบหน้า)

character encodingตอนนี้คุณต้องเป็นตัวแทนของจุดรหัสนี้โดยใช้ไบต์ครับที่เรียกว่า UTF-8, UTF-16, UTF-6เป็นวิธีในการเป็นตัวแทนของตัวละครเหล่านั้น

UTF-8เป็นการเข้ารหัสอักขระหลายไบต์ อักขระสามารถมีได้ 1 ถึง 6 ไบต์ (บางตัวอาจไม่จำเป็นในตอนนี้)

UTF-32 อักขระแต่ละตัวมี 4 ไบต์ต่ออักขระ

UTF-16ใช้ 16 บิตสำหรับตัวละครแต่ละตัวและมันเป็นเพียงส่วนหนึ่งของตัวละคร Unicode ที่เรียกว่า BMP (สำหรับวัตถุประสงค์ในทางปฏิบัติทั้งหมดมันเพียงพอ) Java ใช้การเข้ารหัสนี้ในสตริง


10
Unicode เป็นชุดรหัส 21 บิตและ 4 ไบต์เพียงพอที่จะแสดงถึงอักขระ Unicode ใด ๆ ใน UTF-8 UTF-16 ใช้ตัวแทนแทนที่ตัวละครนอก BMP (ระนาบหลายภาษาพื้นฐาน); ต้องการทั้ง 2 หรือ 4 ไบต์เพื่อแสดงอักขระ Unicode ที่ถูกต้อง UCS-2 เป็นตัวแปรเฉพาะ UTF-16 แบบ 16 บิตโดยไม่สนับสนุนตัวแทนหรือตัวละครนอก BMP
Jonathan Leffler

1
คุณถูก. UTF-8 ดั้งเดิมมีขนาด 6 ไบต์เพื่อรองรับ 32 บิต จริง ๆ แล้วฉันไม่ต้องการที่จะทำให้สิ่งต่าง ๆ ซับซ้อนเท่าที่เขาสับสนกับวิกิเอกสารแล้ว :)
Zimbabao

3
คำตอบนี้ระบุว่า UTF-16 ไม่สามารถเข้ารหัสรหัสจุด BMP ได้ สิ่งนี้ไม่ถูกต้องเนื่องจากสามารถเข้ารหัสได้เช่นเดียวกับใน UTF-8 โดยใช้คู่ตัวแทน (คุณต้องนึกถึง UCS-2 ที่ล้าสมัยก่อนที่ Unicode 2.0 จะออกมาซึ่งเข้ารหัสจุดรหัส 16 บิตเท่านั้น) นอกจากนี้ Java ยังไม่ได้ใช้ UTF-16 แต่ใช้รูปแบบที่ถูกดัดแปลงที่จุดโค้ด 0 ถูกเข้ารหัสแตกต่างกัน
rdb

@rdb - มันตรงกันข้าม คำตอบบอกว่า UTF-16 แสดงถึง BMP
นิโคลัส Barbulesco

3
ฉันพิมพ์ผิด ฉันตั้งใจจะพูดว่า "ไม่ใช่ BMP" ข้อผิดพลาดในคำตอบคือมันบอกว่า UTF-16 แสดงถึงตัวอักษร BMP ซึ่งไม่ถูกต้อง UTF-16 สามารถเข้ารหัสอักขระ Unicode ทั้งหมด - อักขระที่ไม่ใช่ BMP จะถูกเข้ารหัสผ่านคู่ตัวแทน บางทีผู้ตอบอาจสับสนกับ UCS-2
rdb

17

ใน UTF-8:

1 byte:       0 -     7F     (ASCII)
2 bytes:     80 -    7FF     (all European plus some Middle Eastern)
3 bytes:    800 -   FFFF     (multilingual plane incl. the top 1792 and private-use)
4 bytes:  10000 - 10FFFF

ใน UTF-16:

2 bytes:      0 -   D7FF     (multilingual plane except the top 1792 and private-use )
4 bytes:   D800 - 10FFFF

ใน UTF-32:

4 bytes:      0 - 10FFFF

10FFFF เป็นตัวถอดรหัสแบบยูนิโคดตัวสุดท้ายตามคำนิยามและมันถูกกำหนดด้วยวิธีนี้เนื่องจากเป็นข้อ จำกัด ทางเทคนิคของ UTF-16

นอกจากนี้ยังเป็น codepoint ที่ใหญ่ที่สุด UTF-8 สามารถเข้ารหัสใน 4 ไบต์ แต่ความคิดที่อยู่เบื้องหลังการเข้ารหัส UTF-8 ยังใช้งานได้สำหรับการเข้ารหัส 5 และ 6 ไบต์เพื่อครอบคลุม codepoints จนถึง 7FFFFFFF เช่น ครึ่งหนึ่งของสิ่งที่ UTF-32 สามารถทำได้


8

ใน Unicode คำตอบนั้นไม่ง่ายนัก ปัญหาดังที่คุณได้ชี้ให้เห็นแล้วคือการเข้ารหัส

เมื่อได้รับประโยคภาษาอังกฤษที่ไม่มีอักขระกำกับการออกเสียงคำตอบสำหรับ UTF-8 จะมีจำนวนไบต์เท่ากับตัวอักษรและสำหรับ UTF-16 จะมีจำนวนอักขระเป็นสองเท่า

การเข้ารหัสเฉพาะที่ (ณ ตอนนี้) เราสามารถสร้างคำสั่งเกี่ยวกับขนาดคือ UTF-32 มีเสมอ 32 บิตต่อตัวละครแม้ว่าฉันจะจินตนาการว่ารหัสคะแนนนั้นถูกเตรียมไว้สำหรับ UTF-64 ในอนาคต :)

อะไรทำให้มันยากอย่างน้อยสองอย่าง:

  1. อักขระที่ประกอบขึ้นซึ่งแทนที่จะใช้ตัวอักขระที่เน้นเสียง / กำกับ (itic) ผู้ใช้จึงตัดสินใจรวมสำเนียงและอักขระพื้นฐาน (`A)
  2. จุดรหัส จุดรหัสเป็นวิธีการที่การเข้ารหัส UTF อนุญาตให้เข้ารหัสมากกว่าจำนวนบิตที่ให้พวกเขาชื่อพวกเขามักจะอนุญาต เช่น UTF-8 กำหนดไบต์ที่แน่นอนซึ่งไม่ถูกต้อง แต่เมื่อตามด้วยไบต์ต่อเนื่องที่ถูกต้องจะอนุญาตให้อธิบายอักขระเกินช่วง 8 บิต 0..255 ดูตัวอย่างและการเข้ารหัสที่มากเกินไปด้านล่างในบทความ Wikipedia ที่ UTF-8
    • ตัวอย่างที่ดีให้มีที่€ตัวอักษร (จุดรหัสU+20ACสามารถแสดงทั้งสามไบต์ลำดับE2 82 ACหรือสี่ไบต์F0 82 82 ACลำดับ
    • ทั้งสองถูกต้องและสิ่งนี้แสดงให้เห็นว่าความซับซ้อนของคำตอบคือเมื่อพูดถึง "Unicode" และไม่เกี่ยวกับการเข้ารหัสเฉพาะของ Unicode เช่น UTF-8 หรือ UTF-16


4

ฉันเพิ่งดึงหน้า Wikipedia ขึ้นมาด้วยเช่นกันและในส่วนบทนำฉันเห็นว่า "Unicode สามารถใช้งานได้โดยการเข้ารหัสอักขระที่แตกต่างกันการเข้ารหัสที่ใช้บ่อยที่สุดคือ UTF-8 (ซึ่งใช้หนึ่งไบต์สำหรับอักขระ ASCII ใด ๆ ที่มี ค่ารหัสเดียวกันในการเข้ารหัส UTF-8 และ ASCII และสูงสุดสี่ไบต์สำหรับอักขระอื่น) UCS-2 ล้าสมัยแล้ว (ซึ่งใช้สองไบต์สำหรับอักขระแต่ละตัว แต่ไม่สามารถเข้ารหัสอักขระทุกตัวในมาตรฐาน Unicode ปัจจุบัน) "

ตามที่อ้างนี้แสดงให้เห็นว่าปัญหาของคุณคือการที่คุณสมมติว่า Unicode เป็นวิธีการเข้ารหัสอักขระเดียว จริง ๆ แล้วมี Unicode หลายรูปแบบและอีกครั้งในเครื่องหมายคำพูดหนึ่งในนั้นมี 1 ไบต์ต่ออักขระเช่นเดียวกับที่คุณคุ้นเคย

ดังนั้นคำตอบง่ายๆที่คุณต้องการคือมันแตกต่างกันไป


3

สำหรับ UTF-16 อักขระต้องการสี่ไบต์ (สองหน่วยรหัส) หากเริ่มต้นด้วย 0xD800 หรือสูงกว่า ตัวละครเช่นนี้เรียกว่า "คู่ตัวแทน" โดยเฉพาะอย่างยิ่งคู่ตัวแทนมีรูปแบบ:

[0xD800 - 0xDBFF]  [0xDC00 - 0xDFF]

โดยที่ [... ] หมายถึงหน่วยรหัสสองไบต์พร้อมช่วงที่กำหนด สิ่งใด <= 0xD7FF คือหน่วยโค้ดหนึ่งหน่วย (สองไบต์) อะไรก็ได้ = 0xE000 ไม่ถูกต้อง (ยกเว้นตัวบ่งชี้ BOM เนื้อหา)

ดูที่http://unicodebook.readthedocs.io/unicode_encodings.htmlส่วนที่ 7.5



1

จาก Wiki:

UTF-8 การเข้ารหัสความกว้างตัวแปร 8 บิตซึ่งเพิ่มความเข้ากันได้กับ ASCII สูงสุด

UTF-16, การเข้ารหัสความกว้างตัวแปร 16 บิต;

UTF-32 การเข้ารหัสความกว้างคงที่ 32 บิต

นี่เป็นการเข้ารหัสที่แตกต่างกันสามส่วนที่ได้รับความนิยมมากที่สุด

  • ใน UTF-8 อักขระแต่ละตัวจะถูกเข้ารหัสเป็น 1 ถึง 4 ไบต์ (การเข้ารหัสที่โดดเด่น)
  • ใน UTF16 อักขระแต่ละตัวจะถูกเข้ารหัสเป็น 1 ถึงสองคำ 16 บิตและ
  • ใน UTF-32 อักขระทุกตัวจะถูกเข้ารหัสเป็นคำเดียว 32 บิต

1

Unicodeเป็นมาตรฐานที่ให้หมายเลขเฉพาะสำหรับตัวละครทุกตัว ตัวเลขที่ไม่ซ้ำกันเหล่านี้เรียกว่าcode points (ซึ่งเป็นรหัสที่ไม่ซ้ำกัน) สำหรับตัวละครทั้งหมดที่มีอยู่ในโลก (บางส่วนจะยังคงถูกเพิ่ม)

เพื่อจุดประสงค์ที่แตกต่างกันคุณอาจต้องแสดงสิ่งนี้เป็นcode pointsไบต์ (ภาษาการเขียนโปรแกรมส่วนใหญ่ทำเช่นนั้น) และนี่คือจุดCharacter Encodingเริ่มต้น

UTF-8, UTF-16, UTF-32และอื่น ๆ ที่มีอยู่ทั้งหมดCharacter Encodingsและ Unicode ของจุดรหัสจะเป็นตัวแทนในการเข้ารหัสเหล่านี้ในรูปแบบที่แตกต่างกัน


UTF-8 การเข้ารหัสมีความยาวผันแปรได้และอักขระที่เข้ารหัสสามารถรวม 1 ถึง 4 ไบต์ได้

UTF-16มีความยาวและอักขระผันแปรที่เข้ารหัสสามารถใช้เวลา 1 หรือ 2 ไบต์ (ซึ่งคือ 8 หรือ 16 บิต) สิ่งนี้แสดงถึงส่วนหนึ่งของอักขระ Unicode ทั้งหมดที่เรียกว่า BMP (Basic Multilingual Plane) และเพียงพอสำหรับเกือบทุกกรณี Java ใช้การUTF-16เข้ารหัสสำหรับสตริงและอักขระ

UTF-32 มีความยาวคงที่และอักขระแต่ละตัวใช้เวลา 4 ไบต์ (32 บิต)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.