Help us understand the problem. What is going on with this article?

Punycodeのjavascript実装と変換テスト

More than 5 years have passed since last update.

Punycodeのjavascript実装と変換テスト

概要

Punycode変換をjavascriptで実装した

var encoded = Punycode.encode("ぴゅにこーど");//=> "28j1be9azfq9a"
var decoded = Punycode.decode(encoded);
decoded=="ぴゅにこーど" //=> true
encoded = Punycode.encode("Punycode変換・逆変換");  //=> "Punycode-wg5gy946aba2534aca0149m"

以下を参考にした

最後、Punycodeの発案者のサイトに最新のpunycode.cのサンプルがあり大いに参考にした。 RFC3492日本語訳のcのコードには抜けがあるので注意。

実験

Punycodeをjavascriptに移植してみて以下がわかった

  • 国際化URLの為の仕様だとおもっていたがURLには使用できない文字でもエンコード可能
  • とはいえ、ASCII(0x80以下)はスルーするので文字以外には向かないかもしれない
  • ASCIIにエスケープしているがバイトサイズで比較しても元と同じかより小さくなることも
  • 処理は複雑で割り算を多用していることもあり時間がかかる
  • 国際化URLとして使うには使用禁止文字、大文字小文字の同一化、prefix(xn--)追加など工夫が必要

Punycode内部で利用しているBootstringというアルゴリズムを応用すれば 36字(A-Z0-9)以上の文字種でエンコードが可能になる

Punycodeは、Bootstringと呼ばれる、より一般的なアルゴリズムの適用事例
(instance)である。このアルゴリズムは、より大きな文字集合に属する
コードポイントの並びを、小さな"基本(basic)"コードポイントの集合に
含まれるコードポイントの並びによって一意に表現可能にするものである。
Punycodeは、Bootstringの特定のパラメーター値をIDNA向けに適切に設定した
ものである。

試しにBase64([A-Za-z0-9+/])とBase85([0-9A-Za-z!#$%&()*+-;<=>?@^_`{|}~])で作成してみた

var str = "Punycodeのjavascript実装と変換テスト";
Punycode.encode(str,Punycode.Params);        //=> "Punycodejavascript-ei4qnd68efitb5631q2rna9p4c6j0o"
Punycode.encode(str,Punycode.Base64Params);  //=> "Punycodejavascript-8s6A4Bu3AxEvA7/uVqKE/dU8izB"
Punycode.encode(str,Punycode.Base85Params);  //=> "Punycodejavascript.I2Xg1|lv3l0(%)D~a2g`Dd(j"

// ecl.js の JCT11280(JIS-UNICODE変換テーブル)でテスト
JCT11280.length;  //=> 11280 (chars)
Utils.ByteArray.fromText(JCT11280).length;  //=> 33718 (bytes)
Punycode.encode(JCT11280).length;  //=> 31455 (bytes) 93.3%
Punycode.encode(JCT11280,Punycode.Base64Params).length;  //=> 29584 (bytes) 87.7%
Punycode.encode(JCT11280,Punycode.Base85Params).length;  //=> 28565 (bytes) 84.7%

パラメータのせいもあるかもしれないが、文字種が増えても思った以上には縮小されなかった。 36種類→85種類で236%の増加だが、縮小率は93.3%→84.7%で10%程しか差がない。

考察

Bootstringの仕組みは面白く、変換後のサイズも小さいが処理が遅いのが気になる。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away