ByteScope

EPUB ファイル形式

EPUB 電子書籍 — XHTML のコンテンツとマニフェストを収めた ZIP アーカイブ。

MIME タイプ
application/epub+zip
拡張子
.epub
カテゴリ
ドキュメント

マジックナンバー(ファイル署名)

0x00000000504B0304PK··'PK' — it is a ZIP

ZIP 内に、内容が 'application/epub+zip' である 'mimetype' エントリがあります。

EPUB 形式について

EPUB はオープンな電子書籍標準で、構造としては ZIP に入ったウェブサイトです。画面に合わせて流れ直す XHTML 文書、CSS、フォント、画像に加えて、全リソースと読む順序を列挙するパッケージ文書が入っています。ZIP ベースの他の形式と違い、EPUB のコンテナ仕様はアーカイブ先頭のバイト列をきっちり固定しています。だからディレクトリ一覧を見なくてもヘッダだけで種類を判定できる、数少ないコンテナ形式です。これは意図的な設計で、サーバーや判定器が何も展開せずに種類を認識できるようにするためでした。

ヘッダーの構造(バイト単位)

オフセット長さフィールド意味
04Local file header signature50 4B 03 04。EPUB は普通の ZIP アーカイブで、以下はすべて最初のエントリの ZIP ローカルファイルヘッダです。ただし OCF 仕様は、ZIP 自身よりはるかに厳しくその中身を縛っています。
42Version needed to extract0A 00(10)。最初のエントリは deflate ではなく無圧縮でなければならず、無圧縮のエントリはバージョン 1.0 で足りるからです。ここが 14 00 なら書き手が mimetype エントリを圧縮したということで、その時点でパッケージは仕様違反です。
62General purpose bit flag00 00。mimetype エントリは data descriptor を使えないので、ビット 3 は落ちており、下の CRC とサイズはゼロではなく実際の値になります。ヘッダ全体が決定的になるのはこのおかげです。
82Compression method00 00 — 無圧縮での格納。仕様がこれを要求しているのは、メディアタイプの文字列が deflate ストリームの中ではなく、ファイルの固定位置に読める ASCII として現れるようにするためです。
102Last modified timeMS-DOS のパック形式の時刻。ヘッダの中で仕様が自由にしている唯一の箇所なので、周りが全部固定なのにここだけファイルごとに変わります。
122Last modified dateMS-DOS のパック形式の日付で、年は 1980 年起点。これも OCF は縛っておらず、同じくらい何も教えてくれません。本の実際の日付はパッケージ文書のメタデータにあります。
144CRC-32仕様に準拠した EPUB ならどれも 6F 61 AB 2C、つまりリトルエンディアンの 0x2CAB616F です。エントリの中身が固定なので、チェックサムも定数になります。ここが違う値なら、mimetype ファイルが期待どおりの 20 バイトちょうどではないということです。
184Compressed size14 00 00 00(20 バイト)。エントリが無圧縮なので非圧縮サイズと同じ値になります。
224Uncompressed size14 00 00 00(20)。末尾の改行なしの文字列 application/epub+zip のバイト長です。余計な改行が 1 つ入っているだけで検証に落ちますが、テキストエディタでは見えない理由なので厄介です。
262File name length08 00(8 バイト)、名前 'mimetype' の長さです。仕様がこの小文字 ASCII の名前をそのまま要求しているので固定です。
282Extra field length00 00。仕様はこのエントリに extra field を置くことを禁じています。メディアタイプの文字列が確実にオフセット 38 に来て、それより後ろにずれないのはこのためです。
308Entry nameASCII バイトで 'mimetype'。アーカイブ内の最初のエントリでなければならず、これより前に他のファイルを置くことはできません。
3820Media type stringリテラルな ASCII で application/epub+zip。ここにこの文字列があるためには独立した条件が 6 つ成立している必要があります(無圧縮、extra field なし、data descriptor なし、この名前ちょうど、この長さちょうど、アーカイブの先頭)。合わせて考えると、オフセット 38 の 20 バイトはオフセット 0 の 'PK' よりはるかに強い識別子です。
variablevariableMETA-INF/container.xml2 つ目の必須エントリですが、固定オフセットにはありません。読み手が事前に位置ではなく名前を知っている唯一のファイルであり、存在意義はパッケージ文書(多くは OEBPS/content.opf)を指すことだけです。そのパッケージ文書がマニフェストと spine、つまり読む順序を列挙します。
-224End of central directory signature50 4B 05 06。アーカイブコメントが無ければ末尾から 22 バイトの位置です。先頭が固定されていても EPUB はやはり ZIP で、リソースの列挙は末尾のセントラルディレクトリから行われます。だから最初の 58 バイトが完璧でも、途中で切れたファイルは開きません。

