要把 URL 轉換成 Punycode,只需要對位址中的主機部分進行編碼 — scheme、路徑(query string)、fragment 則保持不變,因為 DNS 僅儲存網域的 ASCII 標籤。Punycode Converter 完全在您的瀏覽器中執行,使用 RFC 3492 Bootstring 演算法,並接受像 bücher.example 或 münchen.de 這類的裸網域,產生其等效的 ASCII 形式 xn--bcher-kva.example 或 xn--mnchen-3ya.de。由於像 https://münchen.de/path?q=test 這種完整 URL 仍包含 scheme、路徑和 query,若直接貼上會被拒絕;必須先將主機部分獨立出來。一旦取得轉換後的 ASCII 名稱,結果必須重新附加回原本的 scheme 和路徑,才能交給域名註冊商、TLS 憑證授權單位或 URL parser。這種主機編碼與 URL 組裝之間的分離,是任何剛接觸 IDN 工作的人最常遇到的絆腳石,也是為什麼 URL 轉 Punycode 實際上是兩個步驟:先萃取,再編碼。

convert url to punycode
將 URL 轉換為 Punycode:先萃取網域

為何 URL 在 DNS 層需要 Punycode

網域名稱系統最初僅定義為接受 ASCII 字元 A 到 Z、數字 0 到 9 以及連字號。這就是 wire format 的完整字母集 — 不含變音符號、希臘字母、漢字,也不含表情符號。當網際網路社群決定人們應能以自己的文字註冊網域名稱時,答案並非擴充 DNS 本身;而是定義一種可逆的編碼方式,將 Unicode 碼點壓縮為 ASCII 字母與連字號。該編碼方式即為 Punycode,定義於 RFC 3492

Applications 中的 Internationalized Domain Names (IDNA) 在 RFC 3492 之上加上一小組規則,讓瀏覽器能對像 münchen.de 這類的主機,逐一編碼每個標籤,並將其 ASCII 形式 xn--mnchen-3ya.de 交給 DNS resolver。Resolver 會儲存並查詢該 ASCII 標籤,而完全不曉得原始拼寫使用何種語言。當回應返回後,瀏覽器再次解碼該標籤,讓使用者在網址列看到 münchen.de。這個來回過程中的每一步都能正常運作,是因為 RFC 3492 是精確的演算法,而非語言翻譯 — 而這也正是 Punycode Converter 在本機端實作的內容。

URL 與網域:Converter 實際接受的內容

URL 是一個結構化的字串,由 scheme、authority (主機加上選擇性的 port)、路徑、選擇性的 query,以及選擇性的 fragment 所組成。Punycode 僅處理主機,而且僅在主機內部的標籤層級上處理。Punycode Converter 的文件化範圍刻意比完整的 URL parser 更為限縮:它不接受 scheme、路徑、port、query 或 fragment,也不對任何內容進行 percent-decode,既不解析 DNS、不測試註冊可用性,也不聯繫 registry。若您將 https://münchen.de 貼到輸入框中,將無法運作。

此工具預期接受像 münchen.de 或 xn--mnchen-3ya.de 這類的網域。在進行任何編碼之前,會使用句點將網域切割為標籤,並將 CJK 文字中看起來與 ASCII 點號完全相同的外觀 Unicode 句點(例如 U+3002)正規化為 ASCII 點號,以維持切割結果的可預測性。空標籤會被拒絕,超過 1,000 個碼點的輸入以及任何格式錯誤的 Bootstring 序列同樣會被拒絕。任何看似路徑、query 或 fragment 的內容都不會被解析為 URL — 將被視為格式錯誤的標籤資料而拒絕處理。這就是為何 percent-encoded URL 不適合作為此處的輸入;percent encoding 是套用於路徑與 query 的獨立編碼系統,若您擁有 percent-encoded 字串,可能需要的是 URL decoder

將 URL 的主機部分轉換為 Punycode

當起點是真實的 URL 而非裸網域時,以下是實際的工作流程。

  1. 複製您想編碼的完整 URL,例如 https://münchen.de/produkte/neu。
  2. 移除所有不屬於主機的部分。移除 https:// scheme、移除路徑 /produkte/neu、移除任何 query string 或 fragment。剩下的字串 — münchen.de — 即為 converter 可接受的內容。
  3. 開啟 Punycode Converter,並選擇 Unicode-to-ASCII 進行這個方向的編碼。僅在檢視 xn-- 名稱時,才使用 ASCII-Punycode-to-Unicode。
  4. 將裸主機貼入輸入欄位並執行轉換。輸出將會是 xn--mnchen-3ya.de,其中 xn-- 前綴僅附加在含有非 ASCII 字元的標籤上,而 .de 標籤則保留為純 ASCII 字串。
  5. 複製結果,然後重新附加原始的 scheme 與路徑,使最終 URL 成為 https://xn--mnchen-3ya.de/produkte/neu。將該完整字串交給符合標準的 URL 程式庫、您域名註冊商的 IDN 欄位,或憑證授權單位的 CN/SAN 項目。

