กลับไปหน้าบทความ

อ่าน 16 นาที

ยูทีเอฟ-8

UTF-8เป็น มาตรฐาน การเข้ารหัสอักขระที่ใช้สำหรับการสื่อสารทางอิเล็กทรอนิกส์ กำหนดโดย มาตรฐาน Unicodeชื่อนี้มาจากUnicode Transformation Format – 8-bit ณปี 2026 เกือบทุกเว็บเพจ (99%).

ยูทีเอฟ-8

ยูทีเอฟ-8
มาตรฐานมาตรฐานยูนิโค้ด
การจำแนกประเภทรูปแบบการแปลงยูนิโค้ด , ASCII แบบขยาย , การเข้ารหัสความยาวแปรผัน
ขยายเอเอสซีไอ
แปลง / เข้ารหัสISO/IEC 10646 ( ยูนิโค้ด )
นำหน้าโดยยูทีเอฟ-1

UTF-8เป็น มาตรฐาน การเข้ารหัสอักขระที่ใช้สำหรับการสื่อสารทางอิเล็กทรอนิกส์ กำหนดโดย มาตรฐาน Unicodeชื่อนี้มาจากUnicode Transformation Format – 8-bit [ 1 ] ปี 2026 เกือบทุกเว็บเพจ (99%) ถูกส่งผ่านในรูปแบบ UTF-8 [ 2 ]

UTF-8 รองรับจุดรหัส Unicode ที่ถูกต้อง ทั้งหมด 1,112,064 [ 3 ] จุด โดยใช้การเข้ารหัสความกว้างแปรผันของหน่วยรหัสหนึ่งไบต์ (8 บิต) หนึ่งถึงสี่หน่วย

รหัสจุดที่มีค่าตัวเลขต่ำกว่า ซึ่งมักจะเกิดขึ้นบ่อยกว่า จะถูกเข้ารหัสโดยใช้ไบต์น้อยกว่า ได้รับการออกแบบมาเพื่อความเข้ากันได้แบบย้อนหลังกับASCII : อักขระ 128 ตัวแรกของ Unicode ซึ่งตรงกับ ASCII แบบหนึ่งต่อหนึ่ง จะถูกเข้ารหัสโดยใช้ไบต์เดียวที่มีค่าไบนารีเดียวกันกับ ASCII ดังนั้นไฟล์ที่เข้ารหัส UTF-8 โดยใช้เฉพาะอักขระเหล่านั้นจึงเหมือนกับไฟล์ ASCII ซอฟต์แวร์ส่วนใหญ่ที่ออกแบบมาสำหรับASCII แบบขยาย ใดๆ ก็ สามารถอ่านและเขียน UTF-8 ได้ และส่งผลให้มีปัญหาเรื่องความเป็นสากลน้อยกว่าการเข้ารหัสข้อความทางเลือกอื่นๆ[ 4 ] [ 5 ]

UTF-8 เป็นรูปแบบการเข้ารหัสที่ใช้กันอย่างแพร่หลายในทุกประเทศ/ภาษาบนอินเทอร์เน็ต ใช้ในมาตรฐานส่วนใหญ่ มักเป็นรูปแบบการเข้ารหัสเดียวที่ได้รับอนุญาต และได้รับการสนับสนุนจากระบบปฏิบัติการและภาษาโปรแกรมสมัยใหม่ทั้งหมด

ประวัติศาสตร์

องค์การมาตรฐานสากล (ISO) ได้เริ่มสร้างชุดอักขระหลายไบต์สากลในปี 1989 ร่างมาตรฐาน ISO 10646 มีภาคผนวก ที่ไม่บังคับใช้ ชื่อUTF-1ซึ่งให้การเข้ารหัสแบบสตรีมไบต์ของ จุดรหัส 32 บิตการเข้ารหัสนี้ไม่เป็นที่น่าพอใจในด้านประสิทธิภาพ รวมถึงปัญหาอื่นๆ และปัญหาที่ใหญ่ที่สุดน่าจะเป็นการที่ไม่มีการแยกที่ชัดเจนระหว่าง ASCII และไม่ใช่ ASCII: เครื่องมือ UTF-1 ใหม่จะเข้ากันได้กับข้อความที่เข้ารหัส ASCII แต่ข้อความที่เข้ารหัส UTF-1 อาจทำให้โค้ดที่มีอยู่ซึ่งคาดหวัง ASCII (หรือASCII แบบขยาย ) สับสนได้ เนื่องจากอาจมีไบต์ต่อเนื่องในช่วง0x210x7Eที่มีความหมายอื่นใน ASCII เช่น0x2Fสำหรับตัวคั่นไดเร็กทอรี เส้นทางUnix/

ในเดือนกรกฎาคม พ.ศ. 2535 คณะกรรมการ X/Open XoJIG กำลังมองหาการเข้ารหัสที่ดีกว่า Dave Prosser จากUnix System Laboratoriesได้เสนอรูปแบบการเข้ารหัสที่มีคุณลักษณะการใช้งานที่เร็วกว่า และแนะนำการปรับปรุงที่ว่าอักขระ ASCII 7 บิตจะ แสดงเฉพาะตัวมันเอง เท่านั้นลำดับหลายไบต์จะรวมเฉพาะไบต์ที่มีบิตสูงตั้งค่าไว้เท่านั้น ชื่อFile System Safe UCS Transformation Format ( FSS-UTF ) [ 6 ]และข้อความส่วนใหญ่ของข้อเสนอนี้ได้รับการเก็บรักษาไว้ในข้อกำหนดขั้นสุดท้ายในภายหลัง[ 7 ] [ 8 ] [ 9 ]ในเดือนสิงหาคม พ.ศ. 2535 ข้อเสนอนี้ได้รับการเผยแพร่โดย ตัวแทน IBM X/Open ไปยังผู้ที่สนใจ

