3 คะแนน โดย GN⁺ 2026-02-04 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ช่วงหลังมานี้มีการแชร์ ข้อความอ้างอิงจากอีเมลเก่า บน Twitter กันแพร่หลาย พร้อมตั้งคำถามว่าทำไมถึงมี เครื่องหมายเท่ากับ (=) โผล่อยู่ท้ายประโยค
  • เครื่องหมายนี้เกิดจากกระบวนการเข้ารหัสแบบ quoted-printable ซึ่งใช้แสดงว่าบรรทัดยังต่อเนื่องกันเมื่อมีการบังคับตัดบรรทัดยาว
  • ตอนส่งอีเมลจะใช้ CRLF (carriage return + line feed) เป็นตัวขึ้นบรรทัดใหม่ แต่เมื่อแปลงเป็น NL ของ Unix ถ้าอัลกอริทึมถอดรหัสทำงานผิดพลาด ก็อาจมีเครื่องหมายเท่ากับค้างอยู่หรือทำให้ตัวอักษรหายไป
  • นอกจากใช้กับการขึ้นบรรทัดใหม่แล้ว เครื่องหมายเท่ากับยังใช้แทน อักขระที่ไม่ใช่ ASCII (เช่น =C2=A0) ได้ด้วย และตัวถอดรหัสที่ผิดพลาดอาจแทนที่มันแบบตรง ๆ จนทำให้เกิดข้อผิดพลาด
  • ต้นตอของปัญหาคือ ตรรกะการถอดรหัสที่มีบั๊กและการแปลงข้อมูลที่ไม่เหมาะสม ซึ่งสะท้อนว่าผู้ที่นำอีเมลไปประมวลผลนั้นขาดความชำนาญทางเทคนิค

ตัวตนที่แท้จริงของเครื่องหมายเท่ากับ (=) ในข้อความอ้างอิงจากอีเมล

  • ในช่วงไม่กี่วันที่ผ่านมา มีการแชร์ ข้อความอ้างอิงจากอีเมลเก่า จำนวนมากบน Twitter และสังเกตเห็นปรากฏการณ์ที่มีเครื่องหมายเท่ากับอยู่ท้ายประโยค

    • ผู้เขียนโต้แย้งคำอธิบายที่เข้าใจผิดว่าเป็น โค้ดหรือข้อผิดพลาดจาก OCR (การรู้จำอักขระด้วยแสง)
    • แท้จริงแล้วมันคือ ข้อผิดพลาดในการจัดการ encoding ที่เกิดขึ้นระหว่างกระบวนการแปลงอีเมลให้อ่านง่ายขึ้น
  • เดิมทีอีเมลเป็นเพียงข้อความธรรมดา แต่เพื่อรองรับบรรทัดยาวและอักขระพิเศษ จึงมีการนำ การเข้ารหัสแบบ quoted-printable มาใช้

    • เมื่อต้องตัดบรรทัดยาว จะเติมเครื่องหมายเท่ากับ (=) ไว้ท้ายบรรทัดเพื่อบอกว่า “บรรทัดนี้ยังต่อเนื่อง”
    • จากนั้นหลังเครื่องหมายเท่ากับจะตามด้วย CRLF (carriage return + line feed)

ข้อผิดพลาดในการเข้ารหัสและถอดรหัสการขึ้นบรรทัดใหม่

  • เซิร์ฟเวอร์อีเมลใช้การขึ้นบรรทัดใหม่แบบ CRLF เป็นมาตรฐาน แต่ระบบ Unix ใช้เพียง NL

    • ระหว่างการแปลงจะมีข้อมูลหายไปหนึ่งไบต์ และหากตัวถอดรหัสจัดการผิด ก็อาจทำให้เครื่องหมายเท่ากับค้างอยู่หรือตัวอักษรบางตัวหายไป
    • ตัวอย่างเช่น ถ้า non- =CRLF cloven ถูกประมวลผลผิด อาจกลายเป็น non- loven จนตัว c หายไป
  • บาง implementation จะจัดการโดยลบอักขระสองตัวเมื่อพบเครื่องหมายเท่ากับที่ท้ายบรรทัด

    • อัลกอริทึมนี้จะทำงานผิดพลาดกับไฟล์รูปแบบ Unix และทำให้เกิดอาการที่เครื่องหมายเท่ากับยังคงหลงเหลืออยู่

