มีกระต่ายซ่อนอยู่ในพงหญ้า: เมื่อเอาคาโอโมจิจาก Simeji ไปแทรกในอักษรไทยและเมียนมา Unicode ก็กลายเป็นสวนสัตว์ป่า

มองเผิน ๆ เหมือนกระต่ายตัวเล็กกำลังจ้องเราอยู่ แต่ Unicode ไม่ได้ลงทะเบียนชุดนี้เป็นอีโมจิกระต่าย ฐานของมันคือ U+AA94…

แชร์บทความนี้

แชร์บทความนี้

โฆษณา
โฆษณา

1. สรุปใน 5 วินาที: มองเห็นเป็นกระต่ายหนึ่งตัว แต่ข้างในคือโค้ดพอยต์สามตัว

ตัวปัญหาคือนี่:

ꪔ̤̮

มองเผิน ๆ เหมือนกระต่ายตัวเล็กกำลังจ้องเราอยู่ แต่ Unicode ไม่ได้ลงทะเบียนชุดนี้เป็นอีโมจิกระต่าย ฐานของมันคือ U+AA94 TAI VIET LETTER LOW TO แล้วตามด้วย U+0324 COMBINING DIAERESIS BELOW และ U+032E COMBINING BREVE BELOW.[1][2]

ภายนอก: สัตว์ตัวจิ๋วน่ารัก
ภายใน: อักษร Tai Viet + เครื่องหมายประกอบ + เครื่องหมายประกอบอีกตัว

หน้าตาเป็นมาสคอต แต่เอกสารภายในเหมือนระบบเก่าอายุยี่สิบปี

2. สรุปใน 30 วินาที: พอเอาไปใส่ใน “พงหญ้า” มันก็ดูเหมือนอาศัยอยู่ตรงนั้นจริง ๆ

จุดเริ่มต้นเป็นเพียงคาโอโมจิตกแต่ง:

- ̗̀ ꪔ̤̥ꪔ̤̮ꪔ̤̫ ̖́-

จากนั้นลองเอา “กระต่าย” ไปแทรกในอักษรเมียนมา:

မြန်မာမြန်မာမြန်မာ ꪔ̤̮ မြန်မာမြန်မာ

สำหรับคนที่อ่านอักษรนั้นไม่ออก รูปทรงกลม ๆ ที่เรียงแน่นอาจถูกสมองมองเป็นพื้นผิวคล้ายพุ่มไม้ แล้วหน้ากระต่ายก็เหมือนโผล่ออกมาจากกลางพง

พอใส่ในข้อความภาษาไทย เอฟเฟกต์ยิ่งชัด:

ภาษาไทยꪔ̤̮ภาษาไทย

ปฏิกิริยาแรกกลายเป็น “เดี๋ยวนะ… ตรงนั้นมีกระต่ายหรือเปล่า?”

ดังนั้นการทดลองที่ “เป็นวิทยาศาสตร์มาก” ขั้นต่อไปก็คือใส่สิบตัว

ภาษาไทยꪔ̤̮ภาษาꪔ̤̥ไทยภาษาꪔ̤̫ไทยꪔ̤̮กำลังꪔ̤̥เขียนอยู่ꪔ̤̫ภาษาไทยꪔ̤̮ภาษาꪔ̤̥ไทยภาษาꪔ̤̫ไทยꪔ̤̮

ถึงตรงนี้ไม่ใช่การอ่านแล้ว เป็นการสำรวจประชากรสัตว์ป่า

3. “กระต่าย” ตัวนี้ประกอบด้วยอะไรจริง ๆ

หน้าตา โค้ดพอยต์
ꪔ̤̥ U+AA94 + U+0324 + U+0325
ꪔ̤̮ U+AA94 + U+0324 + U+032E
ꪔ̤̫ U+AA94 + U+0324 + U+032B

U+AA94 เป็นพยัญชนะจริงในอักษร Tai Viet.[1] ส่วนเครื่องหมายด้านล่างเป็น combining marks ของ Unicode ที่มีรหัสและชื่อของตัวเอง.[2]

Unicode ไม่ได้ซ่อนกระต่ายไว้เป็นมุกลับ สมองมนุษย์ต่างหากที่มองเห็น “หน้า” จากการเรียงตัวของอักขระที่ถูกต้องตามระบบ

