コンピューターはファイルの種類をどうやって見分ける?マジックバイトを徹底解説
なぜファイル拡張子は話半分でしかないのか
ほとんどの人は、ファイルが.jpgで終わっているからコンピューターはそれをJPEGだと認識する、と思っています。これはもっともな思い込みですが、半分くらいは間違っています。ファイル拡張子は単なる命名規則にすぎません。OSに対するヒントであって、中身を保証するものではないのです。PNGファイルを.txtにリネームすれば、Windowsは喜んでメモ帳で開こうとし、画面には意味不明の文字列が表示されるでしょう。Word文書を.pdfにリネームして開こうとすれば、Adobe Acrobatはきっぱりと拒否します。 このことは、ファイル変換において非常に重要です。CocoConvertのようなサービスにファイルをアップロードするとき、システムは拡張子をただ信用するわけにはいきません。誰かが悪意のある実行ファイル(.exe)を.jpgにリネームして、単純なファイルハンドラをすり抜けさせようとするかもしれません。あるいは、もっとよくあることとして、ユーザーが誤って間違った拡張子でファイルを保存してしまうこともあります。破損したダウンロードで拡張子のメタデータが完全に失われてしまった、なんてことも誰もが経験したことがあるでしょう。 何十年も前に確立された解決策は、ファイル名を無視して、ファイルの実際のバイナリコンテンツを読むことです。具体的には、プログラムは最初の数バイトを読み込み、既知の署名のデータベースと照合します。この署名はマジックバイト、より正式にはファイル署名と呼ばれます。これこそが、ファイル名に関係なく、ファイルの内容に関する絶対的な真実なのです。
マジックバイトの正体とは
標準化されたすべてのファイルフォーマットは、最初の数バイトを固有の識別子のために予約しています。これらのバイトは16進数で書かれ、フォーマットの仕様自体に組み込まれています。OSが後から追加するものではありません。 これらは16進エディタを使えば自分でも確認できます。いくつかの一般的なファイルタイプを見てみましょう: - **JPEG画像**は常に `FF D8 FF` で始まります。最初の2バイト(FF D8)がデータストリームの開始を示し、3バイト目(FF)が最初のマーカーセグメントの始まりです。 - **PNG画像**は8バイトの署名 `89 50 4E 47 0D 0A 1A 0A` で始まります。`50 4E 47` の部分はASCIIで「PNG」となっていることに注目してください。 - **PDFファイル**は `25 50 44 46` で始まりますが、これはASCIIで「%PDF」です。どんなPDFでもプレーンテキストエディタで開けば、一番上にこれが見えます。 - **ZIPアーカイブ**は `50 4B 03 04` で始まります。これはASCIIで「PK」となり、フォーマットの作成者であるPhil Katzの頭文字です。DOCX、XLSX、PPTX、JARファイルはすべてZIPベースなので、この署名を共有しています。 - **MP3オーディオ**ファイルは、MPEGの同期ワードである `FF FB` や `FF F3` で始まることが多いです。 - **EXEファイル**はWindowsでは `4D 5A` で始まります。これはASCIIで「MZ」となり、MS-DOSの最初の設計者の一人であるMark Zbikowskiの頭文字です。 「マジックバイト」という名前は、Unixの `file` ユーティリティに由来します。このユーティリティは1970年代から `/etc/magic`(モダンなシステムでは `/usr/share/misc/magic`)というデータベースを使用してきました。ターミナルで `file photo.jpg` を実行すると、このユーティリティはファイルの先頭バイトを読み込み、データベースと照合して、.jpgという拡張子を完全に無視して本当のファイルタイプを教えてくれます。
検出ソフトウェアは署名をどう読み取るのか
原理上、マジックバイトの読み取りは単純です。しかし実際には、エッジケースに悩まされることになります。基本的なプロセスは、ファイルを生のバイナリストリームとして開き、小さなバッファ(多くの場合、最初の512バイト)を読み込み、そのバッファを既知の署名のリストと比較するというものです。しかし、フォーマットによってはもっと先まで読み込む必要があります。 比較は常に単純な前方一致ではありません。フォーマットによっては、署名を固定オフセットに配置するものもあります。例えば、ISOディスクイメージフォーマットは、その「CD001」署名が32,769バイト目から始まります。ZIPファイルは中央ディレクトリがファイルの末尾にあることがあるため、検出器によっては先頭からではなく末尾からスキャンを強制されることもあります。 Apache Tika (Java)、python-magic (Python)、libmagic (C) のようなモダンなライブラリがこの複雑さを処理してくれます。Apache Tikaだけで1,300以上のファイルタイプを認識し、MIMEタイプや文字エンコーディング、さらには埋め込まれたメタデータまで検出します。CocoConvertでは、サーバーサイドの署名検出を第一の防御線として使用しています。ブラウザが申告するMIMEタイプとバイナリ署名が示すものが一致しない場合、そのファイルは変換を開始する前により詳細な調査のためにフラグが立てられます。 コンテナフォーマットは事態をさらに厄介にします。DOCXファイルとJARファイルはどちらもZIPアーカイブであるため、両方とも `50 4B 03 04` で始まります。これらを区別するためには、ソフトウェアはアーカイブのより深い部分を調べて、DOCXなら `[Content_Types].xml`、JARなら `META-INF/MANIFEST.MF` といった特定のファイルを探す必要があります。この2パス検出は、本格的なファイル処理パイプラインでは標準的な手法です。
マジックバイトが役に立たないとき(そしてそれは実際に起こる)
マジックバイトは信頼できますが、万能ではありません。いくつかの現実世界のシナリオでは、署名ベースの検出がうまくいかず、間違った、あるいは曖昧な答えを返すことがあります。 **切り捨てられたファイル**は常に頭痛の種です。ダウンロードが中断されると、有効なJPEGヘッダーを持つものの、実際の画像データがないファイルが出来上がることがあります。署名チェックはパスしますが、後でデコーダが完全な画像を期待したときに断片しか見つけられず、変換は失敗します。 **意図的に細工されたファイル**は、マジックバイトがヘッダーしかカバーしないという事実を悪用する可能性があります。ファイルが有効なPNGヘッダーの後に悪意のあるペイロードを持つことができます。これはポリグロットファイルと呼ばれる既知の攻撃ベクトルです。つまり、1つのバイナリが同時に2つの異なるファイルタイプとして有効である状態です。研究者たちは、ブラウザではスクリプトとして実行され、画像ビューアでは写真として表示されるJPEG/JavaScriptポリグロットを作成しています。署名検出だけではこれらを捕らえることはできません。 **フォーマットのバージョン競合**は、別の曖昧さを生み出します。2007年以前、Microsoft Officeファイル(DOC、XLS、PPT)は、`D0 CF 11 E0 A1 B1 1A E1` で始まる複合ドキュメントバイナリフォーマットを使用していました。これら3つのフォーマットは全く同じ署名を共有しています。マジックバイトを使っても.docと.xlsと.pptを区別することはできず、内部構造を解析する必要があります。 CSV、JSON、XML、HTML、Markdownのような**プレーンテキストフォーマット**には、マジックバイトが全くありません。これらは単なる文字の羅列です。ここでの検出は、山括弧(HTML/XML)や波括弧(JSON)のようなパターンを探すヒューリスティック分析に依存します。このヒューリスティックは間違っている可能性があります。カンマの代わりにセミコロンを使った「CSV」と格闘したことのある人なら、この痛みはよくわかるでしょう。 もしCocoConvertがファイルタイプを確信をもって識別できない場合は、その旨を伝えます。私たちは、推測して破損したファイルを生成するよりも、明確なエラーを返す方がずっと有用だと考えています。
ファイル変換における実践的な意味
では、これがどう役に立つのでしょうか?これを知っていると、変換失敗時のトラブルシューティング方法が全く変わります。サービスが「サポートされていない、または認識できないファイル形式です」と報告してきたとき、問題はほとんどの場合、ファイル拡張子ではありません。中身なのです。 最も一般的な原因と対処法は次のとおりです: **ファイルが思っていたものと違うフォーマットである。**これはデザインツールからのエクスポートでよく起こります。例えばFigmaは、.jpgというラベルのファイルをエクスポートすることがありますが、実際にはPNGだったりします。最善策は、ファイルを16進エディタ(WindowsならHxD、macOSならHex Fiendなど)で開き、最初の数バイトを確認することです。`89 50 4E 47` が見えれば、名前に関係なくそれはPNGです。リネームして再試行してください。 **ファイルがパスワードで保護されているか、DRMでロックされている。**暗号化されたOffice文書は依然として `D0 CF 11 E0` で始まるため、署名チェックはパスします。しかし、内部のコンテンツは暗号文です。CocoConvertはパスワードで保護されたファイルを復号できません。これをサービスの制限と勘違いしないでください。これは暗号化自体の基本的なセキュリティ機能なのです。 **コンテナの中身が間違っている。**汎用の.zipを.docxにリネームして作成したファイルは、正しい署名(`50 4B`)を持っていますが、内部に必要なWord処理用のXML構造がないため、変換に失敗します。コンバータはアーカイブを開きますが、処理できるものが見つからずに諦めてしまいます。 **動画ファイル内のコーデックの不一致。**MKVコンテナ(`1A 45 DF A3` で始まる)は、H.264、H.265、AV1、VP9など、数十種類のコーデックでエンコードされたビデオを保持できます。マジックバイトはMKVコンテナを確認しますが、ビデオストリームのコーデックまでは確認しません。CocoConvertがMKVをサポートしていても、ファイルがRealVideo 4のような珍しいコーデックを使用している場合、初期検出はパスしますが、トランスコーディングのステップで失敗します。
専門ソフトなしでファイルの本当の種類を確認する方法
ファイルの本当の正体を確かめるのに、専門のソフトウェアをインストールする必要はありません。これから紹介する方法は、どの主要なOSでも、すでに持っているツールを使って実行できます。 **Windowsの場合:** PowerShellを開き、`Format-Hex -Path 'C:\path\to\yourfile.ext' | Select-Object -First 3` を実行します。このコマンドは最初の48バイトを16進数で表示します。最初の行のバイト列を、この記事の前半でリストした署名と比較してみてください。 **macOSとLinuxの場合:** ターミナルを開き、`xxd yourfile | head -3` を実行します。これにより、バイトオフセット、16進値、ASCII表現が表示されます。さらに良いのは、単に `file yourfile` を実行することです。`file` ユーティリティは標準で組み込まれており、すぐにきれいで人間が読める答えを返してくれます。 **ブラウザで、ツールなしの場合:** コマンドを実行できないロックダウンされたマシンを使用している場合は、CocoConvertの検出ページ cocoConvert.com/detect にアクセスしてください。ファイルをアップロードすると、当社のサービスが検出されたMIMEタイプ、一致した署名バイト、そしてその信頼度を報告します。 **Pythonの場合(開発者向け):** `pip install python-magic` の後、`import magic; print(magic.from_file('yourfile', mime=True))` を実行できます。これにより `image/jpeg` のような標準的なMIMEタイプが得られます。しかし、本番環境のPythonコードには、代わりに `filetype` ライブラリを使用することをお勧めします。システムへの依存関係がないため、WindowsでlibmagicのDLLと格闘することなく、はるかに簡単にデプロイできます。 アップロードする前に本当のMIMEタイプを知っておくことで、多くの時間を節約できます。ファイルの検出されたタイプがサービスのサポート入力リストにない場合、変換が失敗することはすぐにわかります。
どんな変換サービスにも約束できることの限界
マジックバイトによる検出は、日常的に使用される99%をカバーする約200のファイルフォーマットについては、解決済みの問題です。しかし、専門的、プロプライエタリ、あるいはレガシーなフォーマットのロングテールについては、CocoConvertを含め、どのサービスも完全なカバレッジを約束することはできません。 CAD図面用のAutodesk DWG、特定のスキャナブランド独自の医療画像バリアント、あるいはビンテージシンセサイザーのニッチなオーディオフォーマットなどは、オープンなドキュメントが乏しいか、全くないことがよくあります。たとえマジックバイトが知られていても、内部構造はブラックボックスかもしれません。コンバータは、データが欠落したり、色が不正確だったり、メタデータレイヤーがドロップされたりした出力を生成する可能性があります。 この記事の執筆時点で、CocoConvertは約300の入力フォーマットをサポートしています。これは多く聞こえるかもしれませんが、米国議会図書館のPRONOMレジストリには2,000を超える異なるファイルフォーマットが記録されています。その差は、エンジニアリングの労力を正当化するにはあまりにもマイナーであったり、法的に特許で保護されていたり、ドキュメントが不十分で変換の試みがギャンブルになってしまったりするフォーマットを表しています。 私からのおすすめはこうです。もしあなたが医療画像、地理空間データ、プロフェッショナルビデオなどの業界で働いているなら、変換ワークフローを本格的に導入する前に、フォーマットのサポート状況を確認しなければなりません。CocoConvertのフォーマットサポートページを確認してください。そこには、サポートされているすべての入出力と、既知の制限に関する注記がリストされています。4GBの放送マスターファイルをアップロードしてから、その特定のMXFフレーバーがサポートされていないことに気づくよりも、最初に確認する方が良いでしょう。 マジックバイトは、コンピューターにファイルが*何であるか*を伝えます。しかし、そのファイルを変換して*役立つもの*が生成されるかどうかは教えてくれません。その二番目の、より重要な問いは、優れたドキュメント、明確なライセンス、そして専門的なエンジニアリング作業にかかっており、それはどんなに巧妙なバイトスニッフィングでも置き換えることはできないのです。