Bộ chuyển đổi Punycode / IDN

Chuyển văn bản Unicode thành Punycode ASCII (RFC 3492, mã hóa đằng sau các tên miền quốc tế hóa xn--) hoặc giải mã nhãn / tên miền xn-- về lại các ký tự gốc. Bạn có thể nhập một nhãn đơn (ví dụ 中文) hoặc cả tên miền có dấu chấm (ví dụ 例え.jp); mỗi nhãn không phải ASCII được mã hóa độc lập. Ngoài ra: Bộ mã hóa URL | Ascii85 | Base32 / Base58.
Mọi xử lý diễn ra cục bộ trong trình duyệt của bạn — không tải dữ liệu nào lên.
Chưa nghe nói về Punycode? Punycode là gì — giải thích bằng tiếng Anh đơn giản (có ví dụ, các hiểu lầm và các quy tắc thực sự gây khó).
Cách hoạt động: Các nhãn chứa bất kỳ ký tự không phải ASCII nào (CJK, Latin có dấu, emoji, ...) được chuyển thành Punycode ASCII và thêm tiền tố xn--. Các nhãn ASCII thuần (và phần rỗng do dấu chấm cuối) được giữ nguyên. Một nhãn chỉ có ký tự ASCII cơ bản không bao giờ thay đổi.
Ví dụ: 中文 → xn--fiq228c  ·  例え.jp → xn--r8jz45g.jp  ·  bücher.de → xn--bcher-kva.de  ·  😂.com → xn--e28h.com
Cách hoạt động: Mọi nhãn bắt đầu bằng xn-- (tiền tố không phân biệt hoa thường) được giải mã về Unicode; các nhãn ASCII khác được giữ nguyên. Một chữ cái A-Z viết hoa trong phần đã mã hóa (sau dấu gạch ngang cuối) là mơ hồ và bị từ chối — hãy dán nhãn A viết thường.
Ctrl+Enter trong ô nhập sẽ chạy chế độ đang chọn.
Chọn chiều và chạy. Mọi xử lý ở trong trình duyệt của bạn.
Punycode RFC 3492 nhìn qua:
Punycode là mã hóa bootstring: trước tiên sao chép các điểm mã ASCII cơ bản (chữ cái, chữ số, dấu gạch ngang), rồi mỗi điểm mã không phải ASCII được chèn từng cái một như một dãy số nguyên nhỏ dùng mã hóa cơ số 36 có độ dài biến đổi thích ứng độ lệch (chữ số a-z rồi 0-9). Trong tên miền, mỗi nhãn đã mã hóa được thêm tiền tố xn-- để trình duyệt và DNS phân biệt với nhãn thông thường. Điểm mã - đóng vai trò dấu phân cách giữa phần ASCII đã sao chép và phần đã mã hóa.

Các vector đã biết — 中文 → xn--fiq228c, 例え → xn--r8jz45g, 中国 → xn--fiqs8s, bücher → xn--bcher-kva.
Punycode là gì?
Trong một câu: Punycode là một cách đánh vần các ký tự không phải chữ tiếng Anh thuần — tiếng Trung, Latin có dấu, Cyrillic, emoji — chỉ bằng 37 ký tự mà hệ thống tên miền được xây dựng để dùng: a-z, 0-9 và -. Nó được định nghĩa trong RFC 3492, và trong tên miền bạn nhận ra nó qua tiền tố xn--: 中文 thành xn--fiq228c.

Vậy Punycode không phải ngôn ngữ, phông chữ hay mã quốc gia — nó là một phép dịch giữa hai cách đánh vần của cùng một tên. Cách đánh vần Unicode được gọi là nhãn U (中文.com, bücher.de), cách đánh vần ASCII được gọi là nhãn A (xn--fiq228c.com, xn--bcher-kva.de), và toàn bộ ý tưởng đưa tên quốc tế vào DNS được gọi là IDN (tên miền quốc tế hóa) hoặc IDNA, tập quy tắc xây trên nó.

Nó tồn tại vì DNS được thiết kế vào đầu thập niên 1980 quanh một bảng chữ cái nhỏ có chủ đích. Tên máy chủ đi qua DNS, vào tệp zone, bộ nhớ đệm resolver, một dòng nhật ký hay chứng chỉ TLS, phải là ASCII thuần — định dạng truyền đơn giản không có trường cho bất cứ thứ gì khác. Punycode là lối thoát: nó cho phép một tên không phải ASCII đi như thể là ASCII, và cho phép đầu nhận dựng lại chính xác các ký tự gốc. Đó là lý do tên miền tiếng Trung hoạt động trong trình duyệt, và vì sao xn-- là chuỗi duy nhất bạn thấy ở mọi nơi mà cách viết Unicode không thể gửi đi.

