Unicode, UTF-8, UTF-16 คืออะไร


395

พื้นฐานของ Unicode คืออะไรและทำไมต้องใช้ UTF-8 หรือ UTF-16 ฉันได้ค้นคว้าสิ่งนี้บน Google และค้นหาที่นี่เช่นกัน แต่มันก็ไม่ชัดเจนสำหรับฉัน

ใน VSS เมื่อทำการเปรียบเทียบไฟล์บางครั้งมีข้อความแจ้งว่าไฟล์ทั้งสองมีความแตกต่างของ UTF ทำไมถึงเป็นเช่นนี้?

โปรดอธิบายด้วยคำศัพท์ง่ายๆ


123
เสียงเหมือนที่คุณต้องอ่านขั้นต่ำที่แน่นอนนักพัฒนาซอฟต์แวร์ทุกคนแน่นอนต้องรู้เกี่ยวกับ Unicode และชุดอักขระ ! มันเป็นคำอธิบายที่ดีมากเกี่ยวกับสิ่งที่เกิดขึ้น
Brian Agnew


4
@ จอห์น: มันเป็นการแนะนำที่ดีมากแต่มันไม่ใช่แหล่งข้อมูลที่ดีที่สุด: มันข้ามรายละเอียดไปเล็กน้อย (ซึ่งเหมาะสำหรับภาพรวม / แนะนำ!)
Joachim Sauer

5
บทความนี้ยอดเยี่ยม แต่มีข้อผิดพลาดหลายประการและแสดงถึง UTF-8 ในแง่ที่ค่อนข้างอนุรักษ์นิยม ฉันแนะนำให้อ่าน utf8everywhere.org เป็นอาหารเสริม
Pavel Radzivilovsky

2
ดูที่เว็บไซต์นี้: utf8everywhere.org
Vertexwahn

คำตอบ:


550

ทำไมเราต้องใช้ Unicode

ในวันแรก (ไม่มากเกินไป) สิ่งที่มีอยู่ทั้งหมดคือ ASCII ไม่เป็นไรเพราะทุกอย่างที่จำเป็นต้องมีก็คือตัวควบคุมบางตัวเครื่องหมายวรรคตอนตัวเลขและตัวอักษรเหมือนกับตัวละครในประโยคนี้ น่าเสียดายที่โลกที่แปลกประหลาดในปัจจุบันของการสื่อสารระหว่างกันทั่วโลกและโซเชียลมีเดียไม่ได้มองเห็นและมันก็ไม่แปลกเกินกว่าที่จะเห็นภาษาอังกฤษالعربية, 汉语, עִבְרִית, ελληνικάและភាសាខ្មែរในเอกสารเดียวกัน (ฉันหวังว่าฉันจะไม่แก่เลย เบราว์เซอร์)

แต่เพื่อประโยชน์ของการโต้แย้งสมมติว่า Joe Average เป็นผู้พัฒนาซอฟต์แวร์ เขายืนยันว่าเขาต้องการเพียงภาษาอังกฤษเท่านั้นและต้องการใช้ ASCII เท่านั้น นี้อาจจะดีสำหรับโจใช้แต่นี้ไม่ได้ดีสำหรับโจพัฒนาซอฟต์แวร์ ประมาณครึ่งหนึ่งของโลกใช้อักขระที่ไม่ใช่ละตินและการใช้ ASCII นั้นไม่น่าเป็นไปได้สำหรับคนเหล่านี้และยิ่งไปกว่านั้นเขากำลังปิดซอฟต์แวร์ของเขาเพื่อเศรษฐกิจขนาดใหญ่และกำลังเติบโต

ดังนั้นจำเป็นต้องมีชุดอักขระที่ครอบคลุมทุกภาษา ดังนั้น Unicode มา มันกำหนดตัวอักษรเป็นจำนวนเฉพาะที่เรียกว่าทุกจุดรหัส ข้อดีอย่างหนึ่งของ Unicode เหนือชุดที่เป็นไปได้อื่น ๆ คือจุดรหัส 256 จุดแรกนั้นเหมือนกันกับISO-8859-1ดังนั้น ASCII ก็เช่นกัน นอกจากนี้ส่วนใหญ่ของตัวอักษรที่ใช้กันทั่วไปมีแทนได้โดยเฉพาะสองไบต์ในภูมิภาคที่เรียกว่าพูดได้หลายภาษาเครื่องบินขั้นพื้นฐาน (BMP) ตอนนี้จำเป็นต้องใช้การเข้ารหัสอักขระเพื่อเข้าถึงชุดอักขระนี้และเมื่อคำถามถามฉันจะเน้นที่ UTF-8 และ UTF-16