似た形式との見分け方

紛らわしい形式見分け方
ZIPEPUB はどれも ZIP ですが、EPUB である ZIP はほとんどありません。OCF が最初のエントリを丸ごと固定しているぶん、判定はかなり強力です。オフセット 8 が方式 0、26 が名前長 8、28 が extra 長 0、30 が 'mimetype'、38 が application/epub+zip、そして 14 が定数 CRC 0x2CAB616F。汎用アーカイブがこの 6 つを偶然すべて満たすことはありません。
Word 文書(docx)どちらもマークアップを詰めた ZIP パッケージで、'PK' で止まる素朴な検出器はどちらも取り違えます。OOXML はバイトレベルで何も固定せず、パッケージのルート(通常はオフセット 30)に現れる [Content_Types].xml で判別します。EPUB は最初のエントリを丸ごと固定します。オフセット 30 が 'mimetype' なら EPUB、'[Content_Types].xml' なら OOXML です。
MOBI/AZWAmazon の古い電子書籍形式で、そもそも ZIP ではありません。PalmDOC 由来のコンテナで、オフセット 60 に ASCII 文字列 'BOOKMOBI' があります。KF8/AZW3 は同じコンテナを包み直したものです。Kindle 端末はこれらを読み、わりと最近まで EPUB をまったく読まなかったので、同じ本が両方の形式で配られてきました。
PDF電子書籍を届ける 2 つの形式で、設計思想は正反対です。PDF は固定されたページ上の座標にグリフを釘付けにし、EPUB は画面と読者が選んだ文字サイズに合わせて流れ直す XHTML です。だからこそ PDF は「どこでも同じ見た目でなければならない文書」に正しく、スマホでは間違っていて、EPUB はその逆になります。

よくある壊れ方

  • mimetype エントリが圧縮された、あるいは位置が移った。EPUB を壊す一番よくある方法は、普通の zip コマンドで作り直すことです。全エントリが deflate され、順序が変わることもあります。ZIP としては完全に正当なのにリーダーは拒否します。メディアタイプの文字列がオフセット 38 の生の ASCII ではなくなったからです。正しく作るには、まず mimetype を無圧縮で追加し、それから残りを入れます。
  • アーカイブの末尾が欠けている。最初の 58 バイトは見事にファイルの正体を示すのに本が開かないのは、リーダーが末尾のセントラルディレクトリからリソースを列挙するからです。50 4B 03 04 を前方に拾ってディレクトリを組み直せば、XHTML は完全に取り戻せます。
  • META-INF/container.xml が無い、または存在しないパッケージ文書を指している。章も画像もスタイルシートもアーカイブ内に無傷で残っているのに、リーダーには入口がなく、本は空に見えます。これはデータの破損ではなくポインタの断裂であり、手で直せます。
  • マニフェストとアーカイブの中身が食い違っている。すべてのリソースはパッケージ文書に宣言されている必要があります。ZIP には入っているのにマニフェストに無い章は単に一切現れませんし、逆に実体の無いマニフェストエントリがあると厳格なリーダーは本ごと拒否します。どちらも ZIP ツールでは破損として現れません。
  • テキストモード転送。改行変換は固定ヘッダのフィールドを全部読める状態に残し(mimetype は無圧縮なので文字どおり生き残ります)、その裏で各章の deflate ストリームを静かに壊します。ファイルは正しく識別され、本も開き、そして途中で CRC 不一致に落ちます。