Punycode trong 30 giây
Bạn gõ gì (nhãn U) DNS nhận gì (nhãn A) Ý nghĩa
中文.comxn--fiq228c.comCác từ tiếng Trung nghĩa là "tiếng Trung"
中国xn--fiqs8s"Trung Quốc" bằng tiếng Trung
例え.jpxn--r8jz45g.jpVí dụ tiếng Nhật
bücher.dexn--bcher-kva.debücher tiếng Đức, nghĩa là "sách"
münchen.dexn--mnchen-3ya.deMunich
😂.comxn--e28h.comNhãn emoji — hợp lệ trong mã hóa, không hợp lệ ở hầu hết cơ quan đăng ký

Một so sánh độ dài đáng nhớ: 中文 là 2 ký tự và 6 byte trong UTF-8, nhưng xn--fiq228c là 11 byte ASCII. Punycode thường làm tên dài hơn, không bao giờ ngắn hơn.

Cách mã hóa thực sự hoạt động

Lấy bücher và xem ba bước. Bộ máy được gọi là bootstring, và toàn bộ thuật toán chỉ vài chục dòng mã (bạn có thể đọc trong script của trang này).

  1. Sao chép các ký tự thuần lên phía trước. Mọi ký tự ASCII cơ bản được sao chép đúng thứ tự gốc và giữ nguyên khả năng đọc: bücher → bcher. Vì có thứ được sao chép và còn thừa thứ khác, một dấu - được thêm vào làm ranh giới: bcher-.
  2. Viết phần còn lại thành số cơ số 36. Các ký tự còn lại được xử lý theo thứ tự điểm mã tăng dần, và mỗi ký tự được viết như một số độ dài biến đổi cơ số 36 với a=0 … z=25 và 0=26 … 9=35. Với bücher, ký tự còn lại ü thành các chữ số kva.
  3. Gắn tiền tố vào. Phần đã mã hóa nối vào phần đã sao chép cho bcher-kva, và trong ngữ cảnh tên miền được viết là xn--bcher-kva.

Thủ thuật khiến cách làm này thông minh là những gì các số cơ số 36 chứa: không phải chính ký tự, mà là một delta — ký tự cách điểm mã đã mã hóa trước đó bao xa, cộng với vị trí của nó trong chuỗi. Bộ mã hóa đi qua các điểm mã theo thứ tự tăng dần và mỗi nhóm chữ số mô tả một vị trí và một khoảng cách. Sau mỗi ký tự, một số dùng chung gọi là bias được điều chỉnh để số kế tiếp cần ít chữ số nhất có thể.

Hai hệ quả bạn có thể tự thấy ở trên:

  • Ký tự giống nhau thì rẻ. Vì chỉ các khoảng cách được lưu, một chuỗi cùng một ký tự gần như không tốn gì: 30 bản 中 mã hóa thành xn--fiqaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, chỉ 36 byte. Một hỗn hợp chữ Trung không liên quan nhưng gần nhau đo được đóng gói khoảng 41 ký tự vào một nhãn 63 byte hợp lệ, và một ký tự lặp lại đơn lẻ đạt 57.
  • Ký tự rải rác thì tốn kém. Một ký tự xa ký tự trước cần một số delta dài hơn. Văn bản tiếng Trung với nhiều ký tự khác nhau thường tốn khoảng 2–3 chữ cái thêm cho mỗi ký tự, đó là lý do một nhãn CJK hết chỗ quanh 20–40 ký tự dù giới hạn nhãn là 63 byte.

Giải mã là công thức tương tự chạy ngược: sao chép tiền tố ASCII, đọc các chữ số, đổi các delta về lại điểm mã, và chèn mỗi ký tự mới vào chuỗi tại vị trí mà delta mã hóa. Chỉ có chữ số viết thường tồn tại trong bootstring, đó là lý do chữ cái viết hoa bên trong phần đã mã hóa bị từ chối thay vì đoán — DNS không phân biệt hoa thường, nên cho phép cả hai kiểu sẽ làm hai cách viết khác nhau thành mơ hồ.

