Twitter の JSON に罪はない

  • 投稿日:
  • by
  • カテゴリ:

TwitterのステータスIDが53bitを越えたお話 - tmytのらくがき
http://d.hatena.ne.jp/tmyt/20101201/1291166929

から引用。

このうちXMLで処理してる場合は内部で64bit INTで処理していれば特に問題は起きません。

こういう微妙なまちがいをしてる人はこの記事書いた人だけでなく大勢いるようだけど、記事としてはまとまっていたので参照。

JSON という書式は、確かに JavaScript から派生したサブセットですので、

JSONを仕様書通りにパースするとidの値はdouble

と考えてしまうのも無理はない気はします。
が、まちがいであるのも確かです。

RFC 4627 - The application/json Media Type for JavaScript Object Notation (JSON)
http://tools.ietf.org/html/rfc4627

たぶん引用部分の「仕様書」が指してる RFC の文書を読めばわかるとおり、JSON では数値に double 型を使う、などとは書かれていません。単に「10 進数で小数点を含んでもいいし指数表現も OK」とだけ規定されているだけです。

JSON
http://json.org/json-ja.html

こっちは日本語ですね

なので、JSON で 53bit を越える整数値を表現することは全然可能なわけです。

じゃあ XML ならどうなんだというと、この例 を見てもわかるとおり、以前から存在する id タグに 53bit 以上が必要になったツイート ID が普通に入ってます。
XML でも同様に、表現できる数値の範囲に制限はありません。仕様上は 1024bit 整数値でも表せます。

だったら JavaScript でもブラウザ上ならパースできるから XML に切り替えればいいのね、なんていうのはもちろん間違いです。

今回の原因は「JavaScript やその派生の ActionScript では 53bit を越える整数が扱えない」に尽きます。詳しい説明は、最初に引用した記事にあるとおりです。

JavaScript の仕様として「数値はすべて 64bit 浮動小数点型」と決まっているので、53bit 以上の大きい整数は扱えません。
JSON だろうが XML だろうが JavaScript を使っている限り同じ症状が出ます。

Snowflake: An update and some very important information - Twitter Development Talk | Google グループ
http://groups.google.com/group/twitter-development-talk/msg/c30b408a6c09e3d1

Twitter のエンジニアも「JavaScript のようないくつかの言語では 53bit を越える整数を扱えないので注意して」と言ってますし、回避策も「数値でなく文字列値も並列するのでそっち使って」とあります。
JSON に原因があって XML なら問題なし、というのなら、JavaScript とかは XML に切り替えるって回避策も有効なはずですが、それはありません。あくまで言語の仕様が原因ですよということです。

そもそも JSON で 53bit 以上の整数が扱えないのなら、最初からそんな「ルール違反」な JSON 文字列を Twitter が採用できるわけがないはず。

「XML ならだいじょうぶ」という根拠はどこにもないのに、どうしてこういう考え方が出てくるのか...。

ほかの言語で書かれた JSON デコーダーの場合はその実装次第ですが、JSON はあくまで「ただの文字列」とほかのデータ型とを相互変換するための約束事としてまとめられた書式ですので、たいていは「ただの文字列」として取り出せたり、数値や配列といったほかの形式と見なして取り出せるように作られてます。

JSON in Java
http://www.json.org/java/index.html

たとえば Java で書かれたこの JSON パーサーでは、与えたキーから取り出す値のデータ型はプログラムで指定するようになっているので、今回 Twitter の仕様変更で追加されたキー id_str の値を long 型で取り出すこともできます。
内部的にはすべての値を「ただの文字列」としてパースして取り出すときに指定された型に変換してるだけで、利用目的が決まっていないライブラリとしては正しい方針だと思います。

JavaScript ベースだから数値は全部 64bit 浮動小数点型でパースしようなんてのは JSON の仕様を理解してる人からは出ない発想でしょうし、ほかの言語なら数値の内部表現にもいろんなタイプがありますからそれらを有効利用できるような実装にするのが自然だと思います。

今回の問題は、あくまで「言語仕様による整数の内部表現の制約」が原因なので、XML なら解決するといった見方はできないと思います。

JSON に罪はありません。