UTF-8, UTF-16 และ UTF-32


487

ความแตกต่างระหว่าง UTF-8, UTF-16 และ UTF-32 คืออะไร

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


36
ดูวิดีโอนี้หากคุณสนใจว่า Unicode ทำงานอย่างไรyoutube.com/watch?v=MijmeoH9LT4

1
วิดีโอมุ่งเน้นที่ UTF-8 และใช่มันอธิบายได้ดีว่าการเข้ารหัสความยาวผันแปรได้ผลอย่างไรและส่วนใหญ่เข้ากันได้กับคอมพิวเตอร์ที่อ่านหรือเขียนเฉพาะ ASCII ที่มีความยาวคงที่ พวก Unicode นั้นฉลาดเมื่อออกแบบการเข้ารหัส UTF-8
นาที

1
ฉันได้สร้างเครื่องมือออนไลน์สำหรับการแปลงและการเปรียบเทียบ
Amit Kumar Gupta

1
UTF-8 เป็นมาตรฐานโดยพฤตินัยในซอฟต์แวร์ที่ทันสมัยที่สุดสำหรับไฟล์ที่บันทึกไว้ โดยเฉพาะอย่างยิ่งมันเป็นการเข้ารหัสที่ใช้กันอย่างแพร่หลายสำหรับ HTML และไฟล์การกำหนดค่าและการแปล (Minecraft เช่นไม่ยอมรับการเข้ารหัสอื่น ๆ สำหรับข้อมูลข้อความทั้งหมด) UTF-32 นั้นรวดเร็วสำหรับการเป็นตัวแทนหน่วยความจำภายในและ UTF-16 เป็นชนิดที่เลิกใช้แล้วปัจจุบันใช้เฉพาะใน Win32 ด้วยเหตุผลทางประวัติศาสตร์เท่านั้น ( UTF-16 นั้นมีความยาวคงที่เมื่อ Windows 95 เป็นสิ่ง)
Kotauskas

@VladislavToncharov UTF-16 ไม่เคยมีการเข้ารหัสความยาวคงที่ คุณกำลังสับสนกับ UCS-2

คำตอบ:


373

UTF-8 มีข้อได้เปรียบในกรณีที่อักขระ ASCII แสดงถึงตัวอักษรส่วนใหญ่ในบล็อกข้อความเนื่องจาก UTF-8 เข้ารหัสสิ่งเหล่านี้เป็น 8 บิต (เช่น ASCII) นอกจากนี้ยังมีประโยชน์ในกรณีที่ไฟล์ UTF-8 ที่มีอักขระ ASCII เท่านั้นที่มีการเข้ารหัสเช่นเดียวกับไฟล์ ASCII

UTF-16 นั้นดีกว่าโดยที่ ASCII นั้นไม่ได้เด่นกว่าเนื่องจากมันใช้ 2 ไบต์ต่อตัวอักษรเป็นหลัก UTF-8 จะเริ่มใช้ 3 ไบต์ขึ้นไปสำหรับอักขระลำดับที่สูงขึ้นโดยที่ UTF-16 ยังคงอยู่ที่ 2 ไบต์สำหรับอักขระส่วนใหญ่

UTF-32 จะครอบคลุมอักขระที่เป็นไปได้ทั้งหมดใน 4 ไบต์ ทำให้มันป่องสวย ฉันไม่คิดว่าจะได้ประโยชน์จากการใช้มัน


165
ข้อได้เปรียบของ UTF-32: คุณไม่จำเป็นต้องถอดรหัสข้อมูลที่จัดเก็บไปยังจุดโค้ด Unicode แบบ 32 บิตสำหรับอักขระเช่นโดยการจัดการอักขระ จุดรหัสมีอยู่แล้วในอาเรย์ / เวกเตอร์ / สตริงของคุณ
richq

22
นอกจากนี้ยังง่ายต่อการแยกวิเคราะห์ว่า (สวรรค์ช่วยคุณ) คุณต้องนำวงล้อกลับมาใช้ใหม่
Paul McMillan

24
ดี UTF-8 มีข้อได้เปรียบในการถ่ายโอนเครือข่ายไม่จำเป็นต้องกังวลเกี่ยวกับ endianness เนื่องจากคุณกำลังถ่ายโอนข้อมูลทีละไบต์ (เทียบกับ 4)
ทิม 31as