Bạn thực sự sẽ gặp nó ở đâu
  • Trên thanh địa chỉ. Trình duyệt có thể hiển thị xn--fiq228c.com thay vì 中文.com. Đó là cùng một trang. Một số trình duyệt cố ý hiển thị dạng Punycode khi tên trộn nhiều hệ chữ, chính để một ký tự giống hệt (Cyrillic а so với Latin a) không thể ẩn trong URL.
  • Trong chính DNS. Tệp zone, câu trả lời của dig / nslookup / DNS-over-HTTPS và nhật ký resolver chỉ chứa dạng xn--; Unicode thuần bị từ chối hoặc bị làm hỏng âm thầm.
  • Trong chứng chỉ TLS. Tên thay thế chủ thể của tên miền quốc tế được lưu dưới dạng nhãn A (DNS:xn--fiq228c.com), nên chứng chỉ trông không giống tên bạn gõ là bình thường, không phải không khớp.
  • Trong cấu hình và công cụ. Các mục server_name của máy chủ web / virtual host, tên miền cookie, bảng điều khiển hosting và CDN, tên miền email, khóa API gắn với tên miền, và khóa cơ sở dữ liệu đều an toàn hơn ở dạng nhãn A.
  • Trong kiểm thử và pipeline dữ liệu. Một số thư viện chuyển Unicode thẳng cho resolver và bị lỗi; chuyển sang Punycode trước là cách khắc phục chuẩn. Vì ánh xạ là chính tắc — một nhãn Unicode ánh xạ đúng một nhãn A — dạng xn-- cũng là định danh ổn định cho nhật ký và tìm kiếm.
Punycode không phải là gì

Punycode là một cách đánh vần có thể đảo ngược, không hơn không kém. Nó không phải mã hóa và không phải tính năng bảo mật: ai cũng có thể giải mã bằng công cụ trên, nên một nhãn xn-- chỉ nói "cái này đã được mã hóa" và không gì về việc ai sở hữu nó. Nó cũng không phải nén — nó thường làm văn bản dài hơn, như ví dụ 6 byte sang 11 byte ở trên cho thấy. Và nó không giống các cách khác mà Unicode đi quanh internet; những cách đó giải quyết các tầng khác nhau của vấn đề.

Sơ đồ Biến cái gì thành cái gì Được dùng ở đâu 中文 thành
Punycode (RFC 3492)Một nhãn tên miền Unicode thành chữ cái và chữ số ASCIIChỉ nhãn tên miền quốc tếxn--fiq228c
UTF-8 (RFC 3629)Điểm mã thành byteMọi tệp và yêu cầu webE4 B8 AD E6 96 87 (6 byte)
Mã hóa phần trăm (RFC 3986)Byte thành các escape %XXĐường dẫn URL, chuỗi truy vấn, nội dung form%E4%B8%AD%E6%96%87
Base64 (RFC 4648)Byte thành 64 ký tự ASCIINhị phân trong văn bản, JSON, email, data URL5Lit5paH
Thực thể HTMLĐiểm mã thành tham chiếu có tên hoặc sốMã nguồn HTML và XML中文
Escape UnicodeĐiểm mã thành \uXXXXMã nguồn và chuỗi JSON\u4e2d\u6587

Điểm thực tế: Punycode áp dụng cho các nhãn tên miền của URL, không phải cho cả URL. Đường dẫn và chuỗi truy vấn là một vấn đề khác và dùng mã hóa phần trăm (xem Bộ mã hóa URL).

Giới hạn và quy tắc thực sự gây khó
  • Giới hạn kích thước đến từ DNS, không phải từ Punycode. Một nhãn có thể dài tối đa 63 byte và cả tên tối đa 255 byte (RFC 1034 / 1035). Vì nhãn A là ASCII thuần, số byte bằng số ký tự, và mỗi ký tự không phải ASCII tiêu một phần ngân sách đó — khoảng 1 ký tự ngân sách cho mỗi 1–4 chữ cái Punycode.
  • Punycode chuyển đổi mọi thứ; cơ quan đăng ký chỉ cho phép một số thứ. Quy tắc IDNA nằm trên và hạn chế những điểm mã nào được phép đăng ký — chữ hoa, khoảng trắng, dấu câu như !, và cờ không hợp lệ trong tên miền thật. Trang này thực hiện chuyển đổi RFC 3492, nên sẽ mã hóa vui vẻ văn bản mà cơ quan đăng ký sẽ từ chối.
  • Giữ trong một hệ chữ. IDNA khuyến cáo không trộn các hệ chữ trong một nhãn đơn chính vì các tấn công giả mạo ký tự giống nhau. Một tên có thể được mã hóa và vẫn không dùng được, hoặc dùng được nhưng bị trình duyệt đưa vào danh sách chặn.
  • Không mã hóa hai lần. xn-- theo sau bởi văn bản đã mã hóa là không hợp lệ, và nhãn toàn ASCII không bao giờ thay đổi — không có gì để mã hóa, nên không thêm tiền tố.
  • Dấu chấm cuối không sao. 例え.jp. là tên đầy đủ đủ điều kiện và nhãn rỗng cuối được giữ lại; nhãn rỗng ở giữa thì không hợp lệ làm tên máy chủ.
