3 điểm bởi GN⁺ 2026-02-04 | 1 bình luận | Chia sẻ qua WhatsApp
  • Gần đây, các trích dẫn từ email cũ lan truyền trên Twitter đã làm dấy lên thắc mắc về việc vì sao lại xuất hiện dấu bằng (=) ở cuối câu
  • Ký hiệu này xuất hiện do quá trình mã hóa ‘quoted-printable’, được dùng để đánh dấu rằng dòng vẫn còn tiếp tục khi các dòng dài bị buộc phải tách ra
  • Khi truyền email, CRLF (carriage return + line feed) được dùng làm ký tự xuống dòng; nếu thuật toán giải mã hoạt động sai khi chuyển nó sang NL của Unix, dấu bằng có thể bị giữ lại hoặc làm mất ký tự
  • Ngoài việc dùng cho xuống dòng, dấu bằng còn được dùng để biểu diễn ký tự không phải ASCII (ví dụ: =C2=A0); bộ giải mã lỗi có thể thay thế chúng một cách đơn giản và gây ra sai sót
  • Nguyên nhân của vấn đề là logic giải mã có lỗi và xử lý chuyển đổi không phù hợp, cho thấy người đã xử lý email đó thiếu vững vàng về mặt kỹ thuật

Bản chất của dấu bằng (=) trong các trích dẫn email

  • Trong vài ngày gần đây, nhiều trích dẫn từ email cũ được chia sẻ trên Twitter, khiến hiện tượng dấu bằng ở cuối câu trở nên dễ nhận thấy

    • Tác giả phản bác những ý kiến cho rằng đây là mã hoặc lỗi OCR (nhận dạng ký tự quang học)
    • Thực tế, đây là lỗi xử lý mã hóa phát sinh trong quá trình chuyển đổi email sang dạng dễ đọc hơn
  • Trước đây email chỉ là văn bản thuần, nhưng để xử lý các dòng dài hoặc ký tự đặc biệt, mã hóa ‘quoted-printable’ đã được đưa vào sử dụng

    • Khi tách các dòng dài, người ta thêm dấu bằng (=) ở cuối dòng để biểu thị rằng “dòng này vẫn còn tiếp tục”
    • Lúc này, sau dấu bằng sẽ là CRLF (carriage return + line feed)

Lỗi mã hóa xuống dòng và giải mã

  • Máy chủ email dùng CRLF làm chuẩn xuống dòng, còn hệ thống Unix chỉ dùng NL

    • Trong quá trình chuyển đổi, bị mất một byte; nếu bộ giải mã xử lý sai, dấu bằng có thể bị giữ lại hoặc ký tự bị rơi mất
    • Ví dụ, nếu “non- =CRLF cloven” được xử lý sai thì có thể thành “non- loven”, làm biến mất chữ ‘c’
  • Một số triển khai xử lý bằng cách xóa hai ký tự khi gặp dấu bằng ở cuối dòng

    • Thuật toán này hoạt động sai với tệp theo định dạng Unix, khiến dấu bằng vẫn bị giữ nguyên

Một công dụng khác của dấu bằng: mã hóa ký tự không phải ASCII

  • Dấu bằng còn được dùng cho mã hóa ký tự không phải ASCII, không chỉ cho xuống dòng

    • Ví dụ: “=C2=A0” có nghĩa là non-breaking space (khoảng trắng không ngắt dòng)
    • Nó thường xuất hiện khi biểu diễn thụt lề hoặc ký tự đặc biệt trong thân email
  • Tác giả cho rằng một số bộ chuyển đổi chỉ search-replace đơn giản với các chuỗi như =C2, =A0không dùng bộ giải mã chuẩn

Bối cảnh kỹ thuật và tiêu chuẩn

  • Chuẩn RFC 2045 định nghĩa mã hóa quoted-printable là cơ chế transport

    • Sau khi nhận, nó phải được giải mã và lưu dưới dạng văn bản sạch
    • Tuy nhiên, trong nhiều triển khai thực tế, bước này bị bỏ qua nên lỗi xử lý xuống dòng xảy ra thường xuyên
  • Trong ví dụ mã, (quoted-printable-decode-string "he=\nllo") được khôi phục đúng thành "hello"

    • Đó là vì thuật toán được tái sử dụng từ ngữ cảnh máy chủ SMTP, nơi giả định có CRLF
    • Nó hoạt động bình thường trên tệp kiểu Windows nhưng thất bại trên hệ Unix

