要約

  • Bootstringは基本ASCIIコードポイントを元の順でそのまま写し、非基本ポイントをコード値の距離と成長中の出力への挿入位置を兼ねたdeltaで表した。
  • 自己終端する可変長整数と適応biasは表現を一意かつ可逆にしたが、翻訳、正規化、IDNA妥当性、登録、identityを証明しなかった。

Punycodeの末尾は読みにくい。だがRFC 3492の目的は、符号化後の文字列を人に読ませることではなかった。decoderは、すでにASCIIで運べる部分を先に置き、残りを正確な隙間へ挿入して元の列を再建する。扱うのは意味ではなく整数である。

最初に基本コードポイントを分離する。入力に現れた基本ポイントは相対順序を保って先頭へ複写され、一つでもあればdelimiterが続く。Punycodeでは基本集合がASCII、delimiterがhyphen-minusである。literal部分は翻訳ではなく、変換を必要としない入力の写しだ。

後ろのtailが欠けた構造を運ぶ。decoderは候補コード値nと挿入可能位置iを持つ。状態は出力中の全ての隙間を単調に進み、末尾を越すとiがゼロへ戻ってnが増える。deltaは、次に現在のnを現在のiへ挿入するまで、非挿入状態を何回進むかを示す。

一つの非負整数が、コードポイント空間での距離と列内位置を同時に持つ。encoderは非基本ポイントを数値順に処理するため、連続する距離は小さくなりやすい。そしてdecoderが元の出現順を回復するdeltaを導く。明示的な位置表は要らない。

複数deltaを連結するには整数境界が必要だ。Bootstringのgeneralized variable-length integerは各digitにthresholdを置き、threshold未満の唯一のdigitで終わる。little-endianなので先頭から順に切り分けられ、固定されたthreshold群の下では各非負値に一つの表現しかない。

thresholdは挿入ごとに更新される。直前deltaと処理済みポイント数からbiasを変え、最初の大きな跳躍には強いdampingを掛ける。現在のdeltaを次の大きさの手掛かりにするが、これは言語予測ではない。近い数量級を短く表す局所的な算術予測である。

Punycodeはbase 36、文字を0から25、数字を26から35、初期nを128、初期biasを72と定めた。制約を満たすparameterは効率を変えても正しさを変えない。overflow検出も必須であり、IDNA label向けの有限な上限説明を一般実装の無検査理由にはできない。

一意性には安全上の理由があった。同じUnicode列に複数ASCII表現があれば、別々のDNS authorityがそれぞれを支配し得る。Punycodeはその分岐を防ぐ。しかし異なるUnicode列が、人間や言語、normalizationの規則で同じtextと判断される問題は残る。符号化は入力された列だけを扱う。

RFC 3490はPunycodeをIDNAに組み込み、IDNA2008は周囲の準備と妥当性規則を替えながらPunycode A-labelを残した。Heng Luの最小初期仕様にならえば、狭い可逆mechanismは安定させ、文字選択、mapping、登録policyは文脈のある層で進化させられる。

入力列、準備済み列、literal prefix、delta tail、再建列、許可されたA-label、登録、DNS応答、identityは別のreceiptだ。Punycodeが保証したのは列とASCII表現の対応だけであり、その狭さこそ設計の強さだった。

短く見えること自体も証拠ではない。入力、parameter、算術境界、往復結果を一緒に残して初めてcompactな表現を監査できる。tailだけでは選択理由を説明できない。

情報源