RTF ファイル形式
Rich Text Format。プラットフォームをまたげる書式付きテキスト形式。
- MIME タイプ
- application/rtf
- 拡張子
- .rtf
- カテゴリ
- ドキュメント
マジックナンバー(ファイル署名)
| 0x00000000 | 7B5C72746631 | {\rtf1 | '{\rtf1' header |
RTF 形式について
RTF は印字可能な ASCII だけでできた文書形式です。波括弧がグループを開閉し、バックスラッシュで始まる制御ワードが書式を担い、それ以外はすべてそのままのテキスト。テキストエディタで読めて diff が取れて手で直せるワープロ形式はこれだけですし、メールクライアントを経由してペーストしても壊れない形式もこれだけです。代償はサイズと再現性で、画像入りの RTF は非常に大きくなります。画像のバイトが 1 つ残らず 16 進数の文字列として書き出されるからです。
ヘッダーの構造(バイト単位)
| オフセット | 長さ | フィールド | 意味 |
|---|---|---|---|
| 0 | 1 | Opening group brace | バイト 7B、'{'。文書全体が 1 つのグループなので、この括弧に対応する閉じ括弧はファイルの最後のバイトです。グループは入れ子になり、対応が崩れることが RTF ファイルの壊れ方として断然多いパターンです。 |
| 1 | 4 | \rtf control word | 4 バイトの 5C 72 74 66。制御ワードはバックスラッシュに小文字と省略可能な数値パラメータが続く形で、これは形式そのものの名前であり、最外側のグループに入って最初に来なければなりません。 |
| 5 | 1 | Version digit | \rtf の数値パラメータで、これまでリリースされたすべての RTF で ASCII 1 文字の '1' です。仕様はこの数字を一度も上げないまま 1.9.1 に到達しているので、これは版ではなく形式を示す番号だと考えてください。 |
| 6 | variable | Character set control word | 仕様はバージョンの直後に文字セットを置くことを求めています。ほぼ確実に見かけるのは \ansi で 5 バイト。\mac、\pc、\pca は旧来の代替で、いずれも短いため以降のオフセットがずれます。 |
| 11 | variable | \ansicpg code page | 文字セットが 5 バイトの \ansi だった場合に、ちょうどこの位置に現れます。パラメータは文書のバイト列が乗っている Windows コードページで、西欧なら 1252、簡体字中国語なら 936、日本語なら 932 です。そのコードページの外にある文字は \'hh か \uNNNN? としてエスケープされます。 |
| variable | variable | \deff, \fonttbl and \colortbl | コードページの後には既定フォントのインデックス、フォントテーブルのグループ {\fonttbl ...}、たいていはカラーテーブル {\colortbl ...} が続きます。オフセットは上にあるものすべてに左右されますが、必ずグループであり必ず本文より前に来るので、先頭数百バイトを hex ダンプするとフォント名がそのまま ASCII で見えます。 |
| -1 | 1 | Closing group brace | バイト 7D、'}'。オフセット 0 で開いたグループを閉じます。書き手によっては後ろに CR LF を付けます。空白以外の最後のバイトが閉じ括弧でなければ、そのファイルは途中で切れています。しかも多くの形式と違い、足りない括弧を手で書き足すだけで直せることがよくあります。 |
似た形式との見分け方
| 紛らわしい形式 | 見分け方 |
|---|---|
| Word 文書(docx) | バイトレベルでは似ても似つかず、'{\rtf1' 対 50 4B 03 04 です。それでも、人が「.doc ではない Word のファイル」と言うときに指す 2 つがこれです。Word は両方を読み書きしますし、.docx を .rtf にリネームしても Word はバイトを見て開いてしまいます。RTF は変更履歴もコメントスレッドも埋め込みフォントも運べないので、「RTF で保存」は文書を意図的に削ぎ落とす操作でもあります。 |
| OLE2 / CFB | 本当にややこしいのはこの組み合わせです。どちらも '.doc' の正体になり得るからです。本物の Word 97 バイナリ文書は D0 CF 11 E0 で始まる Compound File Binary コンテナですが、.doc として配られているファイルの相当数は中身が RTF です。RTF ならどこでも開けて、拡張子のほうが馴染みがあったからでしょう。拡張子ではなくオフセット 0 を読んでください。'{\rtf1' なら一意に決まります。 |
| HTML | どちらも読める ASCII でできたマークアップで、書式付きテキストをコピーしたときにクリップボードが差し出すものでもあります(Windows は RTF と HTML を同時に載せます)。オフセット 0 で簡単に見分けられますが、実務上の違いは RTF に外部参照が一切ないことです。リンクされたスタイルシートも遠隔の画像もなく、すべてが埋め込み。見知らぬ相手から受け取るなら RTF のほうが安全なのはこのためです。 |
| テキスト(UTF-8 BOM) | RTF は技術的にはプレーンな ASCII テキストなので、印字可能バイトだけを見る素朴な判定器はこれをテキストと呼びますし、テキストエディタも平気で開いてマークアップを表示します。判別に使うのは先頭 6 バイトです。なお RTF は UTF-8 BOM を持てません。必ず波括弧で始まらなければならないからで、オフセット 0 に EF BB BF があるならそのファイルは壊されています。 |
よくある壊れ方
- 波括弧の対応崩れ。グループは入れ子になり、制御ワードは外側のグループから継承されるので、'}' が 1 つ欠けるとそのグループ内で設定された書式属性が文書の残り全部に漏れ出します。見た目の症状は、普通に開いて後半だけフォントが違う、あるいは全部太字になっている、しかもエラーメッセージはどこにも出ない、というものです。
- コードページの取り違え。\ansicpg が 1252 と言っているのに実際のバイトが 936 で書かれていれば、ASCII 以外の文字がすべて文字化けします。ファイルは 1 バイトも壊れておらず、文書構造も完璧に無傷です。間違っているのはオフセット 11 のたった 1 つの数値で、そこを直せば文書全体が元に戻ります。
- 途中切れ。切られた RTF もたいていのワープロでは開いてしまい、パースできたところまでを描画して、開きっぱなしのグループは勝手に閉じてくれます。この寛容さが罠で、文書は完成しているように見えて最後の数ページが黙って消えています。空白以外の最後のバイトが '}' かどうかを確認してください。
- リテラルなテキストに紛れ込んだバックスラッシュ。特殊文字はバックスラッシュ、波括弧、そしてエスケープシーケンスだけなので、リテラルの '\' や '{' をエスケープし忘れた書き手はユーザーのテキストを制御ワードに変えてしまいます。結果として、hex ダンプにははっきり見えているテキストが、描画結果からは消えます。
- 改行変換。これは珍しく無害です。RTF は制御ワードの外にある CR と LF を無視するので、PNG や ZIP を破壊するテキストモード転送を経ても RTF は綺麗に読めます。ASCII モードの FTP を本当に生き延びる、数少ないバイナリ寄りの形式の 1 つです。
この形式の現在地
RTF はフォールバック用の形式で、しかもその用途では今なお最良の選択肢です。これで文書を書きたい人はいませんが、「書式付きで、どこでも開けるものを送って」という要求に対する確実な答えであり続けています。1987 年以降に作られたワープロなら例外なく読めて、しかもプラグインが要りません。特に生き残っているのは 3 か所です。1 つは Windows と macOS のクリップボードにおける書式付きテキストの型。アプリ間でスタイル付きテキストをコピペするたび、裏では RTF を往復しています。2 つ目はベンダーに依存できない法務・行政システムのエクスポート形式。3 つ目は出所の怪しい文書を受け取るときの安全な入口で、RTF にはマクロもスクリプトも外部参照もありません。Microsoft は 2008 年のバージョン 1.9.1 で仕様の開発を止め、Word 自身の RTF コンバータも非推奨になったので、進化ではなく凍結の状態です。新しく作るなら .docx のほうが再現性ははるかに高く、サイズもごく一部で済みます。写真を数枚入れただけの RTF が数十 MB になるのは、画像を ASCII の 16 進で持つためにサイズが倍になり、そのうえ圧縮が一切ないからです。
RTF ファイルをこのサイトで開く
どれもブラウザ内で動きます。ファイルが端末から出ることはありません。
関連する形式
RTF と混同しやすい形式です。先頭バイトを見比べてください。
| 形式 | 先頭バイト | 拡張子 |
|---|---|---|
| Word 文書(docx) | 50 4B 03 04 | .docx |
| OLE2 / CFB | D0 CF 11 E0 A1 B1 | .doc |
| 25 50 44 46 2D |