この形式の現在地

EPUB は Amazon の生態系の中を除けば、どこでも電子書籍の標準です。図書館が貸し出すのも、出版社が納品するのも、Apple Books も Kobo も Google Play ブックスもオープンソースのリーダーも読むのもこれで、2022 年からは Kindle も個人文書として受け付けます。バージョン 3 で、元々その上に建てられていたウェブにぐっと近づきました。HTML5、CSS3、フォント埋め込み、MathML、読み上げ同期のメディアオーバーレイ、インタラクティブな教科書を作れる程度のスクリプト。この形式を決定づけている性質はリフローです。テキストがどんな画面サイズにも、読者が選んだどんな文字サイズにも合わせて流れ直す。スマホで小説を読むのに必要なのはまさにそれであり、PDF にできないのもまさにそれです。同じ性質のせいで、レイアウト自体が意味を持つものには向きません。図版の位置が厳密な技術書、楽譜、漫画、印刷入稿用のものは今も PDF で配られますし、EPUB の固定レイアウトプロファイルは強みというより回避策です。EPUB を単なる ZIP として扱う前に 1 つだけ知っておくべきは、普通の zip コマンドで再パックすると壊れるということ。最初のエントリの格納方式は実装の都合ではなく仕様の一部だからです。

EPUB ファイルをこのサイトで開く

どれもブラウザ内で動きます。ファイルが端末から出ることはありません。

関連する形式

EPUB と混同しやすい形式です。先頭バイトを見比べてください。

形式先頭バイト拡張子
ZIP50 4B 03 04.zip
Word 文書(docx)50 4B 03 04.docx
HTML固定の署名なし.html

よくある質問

ファイルのマジックナンバーとは何ですか?

ファイル先頭の数バイトで、名前が何であろうとその形式を示すものです。PNG は必ず 89 50 4E 47 で始まり、ZIP は 50 4B 03 04 で始まります。OS もブラウザも file コマンドも、拡張子を信用せずこのバイト列を読みます。だからファイル名を変えても中身の正体は変わりません。

マジックナンバーを自分で確認する方法は?

macOS や Linux なら xxd -l 16 ファイル名 で先頭 16 バイトが表示されます。Windows なら PowerShell で Format-Hex -Path ファイル名 -Count 16 です。あるいはこのサイトのファイル形式判別ツールにドロップすれば、ローカルでバイト列を読んで形式を教えてくれます。アップロードはありません。

2 つの形式が同じマジックナンバーを持つのはなぜ?

一方が他方の上に作られているからです。docx、xlsx、pptx、apk、jar、epub はすべて中身が ZIP アーカイブなので ZIP の署名で始まり、区別するには内部のエントリを見る必要があります。Java の class ファイルと macOS のユニバーサルバイナリはどちらも CA FE BA BE で始まり、直後のフィールドで見分けます。

マジックナンバーがまったくないファイルもある?

あります。XML、HTML、JSON、SVG、CSV といったテキストベースの形式には固定のバイト署名がないため、構造から判別します。先頭の <?xml 宣言、<svg 要素、あるいは { に続く引用符付きのキーなどです。これは確定ではなく推測なので、このリファレンスではそうした形式をプローブ判別として示しています。

マジックナンバーが一致すればそのファイルは安全?

いいえ。わかるのは形式であって、中身が無害かどうかではありません。正規の PDF や docx でも悪意のあるペイロードを含んでいることがあります。特に拡張子とバイト列が食い違うときに真の形式を知るのは有用な第一段階ですが、マルウェアスキャンではありません。

EPUB かもしれないファイルをお持ちですか?ファイル形式判別ツールで調べる — マジックナンバーをローカルで読み取ります。アップロードは一切ありません。またはすべての形式を見る。