อีกหน้าที่หนึ่งของเครื่องหมายเท่ากับ: การเข้ารหัสอักขระที่ไม่ใช่ ASCII

  • เครื่องหมายเท่ากับไม่ได้ใช้แค่กับการขึ้นบรรทัดใหม่ แต่ยังใช้ในการเข้ารหัส อักขระที่ไม่ใช่ ASCII ด้วย

    • ตัวอย่าง: =C2=A0 หมายถึง non-breaking space (ช่องว่างที่ไม่ให้ตัดบรรทัด)
    • มักพบได้บ่อยเมื่อใช้อินเดนต์หรือแสดงอักขระพิเศษในเนื้อหาอีเมล
  • ผู้เขียนคาดว่าตัวแปลงบางตัวเพียงแค่แทนที่ =C2, =A0 แบบ search-replace ตรง ๆ โดย ไม่ได้ใช้ตัวถอดรหัสที่ถูกต้องตามปกติ

พื้นหลังทางเทคนิคและมาตรฐาน

  • มาตรฐาน RFC 2045 กำหนดให้การเข้ารหัสแบบ quoted-printable เป็นรูปแบบสำหรับ การส่งข้อมูล (transport)

    • หลังรับข้อมูลแล้วควรถูกถอดรหัสและเก็บเป็น ข้อความที่สะอาด ตามหลักการ
    • แต่ใน implementation จริง ขั้นตอนนี้มักถูกละเลย ทำให้ข้อผิดพลาดเรื่องการจัดการบรรทัดใหม่เกิดขึ้นบ่อย
  • ในตัวอย่างโค้ด (quoted-printable-decode-string "he=\nllo") จะถูกกู้คืนเป็น "hello" ได้อย่างถูกต้อง

    • สาเหตุเพราะมีการนำอัลกอริทึมที่ตั้งสมมติฐานว่าอยู่ในบริบทของเซิร์ฟเวอร์ SMTP และใช้ CRLF กลับมาใช้ซ้ำ
    • บนไฟล์ที่มาจาก Windows มันทำงานได้ปกติ แต่บนระบบ Unix จะล้มเหลว

บทสรุป

  • เครื่องหมายเท่ากับในข้อความอ้างอิงจากอีเมลคือ เศษตกค้างของการเข้ารหัสแบบ quoted-printable และเป็นผลลัพธ์จากการรวมกันของ
    ข้อบกพร่องในการจัดการการขึ้นบรรทัดใหม่และการถอดรหัสอักขระที่ไม่ใช่ ASCII
  • รากของปัญหาที่แท้จริงคือ การ implement ตัวถอดรหัสอย่างไม่แม่นยำและความผิดพลาดในการแปลง encoding
  • ผู้เขียนสรุปว่านี่คือ “ปัญหาทางเทคนิคและผลลัพธ์จากการประมวลผลที่ผิดพลาด” พร้อมเน้นย้ำว่าจำเป็นต้องปฏิบัติตามมาตรฐานอย่างละเอียดในกระบวนการแปลงอีเมล