30
@richq คุณไม่สามารถจัดการตัวละครทีละตัวอักษรใน UTF-32 ได้เนื่องจากจุดโค้ดไม่สอดคล้องกับตัวละครเสมอไป
hamstergene

4
ข้อดีของ UTF-32: การจัดการสตริงอาจเร็วขึ้นเมื่อเทียบกับ utf-8 ที่เทียบเท่า
Wes

331

ในระยะสั้น:

  • UTF-8: การเข้ารหัสความกว้างแปรผันเข้ากันได้กับ ASCII อักขระ ASCII (U + 0000 ถึง U + 007F) รับ 1 ไบต์, รหัสคะแนน U + 0080 ถึง U + 07FF ใช้เวลา 2 ไบต์, รหัสจุด U + 0800 ถึง U + FFFF ใช้เวลา 3 ไบต์, รหัสจุด U + 10,000 ถึง U + 10FFFF ใช้เวลา 4 ไบต์ ดีสำหรับข้อความภาษาอังกฤษไม่ดีสำหรับข้อความภาษาเอเชีย
  • UTF-16: การเข้ารหัสความกว้างแปรผัน จุดโค้ด U + 0000 ถึง U + FFFF ใช้เวลา 2 ไบต์, รหัสจุด U + 10000 ถึง U + 10FFFF ใช้เวลา 4 ไบต์ ไม่ดีสำหรับข้อความภาษาอังกฤษดีสำหรับข้อความภาษาเอเชีย
  • UTF-32: การเข้ารหัสความกว้างคงที่ จุดโค้ดทั้งหมดใช้เวลาสี่ไบต์ หน่วยความจำมหาศาลมหาศาล แต่ใช้งานได้รวดเร็ว ใช้น้อยมาก

ในลองดูวิกิพีเดีย: UTF-8 , UTF-16และUTF-32


65
@spurrymoses: ฉันอ้างอิงอย่างเคร่งครัดกับจำนวนพื้นที่ที่ใช้โดยไบต์ข้อมูล UTF-8 ต้องการ 3 ไบต์ต่ออักขระเอเชียในขณะที่ UTF-16 ต้องการเพียง 2 ไบต์ต่ออักขระเอเชีย นี่ไม่ใช่ปัญหาสำคัญเนื่องจากคอมพิวเตอร์มีหน่วยความจำมากมายในปัจจุบันเมื่อเทียบกับจำนวนข้อความโดยเฉลี่ยที่เก็บไว้ในหน่วยความจำของโปรแกรม
Adam Rosenfield

12
ไม่ได้ใช้ UTF-32 อีกต่อไป ... ใน osx และ linux wchar_tจะมีค่าเริ่มต้นเป็น 4 ไบต์ gcc มีตัวเลือก-fshort-wcharที่ลดขนาดเป็น 2 ไบต์ แต่แบ่งความเข้ากันได้แบบไบนารีกับ std libs
เถาวัลย์

9
@PandaWood ofcource UTF-8 สามารถเข้ารหัสอักขระใด ๆ ! แต่คุณได้เปรียบเทียบข้อกำหนดหน่วยความจำกับ UTF-16 แล้วหรือยัง? คุณดูเหมือนจะพลาดจุด!
Ustaman Sangat

16
ถ้ามีคนบอกว่า UTF-8 นั้น "ไม่ดีสำหรับข้อความภาษาเอเชีย" ในบริบทของรูปแบบการเข้ารหัสทั้งหมดรวมถึงสิ่งที่ไม่สามารถเข้ารหัส Unicode ได้แน่นอนพวกเขาจะผิด แต่นั่นไม่ใช่บริบท บริบทของข้อกำหนดของหน่วยความจำมาจากข้อเท็จจริงที่ว่าคำถาม (และคำตอบ) เปรียบเทียบ UTF-8, UTF-16 และ UTF-32 ซึ่งจะเข้ารหัสข้อความเอเชียทั้งหมด แต่ใช้หน่วยความจำ / พื้นที่เก็บข้อมูลที่แตกต่างกัน ตามมาว่าคุณงามความดีของพวกเขาจะอยู่ในบริบทของความต้องการของหน่วยความจำโดยธรรมชาติ "ไม่ดีมาก"! = "ไม่ดี"
พอลเกรกอรี่

