2009年04月09日 00:15 [Edit]

バイナリとテキストの本当の違い

うーむ、Wikipediaですら「見た目」の違いしか説明していない。

バイナリ - Wikipedia
コンピュータが扱うすべてのデータはバイナリデータ(バイトの並び)であり、プレーンテキスト(または単にテキスト)もバイナリデータの一種ではあるが、通常バイナリとテキストは対比して用いられる。テキストとはデータの内容すべてを人間が読んで理解できる (human-readable) 表現形式を指し、バイナリとはそうでない表現形式を指すことが多い。
Binary file - Wikipedia, the free encyclopedia
A binary file (.bin) is a computer file which may contain any type of data, encoded in binary form for computer storage and processing purposes; for example, computer document files containing formatted text. Many binary file formats contain parts that can be interpreted as text; binary files that contain only textual data - without, for example, any formatting information - are called plain text files.

バイナリーとテキストの本当の違い、それは「終わり」にある。

  • 「終わり」がはじめにわかるのが、バイナリー。
  • 「終わり」が来るまで「終わらない」のが、テキスト。

本質的な違いは、これだけである。

もう少し具体的に言うと、Pascal String はバイナリー、C String はテキストである。Pascalをご存知ない方のために補足すると、 Pascal では最初の 1 byte が文字列の長さを表していた。それに対し、CのString はよく知られているように\0が来るまで終わらない。

上の定義を、もう少し専門的に言い直すと、こうなる。

  • 仕様、メタデータ、またはヘッダーで「終わり」を先に決めておくのがバイナリー
  • 「データはここで終わり」という信号が来るまで「終わりがない」のがテキスト

バイナリーとテキストの特長と欠点は、すべてこの定義から導出できる。

バイナリーの特長は、「待つ」ことなしにデータの処理を始められることと、あらゆる「バイト」を公平に扱えること。この特長により、同じデータであればバイナリーの方がより高速に処理でき、プログラムも簡単に書けることが多い。

その代わり、データをそこから「拡張」することがすごく難しい。なにしろ「終わり」が「あらかじめ」決まっているのだ。バイナリーを「拡張」する方法は二つ。「あらかじめ隙間をあけておく」か、「以下続く」コードをあらかじめ定めておくか。後者の方法は一種の「テキスト化」とも見なせる。拡張性はないのがデフォルトで、あっても「あらかじめ開けておいた隙間を使う」に留まっている。

テキストはまさに逆。「データの終わり」が来ないとデータ処理が開始できないし、「データの終わり」というデータそのものは特別扱いしなければならない。「データの終わり」として定めた信号を「単なるデータ」として扱う場合には、「エスケープ」しなければならない。

その代わり、データはいくらでも拡張できるし、データを入れ子(nest)にするのも簡単だ。例えばJSONでは"が「文字列の終わり」(始まりでもあるが)、]が「配列の終わり」、}が「オブジェクト(ハッシュ)の終わり」だ。これらの「終わり」を「文字」として扱いたい場合には、エスケープする。

このことは、さらに重要かつ決定的な違いをもたらす。バイナリーを扱うためには、仕様が先になければならないが、テキストでは仕様は後でもかまわないのだ。HTMLがなぜこれほどの成功をおさめたかといえば、仕様が現実の後を追いかけてきたというのが最大の理由だろう。

ところで、テキストはバイナリーの連なりとしても表現でき、そして実際にそうなっている。「バイト列」というテキストは、「バイト」というバイナリーの連なりで表現されている。

ここで「バイト」(byte)を正確に定義しておこう。ここでもまたWikipediaにはちょっと裏切られた。英語版の方は少しましであるが。

バイト (情報) - Wikipedia
通常、1バイトは2進数の8桁、即ち8ビット(bit)である。この場合、連続した256(28)個の整数(符号無しで0から255、符号付きで-128から+127、など)を表すことができる。
Byte - Wikipedia, the free encyclopedia
A byte (pronounced IPA: /ba?t/) is a basic unit of measurement of information storage in computer science.

バイトの正確な定義、それは「コンピューターが一度に扱える最小の情報」である。それより小さな情報は「まとめて」扱わなければならない。「理論上最小の情報量である」1ビット(bit)が1バイトであるコンピューターも当然ありえ、実際元祖 turing machine はそうなっている。もっとも現代のコンピューターでは、1バイトはほとんど8ビットである。現代のコンピューターは、bit by bit ではなく byte by byte でしか情報を処理できない。1ビットいじる場合でも、1バイトづつ処理しなければならない。

そう。「1バイトは8ビット」という取り決めそのものが、バイトをバイナリーたらしめているのだ。

このことは、「文字」、すなわち char にも敷衍できる。まだアルファベットしかなかった頃には 1バイト = 1文字でよかったが、世界中の文字を char に収まるようにしようとするとそれでは足りない。「16bitで足りるんじゃね」と想像力の足りない人々が、Unicode 1.0を制定してしまった。