การแก้ไขโดยKen Thompsonจาก กลุ่ม ระบบปฏิบัติการ Plan 9ที่Bell Labsทำให้สามารถซิงโครไนซ์ตัวเองได้ทำให้ผู้อ่านสามารถเริ่มต้นที่ใดก็ได้และตรวจจับขอบเขตของอักขระได้ทันที โดยแลกกับประสิทธิภาพการใช้บิตที่น้อยกว่าข้อเสนอก่อนหน้านี้เล็กน้อย นอกจากนี้ยังยกเลิกการใช้ค่าไบแอสที่ป้องกันการเข้ารหัสที่ยาวเกินไป[ 9 ] [ 10 ]การออกแบบของ Thompson ได้รับการร่างขึ้นเมื่อวันที่ 2 กันยายน 1992 บนแผ่นรองจานในร้านอาหารแห่งหนึ่งในรัฐนิวเจอร์ซีย์ร่วมกับRob Pikeในวันต่อมา Pike และ Thompson ได้นำไปใช้งานและอัปเดตPlan 9ให้ใช้งานได้ทั่วทั้งระบบ[ 11 ]จากนั้นจึงแจ้งความสำเร็จของพวกเขาให้ X/Open ทราบ ซึ่งยอมรับว่าเป็นข้อกำหนดสำหรับFSS- UTF [ 9 ] UTF-8 ได้รับการนำเสนออย่างเป็นทางการครั้งแรกใน การประชุม USENIXที่เมืองซานดิเอโกระหว่างวันที่ 25 ถึง 29 มกราคม พ.ศ. 2536 [ 12 ]คณะทำงานด้านวิศวกรรมอินเทอร์เน็ตได้นำ UTF-8 มาใช้ในนโยบายเกี่ยวกับชุดอักขระและภาษาใน RFC 2277 ( BCP 18) สำหรับงานมาตรฐานอินเทอร์เน็ตในอนาคตในเดือนมกราคม พ.ศ. 2541 โดยแทนที่ชุดอักขระไบต์เดียวเช่นLatin-1ใน RFC รุ่นเก่า[ 13 ]

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

คำอธิบาย

UTF-8 เข้ารหัสจุดรหัสในหนึ่งถึงสี่ไบต์ ขึ้นอยู่กับค่าของจุดรหัส ในตารางต่อไปนี้ ตัวอักษรuถึงzซึ่งแต่ละตัวแทนตัวเลขฐานสิบหก จะถูกแทนที่ด้วยบิต 4 บิต ที่เป็นส่วนประกอบ คือ uuuuถึงzzzzจากตำแหน่งU+ uvwxyz :

การแปลงรหัสจุด ↔ UTF-8
รหัสจุดแรก รหัสจุดสุดท้าย ไบต์ 1 ไบต์ที่ 2 ไบต์ที่ 3 ไบต์ที่ 4
ยู+0000ยู+007เอฟ0 yyyzzzz
ยู+0080U+07FF110 xxxyy10 yyzzzz
ยู+0800ยู+เอฟเอฟเอฟ1110 wwww10 xxxxyy10 yyzzzz
ยู+010000U+10FFFF11110 ยูวีวี10 vvwwww10 xxxxyy10 yyzzzz

ตัวอย่างเช่น ตัวอักษร 桁 มีรหัสเลขฐานสิบหกเป็น U+6841ซึ่งในเลขฐานสองคือ0110 1000 0100 0001และเมื่อแปลงเป็นรหัส UTF-8 จะได้เป็น11100110 10100001 10000001

รหัสจุด 128 รหัสแรก (ASCII) ต้องการ 1 ไบต์ รหัสจุด 1,920 รหัสถัดไปต้องการ 2 ไบต์ในการเข้ารหัส ซึ่งครอบคลุมตัวอักษรละติน เกือบทั้งหมดที่เหลือ รวมถึงส่วนขยาย IPAกรีกซีริลลิก คอติกอาร์เมเนีย ฮิบรูอาหรับซีเรียทาอานาและเอ็นโกตลอดจนเครื่องหมายกำกับเสียงแบบผสม รหัสจุด 61,440 รหัสที่เหลือของ ระนาบหลายภาษาพื้นฐาน (BMP) ต้องการ 3 ไบต์ รวมถึง ตัวอักษรจีน ญี่ปุ่น และเกาหลี ส่วนใหญ่ รหัสจุดที่ไม่ใช่ BMP จำนวน 1,048,576 รหัส ต้องการ 4 ไบต์ ซึ่งรวมถึงอีโมจิตัวอักษร CJKที่ไม่ค่อยพบเห็นและตัวอักษรที่มีประโยชน์อื่นๆ[ 15 ]

UTF-8 เป็นรหัสคำนำหน้าและไม่จำเป็นต้องอ่านเกินไบต์สุดท้ายของจุดรหัสเพื่อถอดรหัส แตกต่างจากการเข้ารหัสข้อความหลายไบต์รุ่นก่อนๆ เช่นShift-JIS UTF-8สามารถ ซิ งโครไนซ์ตัวเองได้ทำให้สามารถค้นหาสตริงหรืออักขระสั้นๆ ได้ และสามารถหาจุดเริ่มต้นของจุดรหัสได้จากตำแหน่งสุ่มโดยย้อนกลับไปไม่เกิน 3 ไบต์ ค่าที่เลือกสำหรับไบต์นำหน้าหมายความว่าการเรียงลำดับรายการสตริง UTF-8 จะอยู่ในลำดับเดียวกับการเรียงลำดับสตริง UTF-32

การเข้ารหัสที่ยาวเกินไป