1 ความคิดเห็น

 
GN⁺ 2026-02-04
ความคิดเห็นจาก Hacker News
  • ตัวเอกของบทความนี้คือ Lars Ingebrigtsen ผู้เขียนคู่มือของ Gnus ซึ่งเป็นแพ็กเกจอ่านอีเมล/Usenet ของ Emacs
    คู่มือของเขาทั้งมีไหวพริบและให้ความรู้ พร้อมทั้งแสดงให้เห็นว่าเขาเข้าใจการพาร์สอีเมลลึกกว่าคนส่วนใหญ่มาก
    ดูคู่มือได้ที่นี่ และอีกเวอร์ชันอยู่ที่ลิงก์นี้

    • เขาไม่ได้เป็นแค่คนเขียนคู่มือ แต่ยังเป็นผู้พัฒนา Gnus เองด้วย
      ฉันจำช่วงที่เขาสร้าง Gnus ขึ้นมาเป็นครั้งแรกที่มหาวิทยาลัยออสโล (UiO) ได้
      เขาเป็นเหมือน นักพัฒนาดาวเด่น ตัวเล็ก ๆ ในหมู่นักศึกษาภาควิชาวิทยาการคอมพิวเตอร์ของเรา และทุกคนก็ใช้ Emacs กับ Gnus กัน
  • เหตุการณ์นี้เป็นตัวอย่างคลาสสิกของคนที่ “รู้มากจนเป็นอันตราย
    รู้อยู่ว่าอีเมลไม่ได้เป็นแค่ข้อความธรรมดา แต่ไม่รู้ว่า quoted-printable decode ไม่ควรจัดการด้วยการแทนที่ข้อความแบบง่าย ๆ
    มันเป็นบั๊กประเภทเดียวกับการพาร์ส HTML ด้วย regex โดยตรง ที่ช่วงแรกดูเหมือนจะใช้ได้ดี ก่อนจะลงเอยด้วยสถานการณ์ที่ มีเครื่องหมาย ‘=’ เต็มไปหมดในหลักฐานที่ยื่นต่อรัฐสภา

    • มีการแชร์ คำตอบบน Stack Overflow อันโด่งดังที่อธิบายอย่างขำ ๆ ว่าทำไมไม่ควรพาร์ส HTML ด้วย regex
    • เพราะผลลัพธ์โดยรวมยังพออ่านได้ ไม่มีใครสังเกตเห็นปัญหา จนกระทั่งหลายปีต่อมามันถูกยื่นเป็นหลักฐานต่อรัฐสภา
    • ปิดท้ายด้วยมุกว่า “ตอนนี้บุคลากรชั้นยอดกำลังจัดการอยู่”
  • มีคำถามว่า “ทำไมเมลเซิร์ฟเวอร์ถึงเกลียดบรรทัดยาว ๆ”

    • SMTP เป็น โปรโตคอลแบบอิงบรรทัด ดังนั้นเนื้อความของข้อความจึงถูกส่งเป็นบรรทัด ๆ ด้วย
      เซิร์ฟเวอร์ต้องพาร์สเฮดเดอร์ จึงไม่สามารถมองมันเป็น binary blob ธรรมดาได้
      IMAP ต้องให้เซิร์ฟเวอร์พาร์สอย่างสมบูรณ์ ส่วน POP3 ถูกออกแบบมาสำหรับอุปกรณ์เดี่ยวซึ่งไม่ค่อยเหมาะกับยุคนี้แล้ว
    • ในอดีต ระบบอีเมลประมวลผลทีละบรรทัดด้วยบัฟเฟอร์ขนาดคงที่
      RFC 821 จำกัดความยาวบรรทัดไว้สูงสุด 1000 ไบต์ และเพื่อความเข้ากันได้ก็มักตัดไม่ให้เกิน 80 ตัวอักษร
      เพราะแบบนี้ การเข้ารหัส Base64 จึงใส่การขึ้นบรรทัดใหม่ทุก ๆ 76 ตัวอักษร
    • ตอนที่ SMTP ถูกออกแบบ หน่วยความจำมีจำกัดอย่างรุนแรง
      เช่น PDP-11 มีราว 512KB และ VAX-11 มีราว 2MB ขณะที่โปรแกรมเมอร์ในยุคนั้น คำนวณหน่วยความจำกันในระดับไบต์
    • มีการยกตัวอย่างลำดับคำสั่งของ SMTP โดยตรง พร้อมอธิบายโครงสร้างการสื่อสารผ่าน HELO, MAIL FROM, RCPT TO, DATA เป็นต้น
    • มีการพูดถึงเครือข่ายมหาวิทยาลัยยุค 1980 อย่าง BITNET พร้อมรำลึกว่าตอนนั้นก็มีข้อจำกัดเรื่องความยาวบรรทัดเช่นกัน
      ดูเอกสารที่เกี่ยวข้องได้จากเอกสารทางการของ IBM และWikipedia
  • ตอนแรกนึกว่าบทความนี้จะพูดถึง ความหมายของโอเปอเรเตอร์ อย่าง = == === .=. <== ==> <<== ==>> (==) => =~=

    • มีคนเล่นมุกว่า “นี่คือ Haskell สำหรับมดหรือเปล่า?”
    • แต่กลับกลายเป็นว่าเนื้อหาจริงน่าสนใจกว่ามาก
  • ส่วนตัวฉันเคยทำซอฟต์แวร์เก็บถาวรอีเมลขึ้นมาเอง
    การจัดการ edge case ของไฟล์ .eml ที่สะสมมากว่า 20 ปีคือส่วนที่ยากที่สุด
    แนวคิดมันดูเรียบง่าย แต่อีเมลซับซ้อนอย่างน่าประหลาด

    • มาตรฐานอีเมลไม่ได้ถูกออกแบบขึ้นใหม่ตั้งแต่ต้น แต่เป็น มาตรฐานต้องสาป ที่เกิดจากการเอาระบบเดิม ๆ มาฝืนต่อกัน
      แม้แต่การตรวจสอบความถูกต้องของที่อยู่อีเมลก็แทบเป็นไปไม่ได้ในทางปฏิบัติ
    • เคยทำเมลไคลเอนต์แบบคอนโซล โดย 25% เป็น C++ และ 75% เป็น Lua เพื่อกำหนด UI และกระบวนการทำงาน
      มีผู้ใช้กลุ่มเล็ก ๆ อยู่หลายปี แต่ การจัดการ MIME คือความทรมานที่สุด
  • สิ่งที่ฉันสนใจไม่ใช่แค่เครื่องหมาย ‘=’ เอง แต่เป็นปรากฏการณ์ที่ ตัวอักษรรอบ ๆ มันหายไป
    มันดูคล้าย off-by-one error ตรงที่แทนที่จะลบ ‘=’ กลับกลายเป็นว่าข้อความจริงบางส่วนหายไป
    อาจเกี่ยวข้องกับการแปลง CRLF/LF ก็ได้

    • บทความต้นฉบับอธิบายเหตุผลนี้ไว้อย่างชัดเจน
    • เลยเกิดเป็น ปริศนาที่ตัวอักษรหายไปจากหลักฐาน ในลักษณะนี้
  • มีคนสงสัยว่าทำไมปัญหานี้ถึงเพิ่งมาเกิด ตอนนี้
    ช่วงไม่กี่วันที่ผ่านมา ผู้คนกำลังโพสต์อีเมลเก่าลงบน Twitter และก็สงสัยว่ามันเกิดจากอะไร

    • มีความเห็นว่าน่าจะเป็นเพราะ การเปิดเผยอีเมลที่เกี่ยวข้องกับ Epstein
    • และมีการบอกว่าจริง ๆ แล้ว DOJ ได้เปิดเผยอีเมลของ Epstein เพิ่มเติม
  • บางคนตั้งข้อสังเกตว่าต้นตอของปัญหานี้อาจไม่ใช่ Gmail แต่เป็น การแปลงข้อมูลที่เซิร์ฟเวอร์กลางทาง
    นอกจากการแปลง CRLF→LF แล้ว ถ้า quoted-printable ถูกประมวลผลซ้ำสองครั้งก็จะเกิดอาการมี ‘=’ ค้างอยู่ได้ ดังนั้นอาจมีเมลเซิร์ฟเวอร์สองตัวเข้ามาเกี่ยวข้อง

    • ใน PDF บางไฟล์มี metadata แบบ plist ของ Apple Mail.app โผล่มา จึงอาจเป็นข้อมูลที่ถูกดึงออกมาจากฟอร์แมตภายใน
    • เรื่องแบบนี้เกิดขึ้นบ่อยในกระบวนการรวบรวมพยานหลักฐานทางกฎหมาย
      ในความเป็นจริงมักเป็น เด็กฝึกงานที่ไม่ใช่มืออาชีพ ใช้เครื่องมือพื้น ๆ รวบรวมข้อมูล แล้วข้อมูลก็ถูกแปลงหลายรอบจนฟอร์แมตพัง
      ต้นฉบับถูกทำลายไปแล้ว เหลือเพียง เศษข้อมูลที่เหลือแต่รูปทรง เท่านั้น
    • บางครั้งปัญหานี้ก็เกิดตอนนำเข้าอีเมลไปยัง ไฟล์ PST ของ MS Outlook
    • มันดูไม่เหมือน Gmail dump ก้อนเดียว แต่เหมือนเป็นผลลัพธ์จากหลายระบบที่ “พยายามช่วย” จนทำให้ข้อมูลผิดรูป
    • บางคนก็มองว่าสมมติฐานนี้น่าเชื่อที่สุด
  • บทความใน archive.today ก็มีอาการ quoted-printable พังแบบเดียวกัน
    ลิงก์ที่เกี่ยวข้องคือ pastes.io/correspond และ เธรด HN

  • มีคนบอกว่าเวลาเปิดดูอีเมลที่ดาวน์โหลดจาก Outlook ถ้ามี ตัวดูไฟล์ .eml ที่ถอด quoted-printable ให้อัตโนมัติได้ก็คงจะดี