5
@McGafter: แน่นอนมีอยู่ หากคุณต้องการความน่าเชื่อถือตรงไปที่ปากม้าที่Unicode Consortium ดูบทที่ 2.5 สำหรับคำอธิบายของการเข้ารหัส UTF- * แต่เพื่อให้ได้ความเข้าใจระดับสูงที่เรียบง่ายของการเข้ารหัสฉันพบว่าบทความ Wikipedia เป็นแหล่งที่เข้าถึงได้ง่ายกว่ามาก
Adam Rosenfield

116
  • UTF-8 เป็นตัวแปร1 ถึง 4ไบต์

  • UTF-16 เป็นตัวแปร2 หรือ 4ไบต์

  • UTF-32 ได้รับการแก้ไข4ไบต์

หมายเหตุ: UTF-8 สามารถใช้เวลา 1 ถึง 6 ไบต์ด้วยการประชุมล่าสุด: https://lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html


35
UTF8 คือ 1 ถึง 6 ไบต์
Urkle

6
@Urkle ถูกต้องทางเทคนิคเนื่องจากการจับคู่ช่วงเต็มของ UTF32 / LE / BE รวมถึง U-00200000 - U-7FFFFFFF แม้ว่า Unicode v6.3 จะสิ้นสุดที่ U-0010FFFF นี่คือรายละเอียดที่ดีของวิธีการเข้ารหัส / Dec 5 และ 6 byte utf8: lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html

4
สำรองข้อมูลเหล่านี้ด้วยส่วนอ้างอิงที่เกี่ยวข้องและแหล่งที่มา?
n611x007

20
@Urkle ไม่ UTF-8 ต้องไม่เกิน 5 หรือ 6 ไบต์ จุดโค้ด Unicode ถูก จำกัด ที่ 21 บิตซึ่ง จำกัด UTF-8 ถึง 4 ไบต์ (แน่นอนคุณสามารถขยายหลักการของ UTF-8 เพื่อเข้ารหัสจำนวนเต็มขนาดใหญ่โดยพลการ แต่มันจะไม่ใช่ Unicode) ดู RFC 3629
rdb

11
การอ้างถึงวิกิพีเดีย: ในเดือนพฤศจิกายน 2546 UTF-8 ถูก จำกัด โดย RFC 3629 เพื่อให้ตรงกับข้อ จำกัด ของการเข้ารหัสอักขระ UTF-16: ห้ามมีการระบุจุดรหัสที่สอดคล้องกับตัวอักษรตัวแทนสูงและต่ำอย่างชัดเจนลบมากกว่า 3% ของลำดับสามไบต์ และสิ้นสุดที่ U + 10FFFF ลบมากกว่า 48% ของลำดับสี่ไบต์และลำดับห้าและหกไบต์ทั้งหมด
Adam Calvet Bohl

79

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

โดยย่อ UTF-32 ใช้ค่า 32- บิตสำหรับแต่ละอักขระ ที่ช่วยให้พวกเขาใช้รหัสความกว้างคงที่สำหรับตัวละครทุกตัว

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

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

และนั่นทำให้เราได้เปรียบ อักขระ ASCII ใด ๆ เข้ากันได้กับ UTF-8 โดยตรงดังนั้นสำหรับการอัปเกรดแอปรุ่นเก่า UTF-8 เป็นตัวเลือกทั่วไปและชัดเจน ในเกือบทุกกรณีมันจะใช้หน่วยความจำน้อยที่สุด ในทางกลับกันคุณไม่สามารถรับรองความกว้างของตัวละครได้ อาจมีความกว้างอักขระ 1, 2, 3 หรือ 4 ตัวซึ่งทำให้การจัดการสตริงทำได้ยาก

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

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

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

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

คำตอบสั้น ๆ : การเข้ารหัสทั้งสามสามารถเข้ารหัสชุดอักขระเดียวกันได้ แต่จะแทนอักขระแต่ละตัวเป็นลำดับไบต์ที่แตกต่างกัน


12
ไม่ถูกต้องที่จะบอกว่า Unicode กำหนดจำนวนเต็มเฉพาะให้กับสัญลักษณ์กราฟิกแต่ละอัน มันกำหนดเช่นนี้สำหรับจุดรหัสแต่ละจุด แต่บางจุดรหัสเป็นตัวควบคุมที่มองไม่เห็นและสัญลักษณ์กราฟิกบางอย่างต้องมีจุดรหัสหลายจุดเพื่อเป็นตัวแทน
tchrist

