JSのMD5をJSXに移植してみました。いくつかハマった点があるのでメモとしてアドベントカレンダーに残します。
Original JavaScript
MD5のC実装をJSに移植したものですが、オリジナルとかなりちがっていてちょっとこれを選んだのは失敗だったかなあと思います。定数なども、もともとuint32な16進数で書かれていたものをint32な10進法として書いているので、JSの数値事情はあるにせよちょっとオリジナルとの対比を面倒にしています。が、ともかくこれを移植しました。
JSX
結果出来上がったのはこちら。hmacに関する部分は除いています。また、utf8 encode/decodeはmizukiにもともとあるユーティリティを使いました。
ハマりどころ
UTF8 encode/decode
これはJSX特有の事情ではないのですが、そもそも MD5 digest はバイト列に対する処理です。そしてJS/JSXの文字列はバイト列ではありません。よって文字列をバイト列に変換する処理が必要です。それが StringUtil.encode_utf8()
で、もともと用意してたので今回はこれを呼び出すだけですみました。ただしメソッド名を見ての通りencode処理はutf8として決め打ちなので、サーバーサイドとの照合の際は注意が必要です。
JSの文字列はバイト列ではない ということははまりがちですし、JSXを使ってもそれはなんとかしてくれたりはしないということですね。
空の配列要素
JSの場合、空の配列要素を初期化せずビット演算(整数演算)にまぜても大丈夫だったりしますが、JSXはこれを許しません。
var a = []
a[0] |= 1; // JSだとOK, JSXだと実行時例外
そこで移植の際には以下のように二項条件演算子を使ってしのぎました。
var a = [];
f(a[i] ?: 0);
ハマったところはこのくらいでした。逆に言えば、それ以外のところではほぼハマることはなく、ほぼコピペして関数シグネチャを整えるだけで済みました。使った時間は1時間くらいです。
今回簡単に移植できたのは、MD5がもともとC由来のライブラリだったからというのも大きいと思いますが、動的型付けやメタプログラミングに依存したコードでなければ移植はそれほど難しくないでしょう。