同樣的五步驟流程適用於任何主機含有非 ASCII 字元的 URL,包括希臘文、斯拉夫文、希伯來文、阿拉伯文、CJK 及輔助平面的符號。每個標籤會獨立處理,因此像 bücher.example.com 這類主機會產生 xn--bcher-kva.example.com — 兩個未變動的標籤(example、com)夾著一個編碼後的標籤(xn--bcher-kva)。在將結果交給任何預期接受完整 URL 的對象之前,請重新附加原始的 scheme 與路徑。

RFC 3492 Bootstring 演算法如何編碼標籤

在 converter 內部,每個標籤都由 Bootstring 演算法處理,並使用一組固定的常數:base 36、tmin 1、tmax 26、skew 38、damp 700、initial bias 72,以及 initial code point 128。標籤中既有的 ASCII 字元會先原封不動地複製過去。非 ASCII 碼點接著會以可變長度的 delta 進行編碼,每次處理後 bias 參數會隨之調整,使短標籤與長標籤都能保持效率。實作上會以完整的 Unicode 碼點逐一疊代,而不是 UTF-16 的半段,這表示輔助字元會保持完整,不會被切分成 high surrogate 與 low surrogate 而無法往返轉換。算術溢位檢查會同時保護 delta 乘法與權重累積,避免長字串悄悄發生 wrap-around。

輸入標籤方向輸出標籤備註
bücherUnicode → ASCIIxn--bcher-kva文件化的範例,含拉丁文變音符號,單一標籤
mañanaUnicode → ASCIIxn--maana-pta西班牙文 ñ 加 tilde,來自拉丁變音的測試案例
exampleUnicode → ASCIIexample純 ASCII 標籤,僅小寫處理,不加上 xn-- 前綴
xn--maana-ptaASCII → Unicodemañana反向,xn-- 前綴會在標籤邊界處被消耗

不含任何非 ASCII 碼點的標籤永遠不會加上 xn-- 前綴 — 僅會進行小寫處理並保持不變,這就是為什麼 example.com 維持 example.com,永遠不會變成 xn--example-com。解碼模式僅對以 xn-- 開頭的標籤執行 Bootstring 解碼;其他標籤則視為純 ASCII 處理。這種嚴格的合約使該工具接受的每個標籤都能維持可逆編碼,任何偏差 — 無論是前導的 scheme、路徑斜線、percent-encoded 位元組 — 都會被拒絕,而不會猜測處理。針對所宣告的原始 Punycode 慣例,輸出是確定性的,而複製按鈕僅複製轉換後的網域,不含 scheme 或尾端斜線。

在語法之外驗證結果

成功的轉換並不保證產生的網域到處都會被接受,也不保證它指向您所認為的對象。生產環境的 URL 系統通常在進入 RFC 3492 編碼之前,會先套用 Unicode 正規化、contextual 規則以及 UTS #46 mapping,這代表瀏覽器顯示的 ASCII 形式可能與 Punycode Converter 的結果略有不同。此工具僅公開原始的標籤轉換;若您的域名註冊商拒絕該輸出,請遵循該 registry 的 IDN 政策,而不是手動編輯字元。標籤長度限制與 registry 政策在轉換後仍然適用 — 語法上編碼完成的標籤可能過長、被保留、被封鎖,或根本不可用。

安全性必須另外處理。Punycode 並非語言翻譯器 — 將標籤解碼回 Unicode 只能告訴您拼法,但無法告訴您該如何發音,或是哪個組織擁有該網域。不同書寫系統的字元可能看起來幾乎完全相同,這正是同形異義攻擊的手法:аррӏе.com (使用斯拉夫字母)在匆忙的讀者眼中可能與 apple.com 難以區辨。請將轉換後的名稱交由符合標準的 URL 程式庫處理、查詢 WHOIS 紀錄,並在將結果視為可信之前,確認其書寫系統與擁有者。編碼步驟是可逆且精確的;可信度則是另一個問題,編碼步驟無法回答。請將安全性過濾與 registry 驗證與這個可逆編碼步驟分開處理。