文字列はテキストでも、文字そのものはバイナリー。

だからこそ、文字というバイナリーを設計するときにはずっと慎重にならなければならなかったのだ。その余裕がなくとも、せめて「もっと隙間を開けておいて」おくべきだったのだ。

「どれだけ隙間を開けておくか」をあらかじめ予想するのは実に難しい。インターネットの開始時、32bitは「無限」に近いほど広く感じられただろう。だからこそ「今日までもった」のであるが、今ではその有限性が「今、そこにある危機」となっている。かといって、当時のコンピューターの性能でいきなり128bitはあまりに非現実的であっただろう。そして「バイト」と同じく、「パケット」はバイナリーで、これを「テキスト化」するのはかなり難しい。難しいので「テキスト化」はIPではなくTCPという「一つ上の階層」でやっている。

いずれにせよ、「バイト」や「パケット」は、今までもバイナリーだったし、これからもバイナリーであり続けるだろう。「テキストのアトム」としてのバイナリーさえきちんと抑えておけば、あとは「テキスト」でしのげる。これが Unix で得た最大の教訓の一つではないか。

404 Blog Not Found:デバッグより重要なもの
迷ったら、テキストにしておけ。
バイナリーがいいと確信してても、テキストにしておけ。
どうしてもバイナリーが欲しかったら、テキスト化する方法も一緒に作っておけ。

これこそが、最も大事な富豪プログラミングだという確信は、年々強くばかりだ。

Dan the Textual Blogger


この記事へのトラックバックURL

この記事へのトラックバック
しつこいようですが、テキストデータについてもう少し考えてみました。 テキストデータの本質は、 (イ)「文字」である事による抽象性 (ロ)「数」が割り振られている事による計算のしやすさ (ハ)広く深く浸透している「標準」 であり、それによって得られるバイナリデータ...
テキストデータの本質【ふにょい日記】at 2009年04月11日 02:40
テキストはバイナリの部分集合だから、 「終わり」がはじめにわかるのが、バイナリー。 「終わり」が来るまで「終わらない」のが、テキスト。 ≫404 Blog Not Found:バイナリとテキストの本当の違い これはウソ! 「終わり」がはじめにわかるのは、そういうお約束がある場合
[SWE]バイナリとテキストの違い?【今日の役に立たない一言 − Today’s Trifle! −】at 2009年04月10日 15:31
ああ、まただよ... バイナリとテキストの本当の違い |404 Blog Not Found テキストって、柔軟性の高いデータ形式なのに、なぜ「小飼弾」が書くとダメテキスト論ばかり登場するのか。うんざりだ。 バイナリーとテキストの本当の違い、それは「終わり」にある。 「...
「小飼弾はもうテキスト論をblogに書くな」と言わせないでくれ【katyos開発室】at 2009年04月10日 11:22
バイナリとテキストの本当の違い(404 Blog Not Found) をちょっと読んで思ったこと。 [引用] バイナリーとテキストの本当の違い、それは「終わり」にある。 * 「終わり」がはじめにわかるのが、バイナリー。 * 「終わり」が来るまで「終わらない」のが、テキスト...
それは「ストリーム」か「レコード」かという事では?【ふにょい日記】at 2009年04月10日 09:26
ref バイナリとテキストの本当の違い データとしての終端に注目しているのが面白い。 バイナリは情報を純粋に表現した形式で、その使い方はさまざま。 情報とは未知のことがらについてどれほど有益なものを得られたか、のようなものだ。 たとえば、地球は太陽の周りを回って...
バイナリには意味がなく、テキストには意味がある【32nd Diary】at 2009年04月09日 23:23
情報元: http://blog.livedoor.jp/dankogai/archives/51199467.html たぶん、異論反論オブジェクションだと思われw 誰がどう考えてもテキストデータとしか言いようがないもの、*.txtなテキストファイルを...
404 Blog Not Found:バイナリとテキストの本当の違い【VMID.NET】at 2009年04月09日 22:38
元記事:404 Blog Not Found:バイナリとテキストの本当の違いより バイナリーとテキストの本当の違い、それは「終わり」にある。「終わり」がはじめにわかるのが、バイナリー。「終わり」が来るまで「終わらない」のが、テキスト。本質的な違いは、これだけである。上の定義...
バイナリとテキストの違いを初めて実感した【Grope in the Dark...】at 2009年04月09日 12:36
この記事へのコメント
メインフレームを知らない人ならではの発想ですね。弾さんはなぜddコマンドでconv=asciiとすると可変長になり、conv=ebcdicとすると(cbsで指定したレコード長の)固定長になるのか考えたことがないんでしょうね。
Posted by 暇人 at 2009年04月11日 14:52
Atomic/Compositeの違いは確かにその通りで面白いが、テキスト/バイナリー論に結びつけるのはどう考えてもアホアホだと思うんだが。
Posted by shou at 2009年04月10日 02:16
> うーむ、Wikipediaですら「見た目」の違いしか説明していない。