Trả lời nhanh

"Vì sao tên miền tiếng Trung của tôi hiện là xn--fiq228c.com trên thanh địa chỉ?"

Vì trình duyệt chọn hiển thị nhãn A. Trang vẫn giống hệt; dùng chiều giải mã của trang này để xem dạng Unicode, hoặc mã hóa dạng Unicode để kiểm tra hai cách viết có khớp không.

"Tôi có cần đổi bản ghi DNS, chứng chỉ hay hosting không?"

Không. Hãy giữ nhãn A xn-- ở mọi nơi máy đọc tên (DNS, chứng chỉ, cấu hình), và dùng dạng Unicode chỉ nơi con người đọc.

"Vì sao kết quả dài hơn những gì tôi gõ?"

Vì mã hóa không mang chính các ký tự, nó mang các khoảng cách cơ số 36, và bảng chữ 36 ký tự phải đánh vần các số có thể rất lớn. Tăng độ dài là điều được mong đợi, không phải lỗi.

"Vì sao giải mã báo 'chữ hoa'?"

Vì các chữ số bootstring được định nghĩa chỉ viết thường (a-z, 0-9). Chữ A-Z viết hoa sau dấu gạch ngang cuối là mơ hồ khi tính đến việc DNS không phân biệt hoa thường, nên nó được báo cáo thay vì âm thầm đoán.

"Punycode có áp dụng cho phần trước @ trong địa chỉ email không?"

Chỉ phần tên miền là tên DNS và có thể là Punycode. Phần local được hệ thống thư xử lý, không phải DNS, nên mã hóa này không áp dụng cho nó.

"Hai tên Unicode khác nhau có thể cho cùng một nhãn A không?"

Không. Mã hóa là đơn ánh: các dãy điểm mã khác nhau luôn cho các bootstring khác nhau, nên giải mã xn--fiq228c cho đúng 中文 và không gì khác. Thứ có thể trùng là diện mạo — các ký tự khác nhau trông giống nhau — và đó là tính chất của bộ ký tự Unicode, không phải của mã hóa.

Chuẩn trang này tuân theo
  • RFC 3492 — Punycode, mã hóa bootstring được triển khai trên trang này. Các vector đã biết nêu ở trên được kiểm tra với chuỗi mẫu trong tài liệu đó.
  • RFC 5890, RFC 5891, RFC 5892 và Unicode UTS #46 — IDNA2008 và cách diễn giải phía trình duyệt, các quy tắc quyết định ký tự nào hợp lệ, nhãn được chuẩn hóa ra sao, và các hệ chữ được trộn thế nào.
  • RFC 1034 và RFC 1035 — giới hạn nhãn 63 byte và tên 255 byte kế thừa từ DNS.
  • RFC 3490 và RFC 3491 — thế hệ IDNA2003 cũ hơn, đã được thay thế bởi IDNA2008. Nếu một tên hành xử khác trong phần mềm cũ, thường là vì lý do này.

Ghi chú phạm vi: công cụ này chỉ thực hiện chuyển đổi RFC 3492 và không gì khác. Nó không phải bộ kiểm tra IDN và không kiểm tra quy tắc đăng ký, giá hay tính sẵn có của tên miền — và vì nó không bao giờ liên lạc với mạng, nó không thể cho bạn biết một tên có tồn tại không.

Thử ở trên: dán 中文 và nhấn Mã hóa Văn bản → Punycode để xem nhãn A, hoặc dán xn--fiq228c và nhấn Giải mã Punycode → Văn bản để lấy lại các ký tự.