การใช้แถวในตารางด้านบนเพื่อเข้ารหัสจุดรหัสที่น้อยกว่า "จุดรหัสแรก" (จึงใช้ไบต์มากกว่าที่จำเป็น) เรียกว่าการเข้ารหัสที่ยาวเกินไป การเข้ารหัสแบบนี้เป็นปัญหาด้านความปลอดภัยเพราะทำให้ลำดับอักขระสามารถข้ามการตรวจสอบความปลอดภัยอื่นๆ เช่นการบล็อก../JavaScript ที่เป็นอันตรายได้มีรายงานช่องโหว่ที่มีชื่อเสียงมากมายที่เกี่ยวข้องกับการเข้ารหัสที่ยาวเกินไปในผลิตภัณฑ์ต่างๆ เช่นเว็บเซิร์ฟเวอร์IIS ของ Microsoft [ 16 ]และคอนเทนเนอร์เซิร์ฟเล็ต Tomcat ของ Apache [ 17 ]ดังนั้นการเข้ารหัสที่ยาวเกินไปจึงควรถือว่าเป็นข้อผิดพลาดและไม่ควรถอดรหัส

การจัดการข้อผิดพลาด

ลำดับไบต์ทั้งหมดไม่ใช่รูปแบบ UTF-8 ที่ถูกต้องเสมอไป จึงจำเป็นต้องเตรียมตัวถอดรหัส UTF-8 สำหรับกรณีต่อไปนี้:

  • ไบต์ต่อเนื่อง ( 0x800xBF ) ที่อยู่ต้นอักขระ
  • ไบต์ที่ไม่ต่อเนื่อง (หรือส่วนท้ายของสตริง) ก่อนสิ้นสุดอักขระ
  • การเข้ารหัสที่ยาวเกินไป ( 0xC0 , 0xC1 , 0xE0ตามด้วยค่าที่น้อยกว่า0xA0หรือ0xF0ตามด้วยค่าที่น้อยกว่า0x90 )
  • ลำดับไบต์หลายตัวที่ถอดรหัสแล้วได้ค่ามากกว่าU+10FFFF ( 0xF4ตามด้วย0x90หรือมากกว่า, 0xF50xFF )

ตัวถอดรหัส UTF-8 รุ่นแรกๆ หลายตัวจะถอดรหัสสิ่งเหล่านี้โดยไม่สนใจบิตที่ไม่ถูกต้อง UTF-8 ที่ไม่ถูกต้องซึ่งสร้างขึ้นอย่างระมัดระวังอาจทำให้ข้ามหรือสร้างอักขระ ASCII เช่นNUL , เครื่องหมายทับ หรือเครื่องหมายอัญประกาศ ซึ่งนำไปสู่ช่องโหว่ด้านความปลอดภัยRFC 3629ระบุว่า "การใช้งานอัลกอริทึมการถอดรหัสต้องป้องกันการถอดรหัสลำดับที่ไม่ถูกต้อง" [ 18 ]มาตรฐาน Unicodeกำหนดให้ตัวถอดรหัสต้อง: "... ถือว่าลำดับหน่วยรหัสที่ไม่ถูกต้องใดๆ เป็นเงื่อนไขข้อผิดพลาด ซึ่งรับประกันว่าจะไม่ตีความหรือส่งลำดับหน่วยรหัสที่ไม่ถูกต้อง"

เป็นเรื่องปกติที่จะโยนข้อยกเว้นหรือตัดสตริงเมื่อเกิดข้อผิดพลาด[ 19 ]แต่สิ่งนี้จะเปลี่ยนข้อผิดพลาดที่ไม่เป็นอันตราย (เช่น "ไม่พบไฟล์") ให้กลายเป็นการปฏิเสธการให้บริการตัวอย่างเช่น Python 3.0 เวอร์ชันแรกๆ จะออกจากโปรแกรมทันทีหากบรรทัดคำสั่งหรือตัวแปรสภาพแวดล้อมมี UTF-8 ที่ไม่ถูกต้อง[ 20 ]ปัจจุบันโค้ดส่วนใหญ่จะแทนที่ข้อผิดพลาดแต่ละรายการด้วยจุดรหัสเดียว (เช่นU+FFFD – อักขระ ทดแทน ) และดำเนินการถอดรหัสต่อไป

ตัวถอดรหัสบางตัวพิจารณาลำดับE1,A0,20 (รหัส 3 ไบต์ที่ถูกตัดทอนตามด้วยช่องว่าง) เป็นข้อผิดพลาดเดียว ซึ่งไม่ใช่ความคิดที่ดี เนื่องจากการค้นหาอักขระช่องว่างจะพบอักขระที่ซ่อนอยู่ในข้อผิดพลาด ตั้งแต่ Unicode 6 (ตุลาคม 2010) [ 1 ]มาตรฐาน (บทที่ 3) ได้แนะนำ "แนวทางปฏิบัติที่ดีที่สุด" โดยที่ข้อผิดพลาดจะเป็นไบต์ต่อเนื่องหนึ่งไบต์ หรือสิ้นสุดที่ไบต์แรกที่ไม่ได้รับอนุญาต ดังนั้นE1,A0,20จึงเป็นข้อผิดพลาดสองไบต์ตามด้วยช่องว่าง ข้อผิดพลาดมีความยาวไม่เกินสามไบต์ ไม่เคยมีจุดเริ่มต้นของอักขระที่ถูกต้อง และมีข้อผิดพลาดที่เป็นไปได้ 21,952  แบบที่แตกต่างกัน ตัวถอดรหัสจำนวนมากกลับทำให้แต่ละไบต์เป็นข้อผิดพลาด ซึ่งในกรณีนี้E1,A0,20คือ ข้อผิดพลาด สองรายการตามด้วยช่องว่าง ตอนนี้มีข้อผิดพลาดที่แตกต่างกันเพียง 128 แบบ ซึ่งทำให้สามารถจัดเก็บข้อผิดพลาดในสตริงเอาต์พุตได้[ 20 ]หรือแทนที่ด้วยอักขระจากการเข้ารหัสแบบเดิม

