ทำไมเราต้องใช้ 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
คู่ตัวแทน: สิ่งเหล่านี้เกิดขึ้นบ่อยพอดังนั้นฉันจะให้ลิงค์ตัวอย่าง:
อื่น ๆ ?: