JavaScriptでバイナリをいじる方法を考える(決定打はない)

 ブラウザでFileAPIが実装され、Node.jsでもファイルのIOができるようになって久しい。JSで書いたライブラリでバイナリを扱っているので、その方法を数年ぶりに考察してみる。

 まずFileAPIで返ってくるDataURI。これはASCIIでバイナリを表示できるようにと考え用意されたもの。JSでの型はstring。
 ブラウザではこの形式で画像を読み込んでくれる。しかしASCII化するためにデータ量が30%以上膨れ上がり、何バイト目のデータはいくつかという値取得などの操作も難しい。バイナリを操作するのに向いていない。

 UInt8Array。まさにバイナリを操作するのに実装された型。メモリ上でのデータの扱いも合理的になっている。1バイトを符号なしのショートの整数として扱える。
 ただいまいち任意の場所のデータ比較がいけてると思えない。Pythonならこう
data[0:2] == b'\xff\xda'



 JSでは…配列同士の比較ではダメかっていうとダメ。配列の等価比較を簡単にやることができない。
"=="をArray系にやる→オブジェクトの比較になる→オブジェクトが同一かを比較される、オブジェクトの値ではなく。
 ↓のはfalse。
data.subarray(0,2) == new UInt8Array([255, 0]);



JSではいちいち切り出して、それを比較しやすいstring型に変更して、という手順をふまなきゃいけない。
String.fromCharCode.apply("", data.subarray(0, 2)) === "\xff\xda"




 それがいやならUInt8Arrayではなくstringを使っておくとか。
data.substring(0, 2) == "\xff\x00";



 ただしstringの弱点は、console.logで表示したときにUnicodeで表示されてしまうこと。そのままではデバッグが困難。
let foo = "\xff\x00";

console.log(foo); // ÿ�


 UInt8Arrayの部分比較がもっと楽だったらなー。そういうわけで個人的に決定打はなかった。
comment: 0