มีเพียงส่วนน้อยของสตริงไบต์ที่เป็นไปได้เท่านั้นที่เป็น UTF-8 ที่ปราศจากข้อผิดพลาด: ไบต์หลายตัวไม่สามารถปรากฏพร้อมกันได้ ไบต์ที่มีบิตสูงสุดถูกตั้งค่าไม่สามารถอยู่โดดเดี่ยวได้ และในสตริงแบบสุ่มอย่างแท้จริง ไบต์ที่มีบิตสูงสุดถูกตั้งค่าจะมีโอกาสเพียง1/15ที่จะเริ่มต้นอักขระ UTF-8 ที่ถูกต้อง ผลที่ตามมาคือทำให้ตรวจจับได้ง่ายหากมีการใช้การเข้ารหัสข้อความแบบเก่าแทน UTF-8 โดยไม่ได้ตั้งใจ ทำให้การแปลงระบบเป็น UTF-8 ง่ายขึ้น และหลีกเลี่ยงความจำเป็นที่จะต้องใช้Byte Order Markหรือเมตาเดตาอื่นๆ

ตัวแทน

นับตั้งแต่ RFC 3629 (พฤศจิกายน 2003) อักขระตัวแทนสูงและต่ำที่ใช้โดยUTF-16 ( U+D800ถึงU+DFFF ) ไม่ใช่ค่า Unicode ที่ถูกต้อง และการเข้ารหัส UTF-8 ของอักขระเหล่านี้จะต้องถือว่าเป็นลำดับไบต์ที่ไม่ถูกต้อง[ 18 ]การเข้ารหัสเหล่านี้ทั้งหมดเริ่มต้นด้วย0xEDตามด้วย0xA0หรือสูงกว่า กฎนี้มักถูกละเลยเนื่องจากอนุญาตให้ใช้อักขระตัวแทนในชื่อไฟล์ของ Windows และนั่นหมายความว่าต้องมีวิธีจัดเก็บอักขระเหล่านี้ในสตริง[ 21 ] UTF-8 ที่อนุญาตให้ใช้อักขระตัวแทนครึ่งเหล่านี้ได้รับการเรียก (อย่างไม่เป็นทางการ) ว่าWTF-8ซึ่งย่อมาจาก "wobbly transformation format" [ 22 ]ในขณะที่รูปแบบอื่นที่เข้ารหัสอักขระที่ไม่ใช่ BMP ทั้งหมดเป็นอักขระตัวแทนสองตัว (6 ไบต์แทนที่จะเป็น 4) เรียกว่าCESU- 8

แผนที่ไบต์

แผนภูมิด้านล่างแสดงความหมายโดยละเอียดของแต่ละไบต์ในสตรีมที่เข้ารหัสด้วย UTF-8