ข้อควรพิจารณาเกี่ยวกับหน่วยความจำ

ดังนั้นมีกี่ไบต์ที่ให้การเข้าถึงอักขระใดในการเข้ารหัสเหล่านี้

  • UTF-8:
    • 1 ไบต์: มาตรฐาน ASCII
    • 2 ไบต์: อาหรับ, ฮิบรู, สคริปต์ยุโรปส่วนใหญ่ (สะดุดตาที่สุดยกเว้นจอร์เจียน )
    • 3 ไบต์: BMP
    • 4 ไบต์: อักขระ Unicode ทั้งหมด
  • UTF-16:
    • 2 ไบต์: BMP
    • 4 ไบต์: อักขระ Unicode ทั้งหมด

มันมูลค่าการกล่าวขวัญว่าตอนนี้ตัวละครที่ไม่ได้อยู่ใน BMP รวมสคริปต์โบราณสัญลักษณ์ทางคณิตศาสตร์, สัญลักษณ์ทางดนตรีและหายากจีน / ญี่ปุ่น / เกาหลี (CJK)ตัวอักษร

หากคุณใช้งานอักขระ ASCII เป็นส่วนใหญ่ UTF-8 จะมีประสิทธิภาพในการใช้หน่วยความจำมากขึ้น อย่างไรก็ตามหากคุณทำงานกับสคริปต์ที่ไม่ได้ใช้ในยุโรปส่วนใหญ่การใช้ UTF-8 อาจทำให้หน่วยความจำมีประสิทธิภาพน้อยกว่า 1.5 เท่าเมื่อเทียบกับ UTF-16 เมื่อต้องจัดการกับข้อความจำนวนมากเช่นหน้าเว็บขนาดใหญ่หรือเอกสารคำที่มีความยาวสิ่งนี้อาจส่งผลกระทบต่อประสิทธิภาพการทำงาน

พื้นฐานการเข้ารหัส

หมายเหตุ: ถ้าคุณรู้วิธีเข้ารหัส UTF-8 และ UTF-16 ให้ข้ามไปยังส่วนถัดไปสำหรับการใช้งานจริง

  • UTF-8:สำหรับอักขระ ASCII (0-127) มาตรฐานรหัส UTF-8 เหมือนกัน สิ่งนี้ทำให้ UTF-8 เหมาะสมที่สุดหากต้องการความเข้ากันได้แบบย้อนหลังกับข้อความ ASCII ที่มีอยู่ อักขระอื่น ๆ ต้องการได้ทุก 2-4 ไบต์ สิ่งนี้ทำได้โดยการสำรองบิตบางส่วนในแต่ละไบต์เหล่านี้เพื่อระบุว่าเป็นส่วนหนึ่งของอักขระแบบหลายไบต์ โดยเฉพาะอย่างยิ่งบิตแรกของแต่ละไบต์คือ1การหลีกเลี่ยงการชนกับอักขระ ASCII
  • UTF-16:สำหรับอักขระ BMP ที่ถูกต้องการแทน UTF-16 เป็นเพียงจุดโค้ด อย่างไรก็ตามสำหรับอักขระที่ไม่ใช่ BMP UTF-16 เปิดตัวตัวแทนคู่ ในกรณีนี้การรวมกันของสองไบต์สองส่วนจะจับคู่กับอักขระที่ไม่ใช่ BMP ส่วนสองไบต์เหล่านี้มาจากช่วงตัวเลข BMP แต่รับประกันโดยมาตรฐาน Unicode ว่าไม่ถูกต้องเป็นอักขระ BMP นอกจากนี้ตั้งแต่ UTF-16 มีสองไบต์เป็นหน่วยพื้นฐานของมันก็เป็นผลกระทบจากendianness เพื่อชดเชยคุณสามารถวางเครื่องหมายคำสั่งไบต์ที่สงวนไว้ไว้ที่จุดเริ่มต้นของสตรีมข้อมูลซึ่งบ่งบอกถึงความ endianness ดังนั้นหากคุณกำลังอ่านอินพุต UTF-16 และไม่ได้ระบุ endianness ไว้คุณต้องตรวจสอบสิ่งนี้