15
@ คริส: ใช่มันไม่ถูกต้อง ปัญหาคือการอธิบาย Unicode อย่างถูกต้องคุณต้องเขียนหลายพันหน้า ฉันหวังว่าจะเข้าใจแนวคิดพื้นฐานเพื่ออธิบายความแตกต่างระหว่างการเข้ารหัส
jalf

@jalf lol ดังนั้นโดยทั่วไปแล้วจะอธิบาย Unicode คุณจะต้องเขียนUnicode Core Specification
Justin Ohms

@tchrist โดยเฉพาะคุณสามารถสร้างสัญลักษณ์ภาษาจีนจากแบบดั้งเดิม (แต่พวกมันอยู่ในแผนภูมิเดียวกันดังนั้นคุณจะจบลงด้วยการใช้พื้นที่จำนวนไม่จริงไม่ว่าจะเป็นดิสก์หรือ RAM เพื่อเข้ารหัสพวกเขา) แทนที่จะใช้ คนในตัว
Kotauskas

44

Unicodeเป็นมาตรฐานและเกี่ยวกับUTF-xคุณสามารถคิดว่าเป็นการใช้งานด้านเทคนิคเพื่อการใช้งานจริง:

  • UTF-8 - " ขนาดที่เหมาะสมที่สุด ": เหมาะที่สุดสำหรับข้อมูลตัวอักษรละติน (หรือ ASCII) ใช้เวลาเพียง 1 ไบต์ต่อตัวอักษร แต่ขนาดจะเติบโตตามความหลากหลายของสัญลักษณ์ (และในกรณีที่เลวร้ายที่สุดสามารถเติบโตได้ถึง 6 ไบต์ต่อตัวอักษร)
  • UTF-16 - " balance ": ใช้เวลาอย่างน้อย 2 ไบต์ต่อตัวอักษรซึ่งเพียงพอสำหรับชุดภาษาหลักที่มีอยู่แล้วซึ่งมีขนาดคงที่เพื่อให้ง่ายต่อการจัดการอักขระ (แต่ขนาดยังคงเป็นตัวแปรและสามารถเติบโตได้สูงสุด 4 ไบต์ต่อตัวอักษร )
  • UTF-32 - " performance ": อนุญาตให้ใช้อัลกอริธึมอย่างง่ายซึ่งเป็นผลมาจากตัวอักษรขนาดคงที่ (4 ไบต์) แต่มีข้อเสียของหน่วยความจำ

«ภาษากระแสหลัก»ไม่ใช่กระแสหลักนั้นในหลาย ๆ ส่วนของโลก ^^
tuxayo

2
UTF-16 เป็นขนาดที่ปรับให้เหมาะสมจริง ๆ สำหรับตัวอักษรที่ไม่ใช่ ASCII เพราะมันขึ้นอยู่กับภาษาที่จะใช้
tuxayo

@tuxayo เห็นด้วยอย่างยิ่งมันเป็นเรื่องที่น่าสังเกตว่าตัวละคร Hanzi และคันจิสำหรับส่วนเอเชียของโลก
rook

ควรเป็นคำตอบที่ดีที่สุด มันถูกต้องเกินไปที่จะฝังไว้ที่นี่
Michal Štein

28

ฉันพยายามที่จะให้คำอธิบายง่ายๆในของฉันblogpost

UTF-32

ต้องใช้ 32 บิต (4 ไบต์) เพื่อเข้ารหัสอักขระใด ๆ ตัวอย่างเช่นในการเป็นตัวแทนของรหัสอักขระ A โดยใช้ชุดรูปแบบนี้คุณจะต้องเขียน 65 ในเลขฐานสองแบบ 32 บิต:

00000000 00000000 00000000 01000001 (Big Endian)

หากคุณมองให้ใกล้ชิดคุณจะทราบว่าเจ็ดบิตที่ถูกต้องที่สุดนั้นเป็นบิตเดียวกันเมื่อใช้รูปแบบ ASCII แต่เนื่องจาก UTF-32 เป็นแบบแผนความกว้างคงที่เราต้องแนบสามไบต์เพิ่มเติม หมายความว่าหากเรามีไฟล์สองไฟล์ที่มีอักขระ "A" เท่านั้นไฟล์หนึ่งจะถูกเข้ารหัส ASCII และอีกไฟล์หนึ่งเข้ารหัส UTF-32 ขนาดของไฟล์จะเป็น 1 ไบต์และ 4 ไบต์ตามลำดับ

