「バイナリ」の意味がわからない問題
中学生の頃に読んだ本で「バイナリ」という言葉を知りました。それから何十年が経ち、エンジニア歴が10年を越えても実は「バイナリファイル」「テキスト通信」といった用語をよくわからないまま使っています。そこで、改めてその意味を整理してみました。
「バイナリ」と「テキスト」の曖昧さ
そもそもコンピュータのデータはすべてバイナリ(2進数)で表現されます。つまりテキストファイルでさえ、実際は0と1のバイナリデータです。
ではなぜ、「バイナリ」と「テキスト」を区別するのでしょうか?
これは「人間が読みやすいか否か」という直感的な基準に基づいていると一般には説明されます。JSON API通信は「テキスト通信」、gRPC(Protocol Buffers)は「バイナリ通信」と呼ばれるのも、実はそうした曖昧な基準が根底にあります。
実は矛盾する?「暗号化されたJSON」はどっちなのか
ここで、面白い例を考えてみましょう。
もしJSONファイルの中身がすべて暗号化され、文字列ばかりだったとしたら、これは「テキスト」でしょうか、それとも「バイナリ」でしょうか?
{
"oY873CDz0": "U2FsdGVkX1+Iq2w=="
}
- テキストエディタでは普通に開けます。
- でも、暗号化された文字列なので、人間が読んでも全く意味は分かりません。
つまり、「人間が読みやすいかどうか」という基準は、こうしたケースでは矛盾を生んでしまいます。
エンジニアは実際にどう判断しているのか
こうした曖昧な状況の中、実際のエンジニアが無意識にどのような条件で判断しているかを整理すると、以下のような条件式が浮かび上がります。
if (ファイルがテキストエディタで正常に表示できる文字コードを持つ)
and (そのファイル形式の慣習がテキストとして扱われることを前提としている)
and (テキスト処理ツールで容易に扱える)
then:
「テキストファイル」とみなす
else:
「バイナリファイル」とみなす
ここで重要なポイントとなるのが 「ファイル形式の慣習」 です。私をずっと悩ませてきたのは、このひどく人間らしい 曖昧な慣習 なのです。
ファイル形式の慣習とは何か?
ファイル形式の慣習とは、「あるフォーマットがどのように作られ、どのように使われるのが一般的か」という社会的な合意です。例えば次のようなものがあります。
-
テキストとして設計されたフォーマット
- JSON、XML、CSV
- 人間が直接読み書きすることを前提として作られています。
-
バイナリとして設計されたフォーマット
- PNG、JPEG、EXE、MP4、ZIP、Protocol Buffers
- 専用ツールによる機械処理を前提として作られ、人間が直接扱うことを意識していません。
つまり結局のところは、この慣習によって分類が決まるのです。
TLS通信のパケットはバイナリ? テキスト?
TLS通信を考えてみましょう。TLSは通信内容を暗号化した状態で送受信します。パケットはバイト単位で処理され、構造も複雑で人間が直接読むことは想定されていないため、一般的に「バイナリ通信」として扱われます。
しかし、証明書を使って暗号化を解除すると、中に含まれている元々の通信形式が現れます。その結果、復号後は以下のような扱いになります。
復号後の中身がHTTP/1.1+JSONなどテキストベースであれば、「テキスト通信」
復号後の中身がHTTP/2やgRPCなどバイナリベースであれば、「バイナリ通信」
つまり、暗号化されているかどうか自体が分類を決めるわけではなく、最終的には元のフォーマット次第で分類が決まるわけです。ここでもまた、「フォーマット次第」「慣習次第」という曖昧さが現れることになります。
ファイル形式の慣習が変わった面白い例
しかし、「慣習」は常に一定ではなく、設計者の意図とユーザーの認識が食い違い、分類が変化したり曖昧になったりすることもあります。以下はその例です。
① Markdown (.md
) ファイル
- 設計意図:テキスト
- 実際:複雑化したことで、一部のツールでバイナリ的に扱われることがあります。
② PDFファイル
- 設計意図:バイナリ
- 実際:内部にテキストが含まれるため、初期にはテキスト的な扱いを受けることがありました。
③ JSON Lines (.jsonl
) ファイル
- 設計意図:テキスト
- 実際:gzipなどで圧縮され、実質的にバイナリとして扱われることも多いです。そもそもクソ長い1行が前提の時点で人が読むことは一切考えられていない。
④ YAMLファイル
- 設計意図:テキスト
- 実際:巨大化したYAMLはツールなしで扱うのが難しく、実質的にバイナリファイルのように専用ツールが必要なことがあります。kubernetes君のことだよ
結論:全フォーマットを覚えられるわけがない
結局のところ、「バイナリかテキストか」はファイルフォーマット次第で、設計者の意図とユーザーの使い方次第で分類が変わります。無限に存在するファイル形式の分類をすべて覚えるのは不可能です。
明確に定義できない、極めて曖昧なものなのです。
結論、「バイナリかどうか」を完璧に判別できる人間はこの世にいないというのが私の結論です。
エンジニアに求められるのは、その曖昧さを理解し、適度に割り切って使い分ける柔軟性だねという話でした。
おまけ
「バイナリ(2進数)」 を細分化して 「バイナリ(違う意味)」にするのはけっこうな悪手だと思うわけです。しかしこの世界はそんなのばっかりみたいです。
-
サーバ(Server)
- 広義のサーバ
- クライアントからの要求に対してサービスやリソースを提供するシステム全般(ソフトウェア・ハードウェア問わず)。
- 狭義のサーバ
- 特定の物理的なハードウェア(サーバマシン)
- 広義のサーバ
違和感なく両方のサーバ使ってるやんけ!
ちゃんちゃん。お後がよろしいようで