0 1 2 3 4 5 6 7 8 9 เอ บี ซี ดี อี เอฟ
0
1
2 ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ เอ บี ซี ดี อี เอฟ จี ชม ฉัน เจ เค แอล เอ็ม เอ็น โอ
5 พี คิว อาร์ เอส ที ยู วี X วาย [ \ ] ^ _
6 ` เอ อี เอฟ จี ชม. ฉัน เจ เค n โอ
7 พี q ที คุณ วี x y z { | } ~
8
9
เอ
บี
ซี 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
ดี 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
อี 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
เอฟ 4 4 4 4 4 4 4 4 5 5 5 5 6 6
อักขระควบคุม ASCII
อักขระ ASCII
ไบต์ต่อเนื่อง
ไบต์แรกของลำดับหน่วยรหัส N ไบต์
ไบต์ต่อเนื่องบางส่วนไม่ได้รับอนุญาต
ยังไม่ได้ใช้งาน

เครื่องหมายลำดับไบต์

ถ้า เครื่องหมายลำดับไบต์ Unicode U+FEFFอยู่ ที่จุดเริ่มต้นของไฟล์ UTF-8 ไบต์สามไบต์แรกจะเป็น0xEF , 0xBB , 0xBF

มาตรฐาน Unicode ไม่ได้กำหนดหรือแนะนำให้ใช้ BOM สำหรับ UTF-8 แต่เตือนว่าอาจพบ BOM ที่จุดเริ่มต้นของไฟล์ที่แปลงรหัสจากการเข้ารหัสอื่น[ 23 ]ในขณะที่ข้อความ ASCII ที่เข้ารหัสโดยใช้ UTF-8 นั้นเข้ากันได้กับ ASCII ในอดีต แต่สิ่งนี้จะไม่เป็นจริงเมื่อละเลยคำแนะนำของมาตรฐาน Unicode และมีการเพิ่ม BOM เข้าไป BOM อาจทำให้ซอฟต์แวร์ที่ไม่พร้อมสำหรับ BOM สับสนได้ แต่ซอฟต์แวร์อื่นๆ สามารถยอมรับ UTF-8 ได้ เช่น ภาษาโปรแกรมที่อนุญาตให้ใช้ไบต์ที่ไม่ใช่ ASCII ในสตริงลิเทอรัลแต่ไม่อนุญาตให้ใช้ที่จุดเริ่มต้นของไฟล์ อย่างไรก็ตาม ยังคงมีซอฟต์แวร์ที่แทรก BOM เสมอเมื่อเขียน UTF-8 และปฏิเสธที่จะตีความ UTF-8 อย่างถูกต้อง เว้นแต่ว่าอักขระตัวแรกจะเป็น BOM (หรือไฟล์นั้นมีเฉพาะ ASCII เท่านั้น)

การเปรียบเทียบกับ UTF-16

เป็นเวลานานแล้วที่มีการถกเถียงกันอย่างมากว่าการประมวลผลข้อความในรูปแบบ UTF-16หรือ UTF-8 ดีกว่ากัน ข้อได้เปรียบหลักของ UTF-16 คือAPI ของ Windowsกำหนดให้ใช้ UTF-16 เพื่อเข้าถึงอักขระ Unicode ทั้งหมด (UTF-8 ไม่ได้รับการสนับสนุนอย่างเต็มที่ใน Windows จนถึงเดือนพฤษภาคม 2019) นี่จึงทำให้ไลบรารีหลายแห่ง เช่นQtต้องใช้สตริง UTF-16 ด้วย ซึ่งส่งผลให้ข้อกำหนดนี้แพร่กระจายไปยังแพลตฟอร์มที่ไม่ใช่ Windows ด้วย

ในยุคแรกเริ่มของ Unicode นั้น ไม่มีอักขระใดที่มีขนาดใหญ่กว่าU+FFFFและ การใช้ ตัวรวมอักขระก็แทบจะไม่เกิดขึ้นเลย ดังนั้นการเข้ารหัส 16 บิตจึงมีขนาดคงที่อย่างมีประสิทธิภาพ บางคนเชื่อว่าการเข้ารหัสขนาดคงที่อาจทำให้การประมวลผลมีประสิทธิภาพมากขึ้น แต่ข้อดีเหล่านั้นก็หายไปทันทีที่ UTF-16 กลายเป็นแบบความกว้างแปรผันได้เช่นกัน

รหัสจุดU+0800U+FFFFใช้พื้นที่ 3 ไบต์ใน UTF-8 แต่ใช้เพียง 2 ไบต์ใน UTF-16 ทำให้เกิดความคิดว่าข้อความในภาษาจีนและภาษาอื่นๆ จะใช้พื้นที่มากขึ้นใน UTF-8 อย่างไรก็ตาม ข้อความจะมีขนาดใหญ่ขึ้นก็ต่อเมื่อมีรหัสจุดเหล่านี้มากกว่ารหัสจุด ASCII 1 ไบต์ ซึ่งแทบจะไม่เกิดขึ้นในเอกสารจริงเนื่องจากการทำเครื่องหมาย[ 24 ]พร้อมกับช่องว่าง บรรทัดใหม่ ตัวเลข เครื่องหมายวรรคตอน คำภาษาอังกฤษ ฯลฯ

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

การนำไปปฏิบัติและการนำไปใช้

ชุดอักขระที่ประกาศใช้สำหรับเว็บไซต์ยอดนิยม 10 ล้านเว็บไซต์แรก ตั้งแต่ปี 2010 ถึง 2021
การใช้การเข้ารหัสหลักบนเว็บตั้งแต่ปี 2001 ถึง 2012 ตามที่ Google บันทึกไว้[ 25 ]โดย UTF-8 แซงหน้าการเข้ารหัสอื่นๆ ทั้งหมดในปี 2008 และครอบคลุมมากกว่า 60% ของเว็บในปี 2012 UTF-8 เป็นการเข้ารหัส Unicode เพียงอย่างเดียวที่ระบุไว้อย่างชัดเจน และส่วนที่เหลือเป็นเพียงชุดย่อยของ Unicode เท่านั้น ตัวเลข ASCII-only รวมถึงเว็บเพจทั้งหมดที่มีเฉพาะอักขระ ASCII เท่านั้น โดยไม่คำนึงถึงส่วนหัวที่ประกาศไว้

UTF-8 เป็นการเข้ารหัสที่ใช้กันมากที่สุดสำหรับเวิลด์ไวด์เว็บตั้งแต่ปี 2008 [ 26 ]ณ เดือนมกราคม 2026 เว็บไซต์ที่สำรวจ 98.9% ใช้ UTF-8 [ 2 ]แม้ว่าหลายหน้าเว็บจะใช้เพียงอักขระ ASCII ในการแสดงเนื้อหา แต่เว็บไซต์จำนวนน้อยมากในปัจจุบันที่ประกาศการเข้ารหัสของตนเป็น ASCII แทนที่จะเป็น UTF-8 [ 27 ]แทบทุกประเทศและทุกภาษามีการใช้การเข้ารหัส UTF-8 บนเว็บมากกว่า 95%

มาตรฐานหลายอย่างรองรับเฉพาะ UTF-8 เท่านั้น เช่น การแลกเปลี่ยน JSONต้องการ UTF-8 (โดยไม่มีเครื่องหมายลำดับไบต์ (BOM)) [ 28 ] WHATWGยังกำหนดให้ใช้ UTF-8 สำหรับข้อกำหนด HTML และDOMซึ่งระบุว่า "การเข้ารหัส UTF-8 เป็นการเข้ารหัสที่เหมาะสมที่สุดสำหรับการแลกเปลี่ยนUnicode " [ 5 ]และInternet Mail Consortiumแนะนำว่าโปรแกรมอีเมลทั้งหมดควรสามารถแสดงและสร้างอีเมลโดยใช้ UTF-8 ได้[ 29 ] [ 30 ] World Wide Web Consortiumแนะนำให้ใช้ UTF-8 เป็นการเข้ารหัสเริ่มต้นใน XML และ HTML (และไม่เพียงแต่ใช้ UTF-8 เท่านั้น แต่ยังประกาศไว้ในเมตาเดตาด้วย) "แม้ว่าอักขระทั้งหมดจะอยู่ในช่วง ASCII ... การใช้การเข้ารหัสที่ไม่ใช่ UTF-8 อาจส่งผลให้เกิดผลลัพธ์ที่ไม่คาดคิด" ข้อกำหนด HTML เวอร์ชัน 5.3 ของ W3C และ Living Standard ปัจจุบันของ WHATWG ต่างก็กำหนดให้ใช้ UTF-8 [ 31 ] [ 32 ]

โปรแกรมซอฟต์แวร์หลายโปรแกรมมีความสามารถในการอ่าน/เขียน UTF-8 อาจต้องให้ผู้ใช้เปลี่ยนตัวเลือกจากการตั้งค่าปกติ หรืออาจต้องใช้ BOM (byte-order mark) เป็นอักขระตัวแรกในการอ่านไฟล์ ตัวอย่างซอฟต์แวร์ที่รองรับ UTF-8 ได้แก่Microsoft Word [ 33 ] [ 34 ] Microsoft Excel ( Office 2003 และ เวอร์ชัน ที่ใหม่กว่า) [ 35 ] Google Drive , LibreOffice [ 36 ]และฐานข้อมูลส่วน ใหญ่

ซอฟต์แวร์ที่ "ตั้งค่าเริ่มต้น" เป็น UTF-8 (หมายความว่าจะเขียนโดยที่ผู้ใช้ไม่ต้องเปลี่ยนการตั้งค่า และอ่านโดยไม่มี BOM) ได้รับความนิยมมากขึ้นตั้งแต่ปี 2010 [ 37 ] Windows Notepadใน Windows ทุกเวอร์ชันที่รองรับในปัจจุบัน จะตั้งค่าเริ่มต้นเป็นการเขียน UTF-8 โดยไม่มี BOM (ซึ่งเป็นการเปลี่ยนแปลงจากWindows 7 Notepad ) ทำให้สอดคล้องกับโปรแกรมแก้ไขข้อความอื่นๆ ส่วนใหญ่[ 38 ]ไฟล์ระบบบางไฟล์ในWindows 11ต้องการ UTF-8 [ 39 ]โดยไม่จำเป็นต้องมี BOM และไฟล์เกือบทั้งหมดใน macOS และ Linux ส่วนใหญ่จะต้องเป็น UTF-8 โดยไม่มี BOM ภาษาโปรแกรมที่ตั้งค่าเริ่มต้นเป็น UTF-8 สำหรับI/Oได้แก่Ruby  3.0 [ 40 ] [ 41 ] R  4.2.2 [ 42 ] RakuและJava  18 [ 43 ] Python 3.15 กำหนดให้ UTF-8 เป็นค่าเริ่มต้นสำหรับ I/O [ 44 ] [ 45 ]เวอร์ชันก่อนหน้าต้องการตัวเลือกในopen()การอ่าน/เขียน UTF-8 [ 46 ] C++23ใช้ UTF-8 เป็นรูปแบบไฟล์ซอร์สโค้ดแบบพกพาเพียงรูปแบบเดียว[ 47 ]

ความเข้ากันได้แบบย้อนหลังเป็นอุปสรรคสำคัญต่อการเปลี่ยนแปลงโค้ดและ API ที่ใช้UTF-16ให้ใช้ UTF-8 แต่สิ่งนี้กำลังเกิดขึ้น ในเดือนพฤษภาคม 2019 ไมโครซอฟต์ได้เพิ่มความสามารถให้แอปพลิเคชันสามารถตั้งค่า UTF-8 เป็น "โค้ดเพจ" สำหรับ Windows API ซึ่งไม่จำเป็นต้องใช้ UTF-16 อีกต่อไป และเมื่อไม่นานมานี้ได้แนะนำให้โปรแกรมเมอร์ใช้ UTF-8 [ 48 ]และยังระบุด้วยว่า "UTF-16 [...] เป็นภาระเฉพาะที่ Windows สร้างขึ้นให้กับโค้ดที่กำหนดเป้าหมายไปยังหลายแพลตฟอร์ม" [ 4 ]สตริงพื้นฐานเริ่มต้นในGo [ 49 ] Julia , Rust , Swift (ตั้งแต่เวอร์ชัน 5) [ 50 ]และPyPy [ 51 ]ใช้ UTF-8 ภายในในทุกกรณี Python (ตั้งแต่เวอร์ชัน 3.3) ใช้ UTF-8 ภายในสำหรับส่วนขยาย Python C API [ 52 ] [ 53 ]และบางครั้งสำหรับสตริง[ 52 ] [ 54 ]และมีแผนที่จะจัดเก็บสตริงเป็น UTF-8 เป็นค่าเริ่มต้นใน Python เวอร์ชันในอนาคต[ 55 ] [ 56 ] Microsoft Visual Studioเวอร์ชันใหม่ๆใช้ UTF-8 ภายใน[ 57 ] Microsoft SQL Server ทุกเวอร์ชันที่รองรับในปัจจุบันรองรับ UTF-8 สำหรับการนำเข้าและส่งออก และนอกจากนี้ ทุกเวอร์ชันที่รองรับหลัก เช่น ตั้งแต่ SQL Server 2019 เป็นต้นไป รองรับ UTF-8 ภายใน และการใช้งานส่งผลให้ความเร็วเพิ่มขึ้น 35% และ "ลดความต้องการพื้นที่จัดเก็บลงเกือบ 50%" [ 58 ]

Javaใช้ UTF-16 ภายในสำหรับcharชนิดข้อมูล และด้วยเหตุนี้จึงใช้กับคลาสCharacter, String, และ[ 59 ]แต่สำหรับการรับส่งข้อมูลจะใช้"Modified UTF-8"ซึ่งเหมือนกับ CESU-8 ยกเว้นอักขระว่างU+0000ใช้การเข้ารหัสแบบยาวเกินสองไบต์0xC0 0x80แทนที่จะเป็นเพียง0x00 [ 60 ] สตริง Modified UTF-8 ไม่เคยมีไบต์ว่างจริง ๆ แต่สามารถมีจุดรหัส Unicode ทั้งหมดรวมถึงU+0000 [ 61 ] ซึ่งช่วยให้สามารถประมวลผลสตริงดังกล่าว (ที่มีไบต์ว่างต่อท้าย) โดยฟังก์ชันสตริงที่ลงท้ายด้วยค่าว่าง แบบดั้งเดิมได้ Java อ่านและเขียน UTF-8 ปกติลงในไฟล์และสตรีม[ 62 ]แต่ใช้ Modified UTF-8 สำหรับการทำให้วัตถุเป็นอนุกรม[ 63 ] [ 64 ]สำหรับJava Native Interface [ 65 ]และสำหรับการฝังสตริงคงที่ในไฟล์คลาส Java [ 61 ] รูปแบบ dex ที่กำหนดโดยDalvikก็ใช้ Modified UTF-8 เดียวกันเพื่อแสดงค่าสตริง[ 66 ] Tclก็ใช้ Modified UTF-8 เดียวกัน[ 67 ] กับ Java สำหรับการแสดงข้อมูล Unicode ภายใน แต่ ใช้ CESU-8 ที่เข้มงวดสำหรับข้อมูลภายนอก StringBuffer 

ภาษา โปรแกรม Raku (เดิมคือ Perl 6) ใช้utf-8การเข้ารหัสเป็นค่าเริ่มต้นสำหรับ I/O ( Perl 5 ก็รองรับเช่นกัน) แม้ว่าการเลือกใน Raku นั้นจะหมายถึง "การทำให้เป็นมาตรฐานเป็น Unicode NFC (normalization form canonical) " ในบางกรณี ผู้ใช้อาจต้องการให้แน่ใจว่าไม่มีการทำให้เป็นมาตรฐาน สำหรับกรณีนี้ " utf8-c8" สามารถใช้ได้[ 68 ] รูปแบบ UTF-8 Clean-8 ที่ Raku นำมาใช้ นั้นเป็นตัวเข้ารหัส/ถอดรหัสที่รักษาไบต์ไว้เหมือนเดิม (แม้แต่ลำดับ UTF-8 ที่ผิดกฎหมาย) และอนุญาตให้มีการสังเคราะห์ Normal Form Grapheme [ 69 ]

ภาษาการเขียนโปรแกรม Pythonเวอร์ชัน 3 ถือว่าไบต์แต่ละไบต์ของสตรีมไบต์ UTF-8 ที่ไม่ถูกต้องเป็นข้อผิดพลาด (ดูการเปลี่ยนแปลงด้วยโหมด UTF-8 ใหม่ใน Python 3.7 [ 70 ] ด้วย ) ซึ่งทำให้เกิดข้อผิดพลาดได้ 128 แบบที่แตกต่างกัน มีการสร้างส่วนขยายเพื่ออนุญาตให้ลำดับไบต์ใดๆ ที่ถือว่าเป็น UTF-8 สามารถแปลงเป็น UTF-16 หรือ UTF-32 ได้โดยไม่สูญเสียข้อมูล โดยการแปลงไบต์ข้อผิดพลาดที่เป็นไปได้ 128 ไบต์เป็นจุดรหัสที่สงวนไว้ 128 จุด และแปลงจุดรหัสเหล่านั้นกลับเป็นไบต์ข้อผิดพลาดเพื่อส่งออก UTF-8 วิธีการที่พบได้บ่อยที่สุดคือการแปลงรหัสเป็นU+DC80 ... U+DCFFซึ่งเป็นค่าตัวแทนต่ำ (ต่อท้าย) และดังนั้นจึงเป็น UTF-16 ที่ "ไม่ถูกต้อง" ตามที่ใช้โดยPEP 383 ของPython (หรือวิธีการ "surrogateescape") [ 20 ] NumPyเวอร์ชัน 2.0 และรูปแบบไฟล์ของมันรองรับ UTF-8 (โดยเพิ่ม StringDType สำหรับมัน) [ 71 ]การเข้ารหัสอีกแบบหนึ่งที่เรียกว่าMirBSD OPTU-8/16 จะแปลงเป็นU+EF80 ... U+EFFFใน พื้นที่ใช้ งานส่วนตัว[ 72 ]ไม่ว่าจะใช้วิธีใด ค่าไบต์จะถูกเข้ารหัสในแปดบิตล่างของจุดรหัสเอาต์พุต การเข้ารหัสเหล่านี้จำเป็นหากต้องการให้ UTF-8 ที่ไม่ถูกต้องยังคงใช้งานได้หลังจากการแปลงเป็นและกลับจาก UTF-16 ที่ใช้ภายในโดย Python และเนื่องจากชื่อไฟล์ Unix อาจมี UTF-8 ที่ไม่ถูกต้อง จึงจำเป็นเพื่อให้สิ่งนี้ทำงานได้[ 73 ]

ระบบไฟล์ส่วนใหญ่บน ระบบ ที่คล้าย Unixสามารถใช้ UTF-8 ในการเข้ารหัสชื่อไฟล์ได้ เนื่องจากการค้นหาชื่อไฟล์ทำได้โดยการเปรียบเทียบไบต์ของชื่อไฟล์ ระบบไฟล์ ext4 ของ Linux และAPFS ของ macOS รองรับการค้นหาชื่อไฟล์แบบไม่คำนึงถึงตัวพิมพ์ใหญ่-เล็ก ซึ่งจำเป็นต้องระบุการเข้ารหัสของชื่อไฟล์ ext4 รองรับ UTF-8 และใช้เป็นค่าเริ่มต้น[ 74 ]และ APFS กำหนดให้ใช้ UTF-8 [ 75 ] HFS Plusรุ่นเก่าของ Apple ใช้UTF-16สำหรับชื่อไฟล์ แต่ใช้ UTF-8 ในลิงก์สัญลักษณ์ [ 76 ] ระบบ ไฟล์ NTFSของ Windows ใช้ UTF-16 สำหรับชื่อไฟล์

มาตรฐาน

ชื่อทางการของระบบการเข้ารหัสคือ `UnicodeConsortium` UTF-8ซึ่งเป็นการสะกดที่ใช้ในเอกสารทั้งหมดของ Unicode Consortium ต้องมี เครื่องหมายยัติภังค์และลบ (hyphen-minus)และห้ามมีช่องว่าง ชื่ออื่นๆ ที่ใช้กันมีดังนี้:

  • มาตรฐานหลายอย่างไม่คำนึงถึงตัวพิมพ์ใหญ่เล็ก และutf-8มักถูกนำมาใช้
  • มาตรฐานเว็บ (ซึ่งรวมถึงCSS , HTML , XMLและส่วนหัว HTTP ) ยังอนุญาตให้utf8ใช้ชื่อแทนอื่นๆ อีกมากมาย[ 77 ]อย่างไรก็ตาม เอกสาร HTML จะต้องระบุการเข้ารหัสเป็น "การจับคู่แบบไม่คำนึงถึงตัวพิมพ์ใหญ่-เล็กของ ASCII สำหรับสตริง 'utf-8 ' " [ 31 ]
  • หน่วยงาน Internet Assigned Numbersอย่างเป็นทางการระบุชื่อcsUTF8แทนเพียงชื่อเดียว[ 78 ]ซึ่งแทบจะไม่ถูกใช้เลย
  • ในบางพื้นที่UTF-8Nหมายถึง UTF-8 ที่ไม่มีเครื่องหมายลำดับไบต์ (BOM) และในกรณีนี้UTF-8อาจหมายความว่ามี BOM [ 79 ] [ 80 ]
  • ในWindows UTF-8 เป็นโค้ดเพจ65001[ 81 ]ที่มีชื่อเชิงสัญลักษณ์CP_UTF8ในซอร์สโค้ด
  • ในMySQLนั้น UTF-8 เรียกว่าutf8mb4[ 82 ] ในขณะที่utf8และutf8mb3อ้างถึงตัวแปรCESU-8 ที่ล้าสมัย [ 83 ]
  • ในOracle DatabaseหมายAL32UTF8ถึง UTF-8 (ตั้งแต่เวอร์ชัน 9.0) ในขณะที่UTF8หมายถึง CESU-8 (ตั้งแต่เวอร์ชัน 8.0) [ 84 ]และไม่แนะนำให้ใช้[ 85 ]
  • ใน HP PCLรหัสสัญลักษณ์สำหรับ UTF-8 คือ18N. [ 86 ]

ปัจจุบันมีคำจำกัดความของ UTF-8 อยู่หลายแบบในเอกสารมาตรฐานต่างๆ ดังนี้:

  • RFC  3629 / STD 63 (2003) ซึ่งกำหนดให้ UTF-8 เป็นองค์ประกอบโปรโตคอลอินเทอร์เน็ตมาตรฐาน
  • RFC  5198กำหนดนิยาม UTF-8 NFCสำหรับการแลกเปลี่ยนข้อมูลผ่านเครือข่าย (2008)
  • ISO/IEC 10646:2020/Amd 1:2023 [ 87 ]
  • มาตรฐานยูนิโคด เวอร์ชัน 17.0.0 (2025)

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

  • มาตรฐานยูนิโคด เวอร์ชัน 2.0 ภาคผนวก A (1996)
  • ISO/IEC 10646-1:1993 ฉบับแก้ไขเพิ่มเติม 2 / ภาคผนวก R (1996)
  • RFC  2044 (1996)
  • RFC  2279 (1998)
  • มาตรฐาน Unicode เวอร์ชัน 3.0 §2.3 (2000) พร้อมด้วย Corrigendum #1 : UTF-8 Shortest Form (2000)
  • ภาคผนวกมาตรฐาน Unicode #27: Unicode 3.1 (2001) [ 88 ]
  • มาตรฐาน Unicode เวอร์ชัน 5.0 (2006) [ 89 ]
  • มาตรฐาน Unicode เวอร์ชัน 6.0 (2010) [ 1 ]

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

ดูเพิ่มเติม

  • เอกสารต้นฉบับในรูปแบบ UTF-8 ( หรือไฟล์ PDF ) เกี่ยวกับแผน 9 จาก Bell Labs
  • ประวัติความเป็นมาของ UTF-8 โดย ร็อบ ไพค์
  • ตัวอักษร สัญลักษณ์ และปาฏิหาริย์ยูนิโค้ดบน YouTube
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1359855149#WTF-8 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ยูทีเอฟ-8

UTF-8เป็น มาตรฐาน การเข้ารหัสอักขระที่ใช้สำหรับการสื่อสารทางอิเล็กทรอนิกส์ กำหนดโดย มาตรฐาน Unicodeชื่อนี้มาจากUnicode Transformation Format – 8-bit ณปี 2026 เกือบทุกเว็บเพจ (99%).

ประวัติศาสตร์

องค์การ มาตรฐานสากล (ISO) ได้เริ่มสร้างชุดอักขระหลายไบต์สากลในปี 1989 ร่างมาตรฐาน ISO 10646 มี ภาคผนวก ที่ไม่บังคับใช้ ชื่อ UTF-1 ซึ่งให้การเข้ารหัสแบบสตรีมไบต์ของ จุดรหัส 32 บิต การเข้ารหัสนี้ไม่เป็นที่น่าพอใจในด้านประสิทธิภาพ รวมถึงปัญหาอื่นๆ...

คำอธิบาย

UTF-8 เข้ารหัสจุดรหัสในหนึ่งถึงสี่ไบต์ ขึ้นอยู่กับค่าของจุดรหัส ในตารางต่อไปนี้ ตัวอักษร u ถึง z ซึ่งแต่ละตัวแทนตัวเลขฐานสิบหก จะถูกแทนที่ด้วย บิต 4 บิต ที่เป็นส่วนประกอบ คือ uuuu ถึง zzzz จากตำแหน่ง U+ uvwxyz :

การเข้ารหัสที่ยาวเกินไป

การใช้แถวในตารางด้านบนเพื่อเข้ารหัสจุดรหัสที่น้อยกว่า "จุดรหัสแรก" (จึงใช้ไบต์มากกว่าที่จำเป็น) เรียกว่า การเข้ารหัสที่ยาวเกินไป การเข้ารหัส แบบนี้เป็นปัญหาด้านความปลอดภัยเพราะทำให้ลำดับอักขระสามารถข้ามการตรวจสอบความปลอดภัยอื่นๆ เช่น การบล็อก ..