อย่างที่เห็น UTF-8 และ UTF-16 นั้นเข้ากันไม่ได้ซึ่งกันและกัน ดังนั้นหากคุณกำลังทำ I / O ให้แน่ใจว่าคุณรู้ว่าการเข้ารหัสที่คุณกำลังใช้! สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการเข้ารหัสเหล่านี้โปรดดูUTF คำถามที่พบบ่อย

ข้อพิจารณาในการเขียนโปรแกรมเชิงปฏิบัติ

ประเภทข้อมูลอักขระและสตริง:มีการเข้ารหัสในภาษาการเขียนโปรแกรมอย่างไร หากเป็นข้อมูลดิบไบต์นาทีที่คุณพยายามส่งออกอักขระที่ไม่ใช่ ASCII คุณอาจพบปัญหาเล็กน้อย นอกจากนี้แม้ว่าประเภทตัวละครจะขึ้นอยู่กับ UTF แต่นั่นไม่ได้หมายความว่าสายอักขระนั้นเป็น UTF ที่เหมาะสม พวกเขาอาจอนุญาตให้ลำดับไบต์ที่ผิดกฎหมาย โดยทั่วไปคุณจะต้องใช้ไลบรารีที่รองรับ UTF เช่นICUสำหรับ C, C ++ และ Java ไม่ว่าในกรณีใดถ้าคุณต้องการอินพุต / เอาต์พุตอย่างอื่นที่ไม่ใช่การเข้ารหัสเริ่มต้นคุณจะต้องแปลงก่อน

แนะนำ / ค่าเริ่มต้น / การเข้ารหัสที่โดดเด่น:เมื่อได้รับตัวเลือก UTF ที่จะใช้มักจะดีที่สุดในการปฏิบัติตามมาตรฐานที่แนะนำสำหรับสภาพแวดล้อมที่คุณกำลังทำงานตัวอย่างเช่น UTF-8 เป็นสิ่งสำคัญบนเว็บและตั้งแต่ HTML5 ได้รับการเข้ารหัสที่แนะนำ ในทางกลับกันสภาพแวดล้อมทั้ง. NET และ Java นั้นถูกสร้างขึ้นบนประเภทอักขระ UTF-16 การอ้างอิงที่สับสน (และไม่ถูกต้อง) มักมีการอ้างอิงถึง "การเข้ารหัส Unicode" ซึ่งมักจะอ้างถึงการเข้ารหัส UTF ที่โดดเด่นในสภาพแวดล้อมที่กำหนด

การสนับสนุนห้องสมุด:ห้องสมุดที่คุณใช้สนับสนุนการเข้ารหัสบางประเภท อันไหน? พวกเขาสนับสนุนกรณีมุมหรือไม่? เนื่องจากความจำเป็นเป็นแม่ของการประดิษฐ์ไลบรารี UTF-8 โดยทั่วไปจะสนับสนุนอักขระ 4 ไบต์อย่างถูกต้องตั้งแต่ 1, 2 และแม้แต่ 3 ไบต์อักขระสามารถเกิดขึ้นได้บ่อยครั้ง อย่างไรก็ตามไลบรารี UTF-16 ที่อ้างว่าไม่สนับสนุนการจับคู่ตัวแทนอย่างถูกต้องเนื่องจากมันเกิดขึ้นน้อยมาก

การนับอักขระ:มีอักขระการรวมอยู่ใน Unicode ตัวอย่างเช่นจุดรหัส U + 006E (n) และ U + 0303 (ตัวหนอนรวม) รูปแบบñ แต่จุดรหัส U + 00F1 รูปแบบñ ควรมีลักษณะเหมือนกัน แต่อัลกอริทึมการนับอย่างง่ายจะคืนค่า 2 สำหรับตัวอย่างแรกและ 1 สำหรับอันหลัง สิ่งนี้ไม่จำเป็นต้องผิด แต่อาจไม่ใช่ผลลัพธ์ที่ต้องการ

เปรียบเทียบเพื่อความเท่าเทียมกัน: A, АและΑเหมือนกัน แต่พวกมันคือละตินซีริลลิกและกรีกตามลำดับ คุณมีกรณีเช่น C และⅭหนึ่งอันคือตัวอักษรอีกตัวเป็นตัวเลขโรมัน นอกจากนี้เรายังมีตัวละครที่น่าสนใจเช่นกัน สำหรับข้อมูลเพิ่มเติมโปรดดูที่ตัวอักษรที่ซ้ำกันใน Unicode