UTF-16

หลายคนคิดว่าเนื่องจาก UTF-32 ใช้ความกว้างคงที่ 32 บิตเพื่อเป็นตัวแทนของรหัสจุด UTF-16 จึงเป็นความกว้างคงที่ 16 บิต ไม่ถูกต้อง!

ใน UTF-16 รหัสจุดอาจแทนทั้ง 16 บิตหรือ 32 บิต ดังนั้นโครงร่างนี้คือระบบเข้ารหัสความยาวผันแปร ข้อดีของ UTF-32 คืออะไร? อย่างน้อยสำหรับ ASCII ขนาดของไฟล์จะไม่เป็น 4 เท่าของต้นฉบับ (แต่ยังคงเป็นสองเท่า) ดังนั้นเราจึงยังไม่รองรับ ASCII แบบย้อนหลัง

เนื่องจาก 7-bits เพียงพอที่จะเป็นตัวแทนของอักขระ "A" ตอนนี้เราสามารถใช้ 2 ไบต์แทน 4 เช่น UTF-32 มันจะมีลักษณะ:

00000000 01000001

UTF-8

คุณเดาถูก .. ใน UTF-8 จุดรหัสอาจแทนด้วย 32, 16, 24 หรือ 8 บิตและเป็นระบบ UTF-16 อันนี้ก็เป็นระบบเข้ารหัสความยาวตัวแปร

ในที่สุดเราสามารถเป็นตัวแทน "A" ในลักษณะเดียวกับที่เราเป็นตัวแทนโดยใช้ระบบเข้ารหัส ASCII

01001101

ตัวอย่างเล็ก ๆ ที่ UTF-16 ดีกว่า UTF-8:

พิจารณาตัวอักษรจีน "語" - การเข้ารหัส UTF-8 คือ:

11101000 10101010 10011110

ในขณะที่การเข้ารหัส UTF-16 นั้นสั้นลง:

10001010 10011110

เพื่อให้เข้าใจถึงการเป็นตัวแทนและวิธีตีความมันไปที่โพสต์ต้นฉบับ


19

UTF-8

  • ไม่มีแนวคิดของการสั่งไบต์
  • ใช้ระหว่าง 1 ถึง 4 ไบต์ต่อตัวละคร
  • ASCII เป็นชุดย่อยของการเข้ารหัสที่เข้ากันได้
  • การซิงโครไนซ์ตัวเองอย่างสมบูรณ์เช่นไบต์ที่ถูกดร็อปจากที่ใดก็ได้ในสตรีมจะทำให้อักขระส่วนใหญ่เสียหาย
  • ภาษายุโรปทั้งหมดนั้นเข้ารหัสในสองไบต์หรือน้อยกว่าต่อตัวอักษร

UTF-16

  • จะต้องมีการแยกวิเคราะห์ด้วยคำสั่งไบต์ที่รู้จักหรืออ่านเครื่องหมายคำสั่ง (BOM)
  • ใช้ 2 หรือ 4 ไบต์ต่อตัวอักษร

UTF-32

  • อักขระทุกตัวคือ 4 ไบต์
  • จะต้องมีการแยกวิเคราะห์ด้วยคำสั่งไบต์ที่รู้จักหรืออ่านเครื่องหมายคำสั่ง (BOM)

UTF-8 จะเป็นพื้นที่ที่มีประสิทธิภาพที่สุดยกเว้นว่าตัวละครส่วนใหญ่นั้นมาจากพื้นที่ของตัวละคร CJK (จีนญี่ปุ่นและเกาหลี)

UTF-32 ที่ดีที่สุดสำหรับการเข้าถึงแบบสุ่มโดยตัวอักษรชดเชยเป็นไบต์อาร์เรย์


"การซิงโครไนซ์ด้วยตนเอง" ทำงานอย่างไรใน UTF-8 คุณสามารถยกตัวอย่างสำหรับอักขระ 1 ไบต์และ 2 ไบต์ได้หรือไม่
Koray Tugay