วัฒนธรรมคาโอโมจิเห็นช่องว่างนี้แล้วก็จัดให้ทันที

4. ทำไมพอแทรกในภาษาไทยแล้วดูพรางตัวได้แรงมาก

นี่ไม่ใช่การบอกว่าอักษรไทย “แปลก” แต่เป็นมุกจากมุมมองของคนที่อ่านอักษรไทยไม่ออก

ภาษาไทยมีสระและวรรณยุกต์ที่สามารถปรากฏเหนือ ใต้ หน้า หรือหลังพยัญชนะได้ และข้อความภาษาไทยทั่วไปไม่ได้เว้นวรรคทุกคำแบบภาษาอังกฤษ Unicode Line Breaking Algorithm จึงจัดอักษรไทยไว้ในกลุ่มที่ต้องอาศัยการวิเคราะห์ตามภาษาและบริบทเพื่อหาจุดตัดบรรทัดที่เหมาะสม.[4]

จากนั้นเราเอา ꪔ̤̮ ซึ่งตัวมันเองก็มีเครื่องหมายประกอบสองตัวอยู่ใต้ฐาน Tai Viet ไปแทรกตรงกลาง

คนที่อ่านภาษาไทยได้จะเห็นทันทีว่ามีอักขระจากระบบอื่นปะปนอยู่ แต่สำหรับคนที่อ่านไม่ออก เส้นโค้งกับเครื่องหมายบนล่างอาจถูกมองเป็น “พื้นผิว” ต่อเนื่อง ทำให้หน้ากระต่ายพรางตัวโดยบังเอิญ

ภาษาไทยꪔ̤̮ภาษาไทย

แปลแบบสายตาได้ประมาณว่า: หญ้า หญ้า หญ้า… เดี๋ยว เมื่อกี้อะไรสบตาเรา?

5. อักษรเมียนมา เขมร มาลายาลัม และสิงหลก็เล่นมุกนี้ได้

เมียนมา:

မြန်မာမြန်မာ ꪔ̤̮ မြန်မာမြန်မာ

เขมร:

ខ្មែរខ្មែរអក្សរ ꪔ̤̮ ខ្មែរខ្មែរ

มาลายาลัม:

മലയാളം മലയാളം ꪔ̤̮ മലയാളം

สิงหล:

සිංහල භාෂාව ꪔ̤̮ සිංහල

ไทย:

ภาษาไทยกำลังเขียนอยู่ ꪔ̤̮ ภาษาไทย

การจัดอันดับว่า “อักษรไหนซ่อนกระต่ายได้ดีที่สุด” เป็นเรื่องส่วนตัวล้วน ๆ อักษรเหล่านี้เป็นระบบการเขียนจริงที่มีผู้ใช้จริง ไม่ใช่ลวดลายตกแต่ง มุกเกิดจากสมองของคนที่ไม่คุ้นเคยกับอักษรนั้นมองรูปทรงเป็นพื้นผิวก่อน แล้วค่อยเจอหน้ากระต่ายที่แทรกอยู่

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

6. พอผ่านระบบแปลแล้วข้อความเคยเพี้ยนจริง แต่ยังโทษ Unicode normalization อย่างเดียวไม่ได้

หลังจากเอาเวอร์ชันสิบกระต่ายผ่านกระบวนการแปล เคยเห็นผลลัพธ์ที่มีช่องว่างผิดธรรมชาติประมาณนี้:

ภาษาไทยꪔ̤̮ภาษาꪔ̤̥ไทยภ าษาꪔ̤̫ไทยꪔ̤̮กำลังꪔ̤̥เข ียนอยู่...

เรียกมันว่า edge case ของการประมวลผล Unicode ได้ แต่ถ้าบอกว่า “Unicode normalization เป็นคนแทรกช่องว่าง” เลย ก็เร็วเกินหลักฐาน

Unicode normalization กำหนดวิธีแยก เรียงตาม canonical order และประกอบกลับลำดับอักขระที่มีความหมายเทียบเท่ากัน.[5] ส่วนระบบแปลอาจมีขั้นตอนอื่นอีกมาก เช่น การแบ่งประโยค การหาขอบเขตคำ tokenization การจัดการอักขระที่ไม่รู้จัก การบันทึกข้อมูล font fallback การจัดหน้า และการแปลงระหว่างคัดลอกกับวาง