คู่ตัวแทน: สิ่งเหล่านี้เกิดขึ้นบ่อยพอดังนั้นฉันจะให้ลิงค์ตัวอย่าง:

อื่น ๆ ?:


11
คำตอบที่ยอดเยี่ยมโอกาสที่ยอดเยี่ยมสำหรับเงินรางวัล ;-) โดยส่วนตัวแล้วฉันจะเพิ่มว่าเถียง UTF-8 เป็นการเข้ารหัสตัวละครสากลแต่ฉันรู้ว่านั่นเป็นความคิดเห็นที่ทุกคนไม่จำเป็นต้องแชร์
Joachim Sauer

3
ยังเทคนิคเกินไปสำหรับฉันในขั้นตอนนี้ คำว่า hello ถูกเก็บไว้ในคอมพิวเตอร์ใน UTF-8 และ UTF-16 อย่างไร
นามสกุล

1
คุณสามารถขยายเพิ่มเติมเกี่ยวกับสาเหตุที่ตัวอย่างเช่น BMP ใช้เวลา 3 ไบต์ใน UTF-8 ได้หรือไม่ ฉันคิดว่าเนื่องจากค่าสูงสุดคือ 0xFFFF (16 บิต) จากนั้นจะใช้เวลาเพียง 2 ไบต์ในการเข้าถึง
ทำเครื่องหมาย

2
@mark บางบิตถูกสงวนไว้สำหรับการเข้ารหัส สำหรับจุดโค้ดที่ใช้เวลา 2 ไบต์ใน UTF-8 จะมี 5 บิตสำรองสงวนเหลือเพียง 11 บิตเพื่อเลือกจุดโค้ด U + 07FF กลายเป็นจุดรหัสสูงสุดที่สามารถแทนได้ใน 2 ไบต์
DPenner1

1
BTW - ASCII เพียงกำหนด 128 คะแนนรหัสโดยใช้เพียง 7 บิตสำหรับการเป็นตัวแทน เป็น ISO-8859-1 / ISO-8859-15 ซึ่งกำหนด 256 รหัสจุดและใช้ 8 บิตสำหรับการแสดง 128 รหัสแรกของคะแนนในทั้ง 3 นี้เหมือนกัน
Tuxdude

67
  • Unicode
    • เป็นชุดของตัวละครที่ใช้กันทั่วโลก
  • UTF-8
    • การเข้ารหัสอักขระที่สามารถเข้ารหัสอักขระที่เป็นไปได้ทั้งหมด (เรียกว่าจุดโค้ด) ใน Unicode
    • รหัสหน่วยเป็น 8 บิต
    • ใช้หน่วยโค้ดหนึ่งถึงสี่หน่วยเพื่อเข้ารหัส Unicode
    • 00100100สำหรับ " $ " (หนึ่ง 8 บิต); 11000010 10100010สำหรับ " ¢ " (สอง 8 บิต); 11100010 10000010 10101100สำหรับ " " (สาม 8 บิต)
  • UTF-16
    • การเข้ารหัสอักขระอื่น
    • รหัสหน่วยเป็น 16 บิต
    • ใช้หน่วยโค้ดหนึ่งถึงสองหน่วยเพื่อเข้ารหัส Unicode
    • 00000000 00100100สำหรับ " $ " (หนึ่ง 16 บิต); 11011000 01010010 11011111 01100010สำหรับ " 𤭢 " (สองบิต 16)

1
สั้นและแม่นยำ
Aritra Chatterjee

30

Unicode เป็นมาตรฐานที่ค่อนข้างซับซ้อน อย่ากลัวเกินไป แต่เตรียมพร้อมสำหรับงานบางอย่าง! [2]

เนื่องจากต้องการทรัพยากรที่น่าเชื่อถืออยู่เสมอ แต่รายงานอย่างเป็นทางการมีขนาดใหญ่มากฉันขอแนะนำให้อ่านสิ่งต่อไปนี้:

  1. ขั้นต่ำสุดยอดนักพัฒนาซอฟต์แวร์ทุกคนต้องรู้อย่างแน่นอนเกี่ยวกับ Unicode และชุดอักขระ (ไม่มีข้อแก้ตัว!)การแนะนำโดย Joel Spolsky ซีอีโอของ Stack Exchange
  2. เพื่อ BMP และอื่น ๆ ! บทช่วยสอนโดย Eric Muller ผู้อำนวยการด้านเทคนิครองประธานคนต่อมาที่ The Unicode Consortium (20 สไลด์แรกและคุณเสร็จแล้ว)