2
@KorayTugay สตริงไบต์ที่สั้นกว่าที่ถูกต้องจะไม่ถูกใช้เป็นอักขระที่ยาวขึ้น ตัวอย่างเช่น ASCII อยู่ในช่วง 0-127 หมายถึงอักขระหนึ่งไบต์ทั้งหมดมีรูปแบบเป็น0xxxxxxxเลขฐานสอง ทุกตัวอักษรสองไบต์เริ่มต้นด้วยกับไบต์ที่สองของ110xxxxx 10xxxxxxดังนั้นสมมติว่าอักขระตัวแรกของอักขระสองไบต์หายไป ทันทีที่คุณเห็น10xxxxxxโดยไม่ต้องนำหน้า110xxxxxxคุณสามารถกำหนดได้ว่าไบต์นั้นสูญหายหรือเสียหายและทิ้งอักขระนั้น (หรือขออีกครั้งจากเซิร์ฟเวอร์หรืออะไรก็ตาม) แล้วไปต่อจนกว่าคุณจะเห็นไบต์แรกที่ถูกต้องอีกครั้ง .
Chris

1
หากคุณมีออฟเซ็ตเป็นอักขระคุณมีออฟเซ็ตเป็นอักขระนั้น - utf8, utf16 หรือ utf32 จะทำงานเหมือนกันในกรณีนั้น นั่นคือพวกมันทุกคนสามารถเข้าถึงแบบสุ่มได้อย่างเท่าเทียมกันโดยการชดเชยอักขระลงในอาร์เรย์ไบต์ แนวคิดที่ว่า utf32 นั้นดีกว่าในการนับตัวอักษรกว่า utf8 ก็เป็นเท็จเช่นกัน codepoint (ซึ่งไม่ได้เช่นเดียวกับตัวละครอีกครั้งซึ่งไม่ได้เป็นเช่นเดียวกับตัวอักษร .. มีถอนหายใจ) เป็น 32 บิตกว้างใน utf32 และระหว่างวันที่ 8 และ 32 บิตใน utf8 แต่ตัวละครอาจครอบคลุม codepoints หลายที่ ทำลายข้อได้เปรียบที่สำคัญที่คนเรียกร้อง utf32 มีมากกว่า utf8
ชัดเจน

14

ฉันทำการทดสอบเพื่อเปรียบเทียบประสิทธิภาพของฐานข้อมูลระหว่าง UTF-8 และ UTF-16 ใน MySQL

อัปเดตความเร็ว

UTF-8

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

UTF-16

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

แทรกความเร็ว

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

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

ลบความเร็ว

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

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


14

ใน UTF-32 อักขระทั้งหมดมีรหัส 32 บิต ข้อดีคือคุณสามารถคำนวณความยาวของสตริงได้อย่างง่ายดาย ข้อเสียคือสำหรับแต่ละอักขระ ASCII คุณเสียสามไบต์พิเศษ

ในอักขระ UTF-8 มีความยาวผันแปรอักขระ ASCII จะถูกเข้ารหัสในหนึ่งไบต์ (แปดบิต) อักขระพิเศษตะวันตกส่วนใหญ่จะถูกเข้ารหัสในสองไบต์หรือสามไบต์ (ตัวอย่างเช่น€คือสามไบต์) และอักขระที่แปลกใหม่อาจใช้เวลานานขึ้น ถึงสี่ไบต์ ข้อเสียที่ชัดเจนคือว่านิรนัยที่คุณไม่สามารถคำนวณความยาวของสตริง แต่จะใช้เวลาน้อยกว่ามากในการเขียนข้อความอักษรละติน (อังกฤษ) เมื่อเทียบกับ UTF-32

UTF-16 ก็มีความยาวผันแปรเช่นกัน อักขระถูกเข้ารหัสทั้งสองไบต์หรือสี่ไบต์ ฉันไม่เห็นประเด็น มันมีข้อเสียของความยาวผันแปร แต่ไม่ได้ประโยชน์จากการประหยัดพื้นที่มากเท่ากับ UTF-8

จากทั้งสามอย่างชัดเจน UTF-8 เป็นที่แพร่หลายที่สุด


เหตุใดฉันจึงต้องการคำนวณความยาวของสตริงขณะพัฒนาเว็บไซต์ มีข้อดีของการเลือก UTF-8 / UTF-16 ในการพัฒนาเว็บหรือไม่?
Morfidon