ภาษาไทยและเมียนมาเองก็ต้องใช้การแบ่งข้อความที่พึ่งบริบทมากกว่าภาษาที่แบ่งคำด้วยช่องว่าง.[4] พอแทรก “อักขระฐานจากอีกระบบหนึ่ง + combining marks หลายตัว” ลงไป มันจึงเป็น stress test ที่น่าปวดหัวสำหรับ text pipeline ทั้งเส้น

ถ้าจะรู้ว่าจุดไหนเปลี่ยนจริง ต้องเทียบลำดับโค้ดพอยต์ทีละชั้น: input → storage → API request → ผลแปล → response parsing → rendering

กระต่ายน่ารัก รายงาน incident ไม่ได้น่ารักตาม

7. “หนึ่งตัวอักษร” ที่ตาเห็น ไม่จำเป็นต้องเท่ากับหนึ่ง Unicode code point

Unicode มีแนวคิด grapheme cluster เพื่อประมาณหน่วยที่ผู้ใช้รับรู้ว่าเป็น “หนึ่งอักขระ”.[3]

ตัวอักษรที่มีเครื่องหมายกำกับอาจถูกเก็บเป็นโค้ดพอยต์ที่ประกอบสำเร็จแล้วหนึ่งตัว หรือเป็นอักขระฐานตามด้วย combining marks หนึ่งหรือหลายตัวก็ได้ บนหน้าจออาจเห็นเป็นหน่วยเดียวเหมือนกัน

กระต่ายตัวนี้ก็มีหลายตัวตน:

  • ทางสายตา: กระต่าย 1 ตัว
  • ภายใน: 3 โค้ดพอยต์
  • ความยาวสตริง: ขึ้นกับโมเดลของภาษาโปรแกรมหรือ API
  • การเลื่อนเคอร์เซอร์: ควรเคารพหน่วยที่ผู้ใช้รับรู้
  • Backspace: อาจทำงานต่างกันตาม implementation
  • การค้นหาและเปรียบเทียบ: ขึ้นกับนโยบาย normalization
  • ฟอนต์: fallback และตำแหน่ง combining marks อาจเปลี่ยนรูปร่าง

สรุปว่าทะเบียนสัตว์ป่านับกันเป็นโค้ดพอยต์

8. เป็นมุกก็จริง แต่ดันเป็น Unicode test fixture ที่ดี

ꪔ̤̮ ใช้ทดสอบได้หลายอย่าง:

  1. UTF-8 round trip
  2. combining marks หายหรือไม่ตอน copy-paste
  3. การนับ code point กับ grapheme cluster
  4. เคอร์เซอร์และการลบ
  5. นโยบายเปรียบเทียบ NFC/NFD
  6. font fallback และตำแหน่งเครื่องหมาย
  7. การตัดบรรทัดเมื่อผสมกับไทย เมียนมา หรือเขมร
  8. translation API round trip
  9. search index
  10. การแสดงผลข้ามเบราว์เซอร์และมือถือ

แต่ไม่ควรเอาไปโปรยในข้อมูลจริงแบบไม่มีเหตุผล ควรแยกสตริงประหลาดไว้ใน test fixture และระบุลำดับโค้ดพอยต์ที่คาดหวังให้ชัด

อย่าปล่อยกระต่ายป่าเข้า production database

9. วิธีรับมือจริงสำหรับเว็บหลายภาษา

  • ใช้ UTF-8 ให้สม่ำเสมอ
  • กำหนดนโยบาย normalization ให้ชัดเจน เนื้อหาเว็บมักใช้ NFC แต่กรณีที่ต้องรักษาต้นฉบับต้องมีข้อยกเว้นที่ระบุไว้.[5]
  • แยกความหมายของ byte, code unit, code point และ grapheme cluster
  • ใส่ lang ให้ถูกต้อง และทดสอบฟอนต์กับ line-height ที่เหมาะสม
  • ทดสอบอักษรไทย เมียนมา เขมร และระบบอื่นที่ไม่สามารถจัดการได้ด้วยการ split ตามช่องว่างอย่างง่าย.[4]
  • อย่าแก้ข้อความที่ผู้เขียนสร้างเองแบบเงียบ ๆ ระหว่างนำเข้าคำแปล
  • QA ตำแหน่งเครื่องหมาย การตัดบรรทัด selection copy-paste search และ accessibility ไม่ใช่ดูแค่ว่ามี mojibake หรือไม่
  • ถ้าเพี้ยน ให้เทียบสตริงทีละ layer ก่อนสรุปว่า “Unicode พัง”