คำอธิบายสั้น ๆ :

คอมพิวเตอร์อ่านไบต์และคนอ่านอักขระดังนั้นเราจึงใช้มาตรฐานการเข้ารหัสเพื่อแมปอักขระเป็นไบต์ ASCII เป็นมาตรฐานแรกที่ใช้กันอย่างแพร่หลาย แต่ครอบคลุมเฉพาะละติน (7 บิต / ตัวอักษรสามารถแสดงถึง 128 ตัวอักษรที่แตกต่างกัน) Unicode เป็นมาตรฐานที่มีเป้าหมายเพื่อให้ครอบคลุมอักขระที่เป็นไปได้ทั้งหมดในโลก (สามารถเก็บได้สูงสุด 1,114,112 ตัวอักษรหมายถึง 21 บิต / ตัวอักษรสูงสุด Unicode ปัจจุบัน 8.0 ระบุจำนวนทั้งหมด 120,737 อักขระและนั่นคือทั้งหมด)

ความแตกต่างหลักคืออักขระ ASCII สามารถพอดีกับไบต์ (8 บิต) แต่อักขระ Unicode ส่วนใหญ่ไม่สามารถ ดังนั้นการเข้ารหัสแบบฟอร์ม / โครงร่าง (เช่น UTF-8 และ UTF-16) จึงถูกนำมาใช้และโมเดลตัวละครจะเป็นดังนี้:

ตัวละครทุกตัวถือตำแหน่งนับจาก 0 ถึง 1,114,111 (Hex: 0-10FFFF) เรียกว่าจุดรหัส รูปแบบการเข้ารหัสแผนที่จุดรหัสไปยังหน่วยลำดับรหัส รหัสหน่วยเป็นวิธีที่คุณต้องการตัวอักษรที่จะจัดในหน่วยความจำหน่วย 8 บิตหน่วย 16 บิตและอื่น ๆ UTF-8 ใช้ 1 ถึง 4 หน่วยจาก 8 บิตและ UTF-16 ใช้ 1 หรือ 2 หน่วยจาก 16 บิตเพื่อครอบคลุม Unicode ทั้งหมด 21 บิตสูงสุด หน่วยใช้คำนำหน้าเพื่อให้ขอบเขตของอักขระสามารถถูกระบุและหน่วยเพิ่มเติมหมายถึงคำนำหน้าเพิ่มเติมที่ใช้บิต ดังนั้นแม้ว่า UTF-8 จะใช้ 1 ไบต์สำหรับสคริปต์ละติน แต่ต้องมี 3 ไบต์สำหรับสคริปต์ในภายหลังใน Basic Multilingual Plane ขณะที่ UTF-16 ใช้ 2 ไบต์สำหรับสิ่งเหล่านี้ และนั่นคือความแตกต่างหลักของพวกเขา สุดท้ายรูปแบบการเข้ารหัส

(เช่น UTF-16BE หรือ UTF-16LE) แมป (ซีเรียลไลซ์) ลำดับหน่วยของโค้ดเป็นลำดับไบต์

ตัวละคร:
รหัสจุดπ :
รูปแบบการเข้ารหัสU + 03C0 (หน่วยรหัส):
      UTF-8: CF 80
      UTF-16:
แผนการเข้ารหัสแบบ03C0 (ไบต์):
      UTF-8: CF 80
      UTF-16BE: 03 C0
      UTF-16LE: C0 03

เคล็ดลับ: เลขฐานสิบหกหมายถึง 4 บิตดังนั้นตัวเลขฐานสิบหกสองหลักจึงแทนไบต์
นอกจากนี้ให้ดูที่แผนที่เครื่องบินในวิกิพีเดียเพื่อให้ได้ความรู้สึกเกี่ยวกับรูปแบบชุดอักขระ


19

ในขั้นต้น Unicode ตั้งใจที่จะมีการเข้ารหัสความกว้าง 16 บิต (UCS-2) ผู้ใช้ Unicode รุ่นแรก ๆ เช่น Java และ Windows NT ได้สร้างไลบรารี่ของพวกเขารอบสตริง 16- บิต