せっかくなので、そのWikipediaの箇所を弾さんなりに編集してもらえませんか?

# 私ではまだバイナリとテキストの違いについての理解が浅はかなので、編集し
# したらとんでもないことになりそうなので。

Posted by しがない大学生 at 2009年04月10日 02:00
バイナリは、見れない。テキストは、見れる。
バイナリは、聞けない。音声は、聞ける。

そんなこんなで、テキストはアナログなもので、バイナリはデジタルなものだと思います。
さぁ、デジタルとアナログの違いやいかに。
Posted by r at 2009年04月10日 00:11
弾の言ってることを私流に言い換えれば、テキストにはデミリタが必要だが、バイナリの場合は「外」で決まってて必要ない、ということだと思うんですが。

だからこそ、
> 文字列はテキストでも、文字そのものはバイナリー。

ということになります。「1文字」という区切りは、弾も書いているように、例えば8bitを区切りとする、というように仕様で決められてるため、弾の定義の通り、バイナリーということになります。

なぜ「デミリタ」という言葉を使わなかったかは、デミリタ自体が存在しなくてただ単にブツ切れで「終わって」いる場合も含めたかったからでしょう。

私がこんな蛇足を書いてるのも、直前の方の書き込みが、非常に気になったからです。

printf("%d")でバイナリーになるって、二重の意味で間違ってませんか。

まず、整数と見なすべきデータは次の何ビットなのか、最初から仕様でわかってる時点でそのデータは「バイナリー」です。

一方、printf("%d")で出力されるデータは、何桁続くのかわからない、最後まで読んで(または最後がわかるように出力されて)初めて何桁で終わっているのかわかるという点で、テキストです。
Posted by 気になった男 at 2009年04月10日 00:11
終わりがあるかどうかが本質的な違いとするのはちょっと乱暴で偏った表現かとおもいます。
もちろん、仰っていることは正しい部分もありますが、そうではない部分もあります。
バイナリにも終わりがないものもあります。
たとえば、RGBデータにXYのピクセル数とRowBytesの情報を記述したヘッダーをつけて保存したファイルは終わりがありません。

前のコメントもそうですね。


テキストもバイナリも本質的な違いはありません。
それは正しいですが、テキストとバイナリの違いは、
そのデータをいわゆる文字コード表と照らし合わせて、「翻訳」したものが、意味のある(人間がわかる)データであった場合には、テキストデータ、意味のないものの場合には、バイナリデータ、それだけのことです。

もちろん、データを扱うプログラム(ソフト)によって違います。
例えば、同じデータでも
printf("%s")とやった場合は、テキストになりますが、同じデータをprintf("%d")とやった場合には、バイナリになります。

つまり、同じデータでも、そのデータを扱うプログラムによってテキストにもバイナリにもなりえます。


終わりがあるかどうかでバイナリ・テキストというのは一部の
データでは正しいと思いますが、全部にはあてはまりません。

まとめて大きなレベルで考えると、
基本的にはバイナリもテキストもなんら違いはまるっきりありません。
違いがあるのは、文字コード表と照らし合わせて翻訳して「人間にとって理解できる文字列」になるかどうかだけです。

まぁ一般的には「改行」があるかどうかですかね^^
Posted by 通りすがりのSE at 2009年04月09日 22:39
SQLのテキストデータはバイナリデータか?
ファイルシステム上のテキストファイルはバイナリファイルか?
紙テープに出力したテキストデータはどうなるんだ?

終わりになんか違いがあるわけがない。

Posted by 意味がわからん at 2009年04月09日 12:53
プレーンテキスト - Wikipedia <http://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AC%E3%83%BC%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88>もご覧いただけると幸いです。
Posted by Hirotow at 2009年04月09日 12:25
エンドマーク(適当な特定のパターン)を検出して通信することは、所謂バイナリデータでもよくありますよ。RS232Cとかでよく使います。
Posted by とおりすがらー at 2009年04月09日 09:07
 CP/M とか DOS で使われてた(使われてる)、COM 形式のファイルはどうなんでしょう。バイナリのような気がしますが、この定義だとテキストだよね。
Posted by 寿命 at 2009年04月09日 08:47
最近また技術的な話題が増えてきて,嬉しい限りです.これからも楽しみにしておりますので,よろしくお願いします.
Posted by an at 2009年04月09日 06:31
瑣末ですが、
>年々強く(なる)ばかりだ。
ですよね?
Posted by md2tak at 2009年04月09日 04:08