"ข้อดีคือคุณสามารถคำนวณความยาวของสตริงได้อย่างง่ายดาย" ถ้าคุณกำหนดความยาวด้วย # ของ codepoints แล้วใช่คุณเพียงแค่หารความยาวไบต์ด้วย 4 เพื่อรับมันด้วย UTF-32 นั่นไม่ใช่คำจำกัดความที่มีประโยชน์มาก แต่อาจไม่เกี่ยวข้องกับจำนวนตัวอักษร นอกจากนี้การปรับสภาพอาจเปลี่ยนจำนวน codepoints ในสายอักขระ ตัวอย่างเช่นคำภาษาฝรั่งเศส "été" สามารถเข้ารหัสได้อย่างน้อย 4 วิธีด้วยความยาว codepoint 3 แบบ

UTF-16 นั้นอาจเร็วกว่า UTF-8 ในขณะที่หน่วยความจำไม่เสียเช่นเดียวกับ UTF-32
Michal Štein

6

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

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


เนื้อหาที่สำคัญกว่าความต้องการพื้นที่ก็คือความจริงแล้ว UTF-8 นั้นมีภูมิคุ้มกันต่อ endianness UTF-16 และ UTF-32 ย่อมจะต้องจัดการกับปัญหา endianness โดยที่ UTF-8 เป็นเพียงกระแสของออคเต็ต
IInspectable

2

ความแตกต่างคือขนาดของตัวแปรพื้นฐานซึ่งในแต่ละกรณีจะมีขนาดใหญ่ขึ้นเพื่อให้สามารถแสดงอักขระได้มากขึ้น

อย่างไรก็ตามแบบอักษรการเข้ารหัสและสิ่งต่าง ๆ มีความซับซ้อนอย่างชั่วร้าย (โดยไม่จำเป็น?) ดังนั้นจำเป็นต้องมีลิงก์ขนาดใหญ่เพื่อกรอกรายละเอียดเพิ่มเติม:

http://www.cs.tut.fi/~jkorpela/chars.html#ascii

อย่าคาดหวังว่าจะเข้าใจมันทั้งหมด แต่ถ้าคุณไม่ต้องการมีปัญหาในภายหลังก็คุ้มค่าที่จะเรียนรู้ให้เร็วที่สุดเท่าที่จะทำได้

พอล


หรือเพียงแค่ใช้ UTF-8 เป็นค่าเริ่มต้นเนื่องจากเป็นมาตรฐานจริงและดูว่าระบบใหม่รองรับหรือไม่ หากไม่เป็นเช่นนั้นคุณสามารถกลับมาที่โพสต์นี้ได้
robotik

-2

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

ฉันสงสัยว่าทำไมทุกคนเลือกที่จะมีการเข้ารหัสที่ไม่ใช่ UTF-8 เมื่อเห็นได้ชัดว่ามันมีประสิทธิภาพมากกว่าสำหรับการใช้งานเว็บ / การเขียนโปรแกรม

ความเข้าใจผิดที่พบบ่อย - หมายเลขต่อท้ายไม่ได้บ่งบอกถึงความสามารถของมัน พวกเขาทั้งหมดสนับสนุน Unicode ที่สมบูรณ์เพียงแค่ที่ UTF-8 สามารถจัดการ ASCII ด้วยไบต์เดียวจึงมีประสิทธิภาพมากขึ้น / น้อยกว่าความเสียหายต่อ CPU และผ่านทางอินเทอร์เน็ต

อ่านบ้างดี: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html และhttp://utf8everywhere.org


ฉันไม่แน่ใจว่าทำไมคุณแนะนำให้ใช้ UTF-16 หรือ UTF-32 เพื่อสนับสนุนข้อความที่ไม่ใช่ภาษาอังกฤษ UTF-8 สามารถจัดการได้ดี และมีอักขระที่ไม่ใช่ ASCII ในข้อความภาษาอังกฤษด้วย เช่นเดียวกับผู้ไม่เข้าร่วมที่มีความกว้างเป็นศูนย์ หรือประประ ฉันกลัวคำตอบนี้ไม่ได้เพิ่มคุณค่ามากนัก
IIsspectable

คำถามนี้มีแนวโน้มที่จะ downvoting เนื่องจาก UTF-8 ยังคงใช้กันทั่วไปในไฟล์ HTML แม้ว่าอักขระส่วนใหญ่จะเป็นอักขระ 3 ไบต์ใน UTF-8,
Ṃųỻịgǻňạcểơửṩ

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

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