ต่อมาขอบเขตของ Unicode ถูกขยายเพื่อรวมอักขระประวัติศาสตร์ซึ่งจะต้องใช้มากกว่า 65,536 รหัสจุดการเข้ารหัส 16 บิตจะสนับสนุน เพื่อให้สามารถแสดงอักขระเพิ่มเติมบนแพลตฟอร์มที่ใช้ UCS-2 ได้มีการแนะนำการเข้ารหัส UTF-16 มันใช้ "คู่ตัวแทน" เพื่อเป็นตัวแทนของตัวละครในเครื่องบินเสริม

ในขณะเดียวกันซอฟต์แวร์เก่าและโปรโตคอลเครือข่ายจำนวนมากใช้สายอักขระ 8 บิต UTF-8 ถูกสร้างขึ้นเพื่อให้ระบบเหล่านี้สามารถรองรับ Unicode ได้โดยไม่ต้องใช้ตัวอักษรกว้าง มันเข้ากันได้กับ ASCII 7 บิต


3
เป็นที่น่าสังเกตว่า Microsoft ยังคงอ้างถึง UTF-16 เป็น Unicode เพิ่มความสับสน ทั้งสองไม่เหมือนกัน
Mark Ransom

15

บทความนี้จะอธิบายรายละเอียดทั้งหมด http://kunststube.net/encoding/

การเขียนเพื่อบัฟเฟอร์

ถ้าคุณเขียนลงในบัฟเฟอร์ 4 ไบต์สัญลักษณ์ที่มีการเข้ารหัส UTF8 ไบนารีของคุณจะมีลักษณะดังนี้:

00000000 11100011 10000001 10000010

ถ้าคุณเขียนลงในบัฟเฟอร์ 4 ไบต์สัญลักษณ์ที่มีการเข้ารหัส UTF16 ไบนารีของคุณจะมีลักษณะดังนี้:

00000000 00000000 00110000 01000010

อย่างที่คุณเห็นขึ้นอยู่กับว่าคุณจะใช้ภาษาใดในเนื้อหาของคุณซึ่งจะส่งผลต่อความจำของคุณ

เช่นสำหรับสัญลักษณ์นี้โดยเฉพาะ: การเข้ารหัส UTF16 นั้นมีประสิทธิภาพมากกว่าเนื่องจากเรามี 2 ไบต์สำรองไว้ใช้สำหรับสัญลักษณ์ถัดไป แต่ไม่ได้หมายความว่าคุณต้องใช้ UTF16 สำหรับตัวอักษรญี่ปุ่น

การอ่านจากบัฟเฟอร์

ตอนนี้ถ้าคุณต้องการอ่านไบต์ข้างต้นคุณต้องรู้ว่าการเข้ารหัสนั้นถูกเขียนและถอดรหัสกลับอย่างถูกต้อง

เช่นถ้าคุณถอดรหัสสิ่งนี้: 00000000 11100011 10000001 10000010 เป็นการเข้ารหัสแบบ UTF16 คุณจะจบลงด้วยการไม่

หมายเหตุ: การเข้ารหัสและ Unicode เป็นสองสิ่งที่แตกต่างกัน Unicode เป็นตารางขนาดใหญ่ที่มีสัญลักษณ์แต่ละตัวจับคู่กับจุดรหัสที่ไม่ซ้ำ เช่นสัญลักษณ์ (ตัวอักษร) มี(จุดรหัส) : 30 42 (ฐานสิบหก) ในอีกทางหนึ่งการเข้ารหัสเป็นอัลกอริทึมที่แปลงสัญลักษณ์เป็นวิธีที่เหมาะสมกว่าเมื่อเก็บไว้กับฮาร์ดแวร์

30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.

30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.

ป้อนคำอธิบายรูปภาพที่นี่


11

Unicodeเป็นมาตรฐานแผนที่ซึ่งตัวละครในทุกภาษาเพื่อให้มีค่าเป็นตัวเลขเฉพาะที่เรียกว่าจุดรหัส เหตุผลที่ทำเช่นนี้คือทำให้สามารถเข้ารหัสที่แตกต่างกันได้โดยใช้รหัสจุดชุดเดียวกัน

UTF-8 และ UTF-16 เป็นการเข้ารหัสสองแบบ พวกเขาใช้จุดรหัสเป็นอินพุตและเข้ารหัสโดยใช้สูตรที่กำหนดไว้อย่างดีในการสร้างสตริงที่เข้ารหัส

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

สำหรับรายละเอียดเชิงลึกเกี่ยวกับ Unicode, UTF-8 และ UTF-16 คุณสามารถตรวจสอบบทความนี้

สิ่งที่โปรแกรมเมอร์ทุกคนควรรู้เกี่ยวกับ Unicode


9

ทำไมต้อง Unicode? เพราะ ASCII มีเพียง 127 ตัวอักษร เหล่านั้นจาก 128 ถึง 255 แตกต่างกันในประเทศที่แตกต่างกันนั่นคือเหตุผลที่มี codepages ดังนั้นพวกเขาบอกว่าให้มีมากถึง 1114,111 ตัวละคร ดังนั้นคุณจะเก็บ codepoint สูงสุดได้อย่างไร คุณจะต้องเก็บมันด้วย 21 บิตดังนั้นคุณจะใช้ DWORD ที่มี 32 บิตโดยเสีย 11 บิต ดังนั้นถ้าคุณใช้ DWORD เพื่อเก็บอักขระยูนิโค้ดมันเป็นวิธีที่ง่ายที่สุดเพราะค่าใน DWORD ของคุณตรงกับ codepoint ทุกประการ แต่อาร์เรย์ DWORD นั้นมีขนาดใหญ่กว่า WORD และแน่นอนว่าจะใหญ่กว่า BYTE arrays นั่นเป็นเหตุผลที่ไม่เพียง แต่มี utf-32 แต่ยังให้ utf-16 ด้วย แต่ utf-16 หมายถึงสตรีม WORD และ WORD มี 16 บิตดังนั้น codepoint สูงสุด 1114111 จะเข้ากับ WORD ได้อย่างไร? มันไม่สามารถ! ดังนั้นพวกเขาจึงใส่ของทุกอย่างที่สูงกว่า 65535 ลงใน DWORD ซึ่งพวกเขาเรียกคู่แทน คู่ตัวแทนดังกล่าวเป็นสองคำและสามารถตรวจพบได้โดยดูที่ 6 บิตแรก แล้ว utf-8 จะเป็นอย่างไร? มันเป็นอาร์เรย์ไบต์หรือกระแสไบต์ แต่ codepoint สูงสุด 1114111 สามารถใส่ลงในไบต์ได้อย่างไร มันไม่สามารถ! ตกลงพวกเขาใส่ DWORD ด้วยหรือไม่ หรืออาจเป็นคำใช่มั้ย เกือบจะถูก! พวกเขาคิดค้นลำดับ utf-8 ซึ่งหมายความว่าทุก codepoint ที่สูงกว่า 127 ต้องได้รับการเข้ารหัสเป็นลำดับ 2 ไบต์ 3 ไบต์หรือ 4 ไบต์ ว้าว! แต่เราจะตรวจจับลำดับดังกล่าวได้อย่างไร ทุกอย่างที่มากถึง 127 คือ ASCII และเป็นไบต์เดียว สิ่งที่เริ่มต้นด้วย 110 คือลำดับสองไบต์สิ่งที่เริ่มต้นด้วย 1110 เป็นลำดับสามไบต์และสิ่งที่เริ่มต้นด้วย 11110 เป็นลำดับสี่ไบต์ บิตที่เหลือของสิ่งเหล่านี้ที่เรียกว่า "startbytes" เป็นของ codepoint ตอนนี้ขึ้นอยู่กับลำดับไบต์ต่อไปนี้จะต้องปฏิบัติตาม ไบต์ต่อไปนี้เริ่มต้นด้วย 10 บิตที่เหลืออยู่คือบิตโหลดข้อมูล 6 บิตและเป็นของ codepoint เชื่อมบิตของส่วนของข้อมูลของ startbyte และไบต์ต่อไปนี้และคุณจะมี codepoint นั่นคือความมหัศจรรย์ของ utf-8