ส่วนใหญ่ Unicode ทำตามสเปกของมัน ปัญหามักเริ่มตอนซอฟต์แวร์แอบสมมติว่า “สิ่งที่เห็นเป็นหนึ่งตัว = ภายในเป็นหนึ่งหน่วยง่าย ๆ”

ตรงนั้นเองที่กระต่ายเดินออกมาจากพุ่ม

10. สรุป: สิ่งที่ซ่อนอยู่ในพงหญ้าคือการมองหารูปแบบของมนุษย์กับความลึกของ Unicode

เรื่องเริ่มจากคาโอโมจิน่ารัก:

ꪔ̤̮

พออยู่ในอักษรเมียนมาก็ดูเหมือนซ่อนในพุ่ม พออยู่ในภาษาไทยก็ดูเหมือนมีถิ่นอาศัยอยู่แล้ว ใส่สิบตัวก็กลายเป็นประชากร ส่งผ่านระบบแปลก็กลายเป็นบทเรียน debugging Unicode

ใต้เรื่องตลกมีบทเรียนจริง:

  • หนึ่งอักขระที่มองเห็นอาจประกอบด้วยหลายโค้ดพอยต์
  • combining marks ถูกวาดร่วมกับอักขระฐาน
  • บางระบบอักษรต้องใช้การแบ่งข้อความที่รู้ภาษา
  • normalization, segmentation, line breaking, font, translation และ rendering เป็นคนละ layer
  • หน้าจอที่ดูประหลาดเพียงอย่างเดียวบอกไม่ได้ว่า layer ไหนผิด

และหลังจากเห็นบรรทัดนี้เป็น “กระต่ายในพงหญ้า” ไปแล้วสักครั้ง:

ภาษาไทยꪔ̤̮ภาษาไทย

ก็ยากจะกลับไปมองแบบเดิม

ตั้งใจมาเรียน Unicode สุดท้ายกลับบ้านหลังยืนยันแหล่งอาศัยของกระต่ายเรียบร้อย


แชร์บทความนี้

โฆษณา

หาบทความอื่น

บทความทั้งหมด

Mendoi-chan

ผู้เขียน

Mendoi-chan

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

เกี่ยวกับเว็บไซต์
โฆษณา

บทความล่าสุด

  1. 1นอน 18 ชั่วโมงในวันเดียว: เป็นการนอนชดเชย หรือเป็นสัญญาณที่ควรระวัง?
  2. 2จำเป็นจริงหรือที่จะต้องขอโทษว่า “ยังไม่ได้มีหลานให้พ่อแม่”? บางครั้งแค่ลูกที่โตแล้วกลับบ้านมากินข้าวด้วยกันก็มีความหมายมากพอ
  3. 3วันที่ VTuber วัย 40 กลายเป็น “ศูนย์ชุมชนดิจิทัล” — อายุไม่ได้ฆ่าความต้องการเสมอไป บางครั้งมันแค่เปลี่ยนรูปของความต้องการ
  4. 4ประมาณหนึ่งสัปดาห์ ระบบเขียนบทความด้วย AI กลายเป็น “โรงงานอัตโนมัติ”: หมัดเดียวของ Ultra, Level 6 และเหตุผลที่ Level 7 ยังไม่ต้องรีบ
  5. 5AI เก่งมาก แต่โรงงานมักหยุดตรงคำถามว่า “แล้วจะสร้างอะไร?” — คนที่จุดประกายไอเดียแรกได้ จะเปลี่ยนความสามารถให้กลายเป็นกำลังการผลิต

บทความที่เกี่ยวข้อง

โฆษณา