Kết luận

  • Dấu bằng trong các trích dẫn email là tàn dư của mã hóa quoted-printable, và là kết quả của việc kết hợp giữa
    lỗi xử lý xuống dòng và lỗi giải mã ký tự không phải ASCII
  • Căn nguyên của vấn đề là việc triển khai bộ giải mã thiếu chính xác và sai sót trong chuyển đổi mã hóa
  • Tác giả tóm lược đây là “một vấn đề kỹ thuật, đồng thời là kết quả của cách xử lý sai”,
    đồng thời nhấn mạnh sự cần thiết phải tuân thủ chặt chẽ các tiêu chuẩn chi tiết trong quá trình chuyển đổi email

1 bình luận

 
GN⁺ 2026-02-04
Ý kiến trên Hacker News
  • Nhân vật chính của bài viết này là Lars Ingebrigtsen, người đã viết tài liệu hướng dẫn cho Gnus, gói trình đọc email/Usenet của Emacs
    Tài liệu của ông vừa dí dỏm vừa hữu ích, và ông hiểu về việc phân tích email sâu hơn rất nhiều so với đa số mọi người
    Có thể xem tài liệu tại đây, và một phiên bản khác ở liên kết này

    • Ông không chỉ viết tài liệu mà còn là một nhà phát triển của chính Gnus
      Tôi còn nhớ thời ông lần đầu tạo ra Gnus ở Đại học Oslo (UiO)
      Ông là một ngôi sao lập trình viên nho nhỏ trong giới sinh viên khoa tin học của chúng tôi, và mọi người đều dùng Emacs cùng Gnus
  • Vụ việc này là ví dụ điển hình của kiểu người “biết quá nhiều đến mức nguy hiểm
    Ai cũng biết email không phải chỉ là văn bản thuần túy, nhưng không phải ai cũng biết không thể xử lý giải mã quoted-printable bằng phép thay thế đơn giản
    Nó cùng loại với lỗi tự parse HTML bằng regex: lúc đầu có vẻ chạy được, nhưng rồi về sau lại dẫn tới cảnh hồ sơ chứng cứ trước quốc hội đầy các ký hiệu ‘=’

    • Có người chia sẻ câu trả lời nổi tiếng trên Stack Overflow, giải thích một cách hài hước vì sao không nên parse HTML bằng regex
    • Vì đầu ra nhìn chung vẫn đọc được nên không ai nhận ra vấn đề, mãi đến nhiều năm sau khi nó được nộp làm chứng cứ trước quốc hội mới bị phát hiện
    • Kết lại bằng câu đùa “đội ngũ giỏi nhất hiện đang xử lý việc này”
  • Có câu hỏi rằng “tại sao máy chủ mail lại ghét các dòng quá dài”

    • SMTP là giao thức dựa trên dòng, nên phần thân thư cũng được truyền theo từng dòng
      Máy chủ phải parse header nên không thể chỉ coi nó như một khối nhị phân đơn giản
      IMAP yêu cầu máy chủ phải parse hoàn chỉnh, còn POP3 vốn dành cho một thiết bị duy nhất nên ngày nay không còn phù hợp
    • Trước đây mail được xử lý theo từng dòng với bộ đệm độ dài cố định
      RFC 821 giới hạn độ dài dòng tối đa 1000 byte, và để tương thích thì việc ngắt ở dưới 80 ký tự là rất phổ biến
      Vì vậy mã hóa Base64 cũng chèn ngắt dòng sau mỗi 76 ký tự
    • Vào thời SMTP được thiết kế, bộ nhớ cực kỳ hạn chế
      Ví dụ PDP-11 có khoảng 512KB, VAX-11 khoảng 2MB, và lập trình viên khi đó tính toán bộ nhớ đến từng byte
    • Có người còn minh họa trực tiếp luồng lệnh SMTP, giải thích cấu trúc giao tiếp bằng HELO, MAIL FROM, RCPT TO, DATA v.v.
    • Nhắc tới mạng đại học BITNET trong thập niên 1980, hồi tưởng rằng khi đó cũng đã có giới hạn độ dài dòng
      Có thể xem tài liệu liên quan trên tài liệu chính thức của IBMWikipedia
  • Ban đầu tôi tưởng bài này sẽ nói về ý nghĩa của các toán tử như = == === .=. <== ==> <<== ==>> (==) => =~=

    • Có người đùa rằng “đây là Haskell cho loài kiến à?”
    • Nhưng hóa ra nội dung thật còn thú vị hơn nhiều
  • Cá nhân tôi từng tự viết phần mềm lưu trữ email
    Phần khó nhất là xử lý các trường hợp biên trong những file .eml tích lũy suốt hơn 20 năm
    Ý tưởng thì đơn giản nhưng email lại phức tạp đến ngạc nhiên

    • Chuẩn email không phải được thiết kế lại từ đầu mà là một chuẩn bị nguyền rủa ghép vá từ nhiều hệ thống sẵn có
      Việc kiểm tra tính hợp lệ của địa chỉ email trên thực tế gần như bất khả thi
    • Có người từng làm một mail client chạy trên console, trong đó 25% viết bằng C++, 75% bằng Lua để định nghĩa UI và xử lý
      Trong vài năm có một nhóm nhỏ người dùng, nhưng xử lý MIME là nỗi đau lớn nhất
  • Điều tôi thấy thú vị không phải bản thân dấu ‘=’, mà là hiện tượng các ký tự xung quanh nó biến mất
    Nó giống như lỗi off-by-one: thay vì xóa dấu ‘=’ thì một phần văn bản thật lại bị mất
    Có lẽ việc chuyển đổi CRLF/LF có liên quan

    • Bài gốc giải thích khá chính xác nguyên nhân của điều này
    • Chính kiểu này tạo ra bí ẩn ký tự biến mất trong các tài liệu chứng cứ
  • Có người thắc mắc vì sao vấn đề này lại xuất hiện ngay bây giờ
    Mấy ngày gần đây người ta liên tục đăng các email cũ lên Twitter, nên tự hỏi nguyên nhân là gì

    • Có lẽ là do công bố email liên quan tới Epstein
    • Thực tế DOJ được cho là đã công bố thêm email của Epstein
  • Một số người nêu khả năng nguyên nhân không phải Gmail mà là quá trình chuyển đổi ở máy chủ trung gian
    Ngoài việc đổi CRLF→LF, nếu áp dụng quoted-printable hai lần thì hiện tượng còn sót lại dấu ‘=’ cũng có thể xuất hiện, nên có thể đã có hai máy chủ mail tham gia

    • Một số file PDF cho thấy metadata plist của Apple Mail.app, nên có thể chúng được trích xuất từ một định dạng nội bộ
    • Điều này thường xảy ra trong quá trình thu thập chứng cứ pháp lý
      Trên thực tế thường là thực tập sinh không chuyên gom dữ liệu bằng công cụ đơn giản, qua nhiều lần chuyển đổi khiến định dạng bị hỏng
      Bản gốc thì đã bị xóa, và thứ còn lại chỉ là dữ liệu mảnh vỡ chỉ còn hình dạng bên ngoài
    • Đôi khi vấn đề xảy ra khi nhập email vào file PST của MS Outlook
    • Nó trông không giống một bản dump Gmail đơn lẻ, mà giống kết quả của nhiều hệ thống cùng “giúp đỡ” biến dạng dữ liệu
    • Cũng có ý kiến cho rằng giả thuyết này nghe thuyết phục nhất
  • Bài trên archive.today cũng cho thấy cùng hiện tượng quoted-printable bị vỡ
    Các liên kết liên quan là pastes.io/correspondchuỗi HN

  • Có người nói rằng khi xem email tải về từ Outlook, sẽ rất tiện nếu có một trình xem .eml tự động giải mã quoted-printable