3
ตัวอย่าง utf-8 ของเครื่องหมาย€ (Euro) ถอดรหัสในลำดับ utf-8 3 ไบต์: E2 = 11100010 82 = 10000010 AC = 10101100 อย่างที่คุณเห็น E2 เริ่มต้นด้วย 1110 ดังนั้นนี่คือลำดับสามไบต์ตามที่คุณเห็น 82 และ AC เริ่มต้นด้วย 10 ดังนั้นตอนนี้เราจึงต่อไบต์ตอนนี้เราต่อเชื่อม "บิตโหลดข้อมูล": 0010 + 000010 + 101100 = 10000010101100 ซึ่งเป็นทศนิยม 8364 ดังนั้น 8364 ต้องเป็น codepoint สำหรับเครื่องหมาย€ (Euro)
bright

5

ASCII - ซอฟต์แวร์จัดสรรหน่วยความจำเพียง 8 บิตสำหรับอักขระที่กำหนด มันทำงานได้ดีสำหรับตัวอักษรภาษาอังกฤษและการรับเลี้ยงบุตรบุญธรรม (เช่นคำยืมส่วนหน้า) เนื่องจากค่าทศนิยมที่สอดคล้องกันนั้นต่ำกว่า 128 ในค่าทศนิยม ตัวอย่างโปรแกรม C

UTF-8 - ซอฟต์แวร์จัดสรร 1 ถึง 4 ตัวแปร 8 บิตไบต์สำหรับอักขระที่กำหนด ตัวแปรที่นี่หมายความว่าอย่างไร ให้เราบอกว่าคุณกำลังส่งอักขระ 'A' ผ่านหน้า HTML ของคุณในเบราว์เซอร์ (HTML คือ UTF-8) ค่าทศนิยมที่สอดคล้องกันของ A คือ 65 เมื่อคุณแปลงเป็นทศนิยมจะกลายเป็น 01000010 ซึ่งต้องใช้เพียง 1 ไบต์ หน่วยความจำ 1 ไบต์ได้รับการจัดสรรแม้สำหรับอักขระภาษาอังกฤษพิเศษเช่น 'ç' ในคำศัพท์ อย่างไรก็ตามเมื่อคุณต้องการเก็บอักขระยุโรปต้องใช้ 2 ไบต์ดังนั้นคุณต้องใช้ UTF-8 อย่างไรก็ตามเมื่อคุณใช้อักขระเอเชียคุณต้องมีอย่างน้อย 2 ไบต์และสูงสุด 4 ไบต์ ในทำนองเดียวกัน Emoji ต้องการ 3 ถึง 4 ไบต์ UTF-8 จะแก้ปัญหาทุกความต้องการของคุณ

UTF-16 จะจัดสรรขั้นต่ำ 2 ไบต์และสูงสุด 4 ไบต์ต่ออักขระโดยจะไม่จัดสรร 1 หรือ 3 ไบต์ อักขระแต่ละตัวจะถูกแทนใน 16 บิตหรือ 32 บิต

ทำไมจึงมี UTF-16 เดิม Unicode คือ 16 บิตไม่ใช่ 8 บิต Java นำ UTF-16 เวอร์ชันเดิมไปใช้

สรุปคุณไม่จำเป็นต้องใช้ UTF-16 ที่ใดก็ได้เว้นแต่จะได้รับการรับรองโดยภาษาหรือแพลตฟอร์มที่คุณกำลังทำงานอยู่

โปรแกรม Java ที่เรียกใช้โดยเว็บเบราว์เซอร์ใช้ UTF-16 แต่เว็บเบราว์เซอร์ส่งอักขระโดยใช้ UTF-8


"คุณไม่จำเป็นต้องใช้ UTF-16 ที่ใดก็ได้ยกเว้นว่ามีการใช้ภาษาหรือแพลตฟอร์มแล้ว": นี่เป็นจุดที่ดี แต่นี่เป็นรายการที่ไม่รวม: JavaScript, Java, .NET, SQL NCHAR, SQL NVARCHAR , VB4, VB5, VB6, VBA, VBScript, NTFS, Windows API ….
Tom Blodget

2

UTF ย่อมาจากย่อมาจากรูปแบบการแปลง Unicode โดยทั่วไปในโลกปัจจุบันมีสคริปต์ที่เขียนในหลายร้อยภาษารูปแบบที่ไม่ครอบคลุมโดย ASCII พื้นฐานที่ใช้ก่อนหน้านี้ ดังนั้น UTF จึงเกิดขึ้น

UTF-8 มีความสามารถในการเข้ารหัสอักขระและหน่วยของรหัสคือ 8 บิตในขณะที่สำหรับ UTF-16 เป็น 16 บิต

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