Book Code Builder は、歴史的な 書籍暗号(Book Code) を体験できる教育用ツールです。
書籍暗号は、任意のテキスト(当時は書籍だった)を鍵とし、それをコードブックと呼びます。
平文に登場する1単語を、コードブックに登場する単語の位置(「ページ数・行数・何番目」の3数字の組み合わせ)に対応させます。
本ツールでは、これを**page:line:word** の形式で表記します(文献によっては、`page-line-word'を採用している)。
例:
12:5:3は「12ページ目の5行目の3語目」を意味します。
つまり、暗号化の場合、コードブックを用いて、英文から「p:l:wの数列」に変換します。 逆に復号の場合、同じコードブックを用いて、暗号文「p:l:wの数列」から元の英文に戻します。
本ツールでは、ページ分割は「行数ベース(Lines Per Page)」で再現します。 また、インデックス統計・曖昧語の検出・未対応語のハイライト もサポートしています。
👉 https://ipusiron.github.io/book-code-builder/
ブラウザーで直接お試しいただけます。
このツールは以下のような方々を対象としています:
- 📚 暗号学を学ぶ学生 - 大学・高専・専門学校で暗号理論や情報セキュリティを学んでいる方
- 🔬 情報セキュリティ分野の研究者 - 古典暗号の実装や統計的攻撃手法を研究する方
- 🕰️ 暗号史に興味がある方 - 歴史的な暗号技術の実物を体験したい一般の方
- 👨🏫 情報科学の教育者・教員 - 暗号学の授業で古典暗号を実例で教えたい方
- 🚩 CTF参加者 - Capture The Flagで古典暗号問題に取り組む方
- 💻 セキュリティエンジニア - 暗号解析や頻度分析の基礎技術を実践的に学びたい方
- 🛠️ 暗号実装を学ぶプログラマー - 暗号システムの実装パターンを学びたい開発者
- 📊 統計的攻撃を体験したい方 - Zipfの法則やn-gram分析などを実データで確認したい方
- 🎓 独学で暗号を学ぶ方 - 書籍だけでは分かりにくい古典暗号を手を動かして理解したい方
推奨される学習レベル: 高校レベルの英語と基本的なコンピューター操作ができる方であれば、どなたでも使用できます。暗号学の事前知識は不要ですが、より深く理解するには情報理論や統計学の基礎知識があると有益です。
本ツールの具体的な活用方法を3つのシナリオで紹介します。
対象: 大学・高専の情報セキュリティ授業、専門学校のサイバーセキュリティコース
目的: 古典暗号の仕組みと脆弱性を体験的に学ぶ
実習の流れ:
-
書籍暗号の基本を学ぶ(15分)
- ヘルプタブの「📖 書籍暗号の基本」「⚙️ 仕組みと動作原理」を読む
- 歴史的背景(スパイ活動での使用例)を理解
-
実際に暗号化・復号を体験(20分)
- プリセット「Declaration of Independence(アメリカ独立宣言)」を読み込み
- サンプル文「this is a secret message」を暗号化
- 暗号文をコピーして復号タブで復号
- 学習ポイント: 同じ単語でも異なる座標になることを確認(ラウンドロビン)
-
ラウンドロビンON/OFFの比較実験(15分)
- ラウンドロビン割当をOFFにして再度暗号化
- 同じ平文が異なる暗号文になることを確認
- 課題: 「the」という単語が暗号文で何回出現するか数える
- 考察: ラウンドロビンOFFでは頻度分析攻撃に脆弱であることを理解
-
未収録語の問題を体験(10分)
- 平文に「cryptography」「encryption」など専門用語を含める
- 暗号化すると
{???}が出力されることを確認 - 学習ポイント: 語彙の制限が実運用での大きな課題であることを理解
-
ビューワーで単語分布を分析(15分)
- ビューワータブで「the」「and」「of」などの頻出語をクリック
- 全出現座標を確認し、分布の偏りを観察
- 発展課題: Zipfの法則との関連を調べる
教育効果:
- ✅ 暗号化・復号の仕組みを実体験で理解
- ✅ 頻度分析攻撃の脅威を具体的に認識
- ✅ 古典暗号の限界と現代暗号への発展を理解
対象: 情報セキュリティ分野の研究者、大学院生
目的: 書籍暗号の統計的性質を分析し、攻撃手法の有効性を検証
研究手順:
-
実験環境の準備
- 複数のコードブックを用意(Declaration of Independence、Aesop's Fables、King James Bible)
- 各コードブックでインデックスを構築し、統計情報を記録
- インデックス統計(ページ数・行数・単語数・ユニーク語数)を比較
-
頻度分析攻撃の実験
- 実験1: ラウンドロビンOFFで同じ平文を3種類のコードブックで暗号化
- ビューワーで頻出語("the", "and", "of")の座標を確認
- 仮説: 暗号文中の頻出座標が平文の頻出語に対応する
- 検証: 座標の出現頻度をカウントし、英語の単語頻度リストと比較
-
ラウンドロビンの効果測定
- 実験2: ラウンドロビンON/OFFで同じ平文(100単語以上)を暗号化
- 暗号文中の座標の重複率を計算
- OFF: 頻出語が常に同じ座標 → 高い重複率
- ON: 頻出語でも異なる座標 → 低い重複率
- データ収集: 座標の分散度合いを定量化
-
単語分布の偏り分析
- ビューワーで特定の単語(例:"wolf")をクリックし、全出現座標を記録
- 座標のページ分布をプロット(例:ページ1-5に集中)
- 研究テーマ: 座標の空間的偏りから元のコードブックの構造を推測可能か
-
n-gram分析への応用
- 平文「of the」「in a」などの頻出バイグラムを暗号化
- 暗号文で連続する座標ペアのパターンを抽出
- 研究課題: 連続座標パターンから文法構造を推測可能か
研究成果の例:
- 📊 ラウンドロビンによる頻度分析耐性の定量評価
- 📊 コードブックの語彙多様性とセキュリティの相関分析
- 📊 座標の空間的分布パターンと攻撃成功率の関係
参考文献との対応:
- Friedman (1918)『The Index of Coincidence and Its Applications in Cryptography』の一致指数を実測
- Gaines (1956)『Cryptanalysis』のn-gram分析手法を実践
対象: CTF参加者、CTF問題作成者、セキュリティコンペティション運営者
目的: 書籍暗号を題材にしたCTF問題を作成・解答する
出題例:「Lost Message(失われたメッセージ)」
問題文:
スパイが使用していたメッセージを傍受しました。
コードブックとして「The King James Bible」が使われていることが判明しています。
以下の暗号文を解読してフラグを取得してください。
暗号文:
1:2:3 5:7:2 8:1:5 12:4:1 15:6:3 ...
作成手順:
- プリセット「King James Bible」を読み込み
- フラグ文字列(例:
flag{book_codes_are_historical})を暗号化タブに入力 - ラウンドロビンONで暗号化し、暗号文をコピー
- 暗号文を問題文に含め、コードブック名をヒントとして提示
難易度調整のバリエーション:
- EASY: コードブック名を明示、ラウンドロビンOFF
- MEDIUM: コードブック名を明示、ラウンドロビンON
- HARD: コードブック名は伏せ、「19世紀の有名な書籍」とヒント
- EXPERT: コードブックの一部のページのみ提供(不完全な鍵)
解答手順:
-
コードブックの特定(HARD問題の場合)
- ヒント「19世紀の有名な書籍」から候補を絞る
- プリセットの3種類を試す(Declaration of Independence、Aesop's Fables、King James Bible)
-
インデックス構築
- 特定したコードブックをプリセットから読み込み
- 「ページあたりの行数」が問題文と一致するか確認(デフォルト40行)
- インデックス構築を実行
-
復号実行
- 暗号文を復号タブに貼り付け
- 復号ボタンをクリック
- 復号結果から
flag{...}形式のフラグを抽出
-
エラーのトラブルシューティング
[?]が出力される場合、正規化オプション(大文字小文字、NFKC)を調整- ページあたりの行数を変えて試す(35, 40, 45など)
練習問題のアイデア:
- 📝 Problem 1: 単純な暗号化・復号(ラウンドロビンOFF)
- 📝 Problem 2: ラウンドロビンONでの頻度分析耐性を体験
- 📝 Problem 3: 未収録語
{???}を含む暗号文の部分解読 - 📝 Problem 4: 異なるページあたりの行数で暗号化された暗号文(設定推測が必要)
スキルアップのポイント:
- ✅ 古典暗号の仕組みを素早く理解する力
- ✅ 不完全な情報から鍵(コードブック・設定)を推測する力
- ✅ ツールを活用した効率的な解読技術
CTF運営者向けのヒント:
- 💡 複数のコードブックを組み合わせた複合問題(ページごとに異なるコードブック)
- 💡 暗号文の一部が欠落している問題(文脈からの推測が必要)
- 💡 書籍暗号と他の暗号方式を組み合わせたチェイン問題
- 書籍・新聞・聖書など「誰でも入手できるテキスト」を鍵の代替とすることで、怪しまれにくい秘匿通信 を実現。
- 19–20世紀の スパイ・外交・戦時通信 で多用され、ブックコード破り(book code breaking) は情報戦の一分野でした。
- 実務では 版違い・改訂差・句読点差 などが致命的エラー源であり、運用設計(同一版の配布・更新手順)が重要でした。
-
鍵の隠匿性が高い
- 書籍を持っていても、それが暗号の鍵だと気づかれにくい
- 怪しまれずに鍵を運搬・保管できる
-
鍵の入手が容易
- 市販の書籍・新聞・聖書などを使用可能
- 秘密の鍵交換が不要(公開されているテキストを使える)
-
理論的には解読困難
- コードブックが分からなければ、暗号文だけでは解読不可能
- 総当たり攻撃が実質的に不可能(コードブック候補が無限)
-
実装がシンプル
- 複雑な数学的計算が不要
- 紙とペンだけで暗号化・復号が可能
-
語彙の制限
- コードブックに含まれない単語は暗号化できない
- 専門用語や固有名詞の暗号化が困難
-
版の違いに脆弱
- 送信者と受信者が同じ版(edition)を持っている必要がある
- 改訂版・誤植・句読点の違いで互換性が失われる
-
統計的攻撃に脆弱
- 単語の出現頻度や位置の偏りから情報が漏れる
- 長い暗号文では頻度分析が有効
-
運用コストが高い
- 暗号化・復号に時間がかかる(各単語を手作業で検索)
- コードブックの配布・更新が困難
-
暗号文のサイズが大きい
- 1単語が3つの数字(例:
12:5:3)に変換される - 元の文章より暗号文の方が長くなる
- 1単語が3つの数字(例:
書籍暗号は暗号史において「単純置換暗号の変種」として分類され、古典暗号学の文献で詳細に分析されています。
主要な文献:
- David Kahn『The Codebreakers』(1967)
- 第2章「The First 3,000 Years」で書籍暗号の歴史的事例を詳述
- Benedict Arnold事件(1780年)での使用例を分析
- Simon Singh『The Code Book』(1999)
- 古典暗号から現代暗号への発展を概観し、書籍暗号の限界を指摘
- Cipher A. Deavours & Louis Kruh『Machine Cryptography and Modern Cryptanalysis』(1985)
- 手計算暗号の時代背景と、機械式暗号への移行を論じる
置換暗号としての性質:
- ホモフォニック置換暗号(Homophonic Substitution Cipher) の一種
- 1つの平文単語が複数の暗号表現(座標)を持つ
- 頻度分析への耐性を向上(完全ではない)
- Shannon の情報理論的評価:
- 混乱(Confusion): 中程度(単語→座標の対応は複雑)
- 拡散(Diffusion): 低い(単語ごとに独立した変換、相互作用なし)
現代の暗号学の観点から、書籍暗号は以下のように評価されます:
計算量的安全性(Computational Security):
- ❌ 不十分: コードブックが既知の場合、瞬時に復号可能
- ❌ 鍵空間の錯覚: 理論的には膨大だが、実際には攻撃者が候補を絞り込める
- 例:「聖書を使った」という情報が漏れれば、鍵空間は数十種類の版に限定
情報理論的安全性(Information-Theoretic Security):
- ❌ 完全秘匿性なし: ワンタイムパッドと異なり、複数回の使用で統計的性質が露呈
- ❌ 平文と暗号文の長さに相関: 暗号文の長さから平文の単語数が推測可能
暗号解析の文献では、以下の攻撃手法が確立されています:
-
頻度分析(Frequency Analysis)
- Friedman, W. F. (1918)『The Index of Coincidence and Its Applications in Cryptography』
- 座標の出現頻度から、英語の頻出語("the", "and", "of")を推定
- 対策: ラウンドロビン割当(本ツールで実装)
-
既知平文攻撃(Known-Plaintext Attack)
- 一部の平文-暗号文ペアが既知の場合、コードブックの内容を推測
- 実例: 定型句("Dear Sir", "Yours faithfully")からの突破
-
コードブック推定攻撃
- 暗号文の統計的性質から、使用されたコードブックを推測
- 実例: 座標の範囲(例:ページ1〜50のみ)から書籍のサイズを推定
-
n-gram分析
- Gaines, H. F. (1956)『Cryptanalysis: A Study of Ciphers and Their Solution』
- 連続する単語の組み合わせパターンを分析
- "of the", "in a" などの頻出バイグラムを特定
| 暗号方式 | 鍵の秘匿性 | 頻度分析への耐性 | 実装の複雑さ | 歴史的重要性 |
|---|---|---|---|---|
| 書籍暗号 | ⭐⭐⭐⭐ | ⭐⭐ | ⭐ | ⭐⭐⭐ |
| 単一換字式暗号(単純置換) | ⭐⭐ | ⭐ | ⭐ | ⭐⭐⭐⭐ |
| ヴィジュネル暗号 | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| プレイフェア暗号 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| エニグマ暗号 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
近代暗号(1970年代以降)との対比:
| 特性 | 書籍暗号 | 現代暗号(AES, RSAなど) |
|---|---|---|
| 理論的基盤 | 経験則 | 計算量理論・数論 |
| 安全性の証明 | なし | 数学的証明あり |
| 鍵の配送 | 物理的配送 | 公開鍵暗号で解決 |
| 処理速度 | 極めて遅い | 高速(ハードウェア支援) |
| 標準化 | なし | NIST, ISOなどで標準化 |
書籍暗号は現代では実用されませんが、以下の教育的価値があります:
- 暗号史の理解: 古典暗号から現代暗号への発展を理解する出発点
- 統計的攻撃の学習: 頻度分析・n-gram分析などの基礎技術を体験
- 鍵管理の重要性: 版の違いによる互換性問題は、現代の鍵管理にも通じる教訓
- 完全秘匿性の限界: ワンタイムパッド以外の暗号は統計的性質を持つことを体感
- Kahn, D. (1967). The Codebreakers: The Story of Secret Writing. Macmillan.
- Singh, S. (1999). The Code Book: The Science of Secrecy from Ancient Egypt to Quantum Cryptography. Doubleday.
- Friedman, W. F. (1918). The Index of Coincidence and Its Applications in Cryptography. Riverbank Publication No. 22.
- Gaines, H. F. (1956). Cryptanalysis: A Study of Ciphers and Their Solution. Dover Publications.
- Deavours, C. A., & Kruh, L. (1985). Machine Cryptography and Modern Cryptanalysis. Artech House.
- Schneier, B. (1996). Applied Cryptography (2nd ed.). John Wiley & Sons. (Chapter 1: Foundations)
- 📕 任意テキストをコードブック化(貼り付け→インデックス構築)
- 📚 コードブックプリセット機能(data/フォルダーから自動読み込み、初回起動時に自動ロード)
- 🧮 page:line:word 参照の双方向変換(暗号化/復号)
- ⚙️ 調整可能な ページあたりの行数、大文字小文字・NFKC正規化のON/OFF
- 🔄 ラウンドロビン割当のON/OFF(頻出語が毎回異なる座標になるモード、デフォルトON)
- 🔍 未対応語・衝突(同語の多数出現)の検出
- 📊 インデックス統計(ページ数・行数・単語数・ユニーク語数)
- 🖱️ クリックで該当語をハイライトするビューワー(全出現座標を表示)
- ⌨️ キーボードショートカット対応(Enter/Ctrl+Enterで実行)
- 📋 ワンクリックでコピー機能(暗号文・平文、フィードバック付き)
- 🔄 暗号文同期機能(暗号化タブの出力を復号タブへワンクリック転送)
- 🎛️ スマートなボタン状態管理(入力内容に応じて自動的に有効/無効を切り替え)
- 📖 アコーディオン形式のヘルプ(基本・仕組み・歴史・使い方・技術仕様を折りたたみ表示)
- 🔒 セキュリティ機能(CSP、XSS防止、パストラバーサル防止)
- 🌗 ダークモード対応(システム設定に追従)
- 📱 レスポンシブデザイン(モバイル対応)
- Reference Text(コードブック原文) にコードブックとして使うテキストを設定:
- 自動ロード:初回起動時に最初のプリセットが自動的に読み込まれます
- プリセットから選択:コードブックプリセットボタンをクリック(Project Gutenbergからの歴史的文書を収録)
- 手動で貼り付け:任意のテキストを貼り付け
ページあたりの行数や正規化オプションを調整し、インデックス構築 を押す- 大文字・小文字を無視(デフォルトON)
- Unicode正規化/NFKC(デフォルトON)
- ラウンドロビン割当(デフォルトON、推奨)
- 暗号化 タブで平文を入力 → 暗号化 で
p:l:wに変換- プリセットボタンで例文を素早く入力可能
- 📋 コピーボタンで暗号文をクリップボードにコピー
- 重要: 同じ平文でも暗号化ボタンを押すたびに暗号文が変わります(これは正常な動作です。詳細は下記の「ラウンドロビン割当」を参照)
- 復号 タブで
12:5:3, 12:5:4 ...のようなコード列を入力 → 復号- ↓ 同期ボタンで暗号化タブの暗号文を自動転送
- 📋 コピーボタンで復号した平文をクリップボードにコピー
- ビューワー タブでコードブックの内容を確認、単語をクリックして全出現座標を表示
- ページ送り・戻しボタンでナビゲーション
- 単語をクリックすると、その単語の全出現座標がハイライト表示されます
- ヘルプ タブで詳しい使い方や技術仕様を確認
- アコーディオン形式で必要な情報を展開できます
- 統計値やハイライトを確認し、運用上の課題(曖昧・未収録)を体感
data/フォルダーにテキストファイル(.txt)を配置data/manifest.jsonにファイル情報を追加:
{
"codebooks": [
{
"id": "aesops-fables",
"title": "Aesop's Fables (イソップ物語)",
"filename": "aesops-fables.txt",
"description": "古典的な寓話集",
"source": "Project Gutenberg",
"sourceUrl": "https://www.gutenberg.org/ebooks/11339"
}
]
}フィールド説明:
id,title,filename: 必須description: オプション(ツールチップに表示)source,sourceUrl: オプション(管理用、UIには表示されない)
- ページをリロードすると、プリセットボタンが自動的に表示されます
詳細は data/README.md を参照してください。
本ツールでは、コードブックのテキストを以下のように処理します:
-
改行による行分割
- 入力テキストは改行文字(
\nまたは\r\n)で行に分割されます - 改行情報自体は保持されず、各行は独立した行番号で管理されます
- 空行も1つの行として扱われます(単語数0の行)
- 入力テキストは改行文字(
-
ページ分割
- 「ページあたりの行数」(デフォルト40行)で指定した行数ごとにページが切り替わります
- 例:Lines Per Page = 40 の場合
- 1〜40行目 → ページ1
- 41〜80行目 → ページ2
- 81〜120行目 → ページ3
- 物理的な書籍のページとは異なり、行数ベースの論理的なページ分割です
-
行の構造
- 1行あたりの単語数に制限はありません(可変長)
- 各行は改行で自然に区切られ、その行に含まれる単語はすべて記録されます
- 実際の書籍と同様、行の長さ(単語数)は様々です
-
単語の抽出
- Unicode対応の正規表現で抽出:
/[\p{L}\p{N}]+(?:[-'''][\p{L}\p{N}]+)*/gu - 認識される単語例:
- 英数字:
hello,abc123 - ハイフン付き:
co-operate - アポストロフィ付き:
don't,it's
- 英数字:
- 空白・句読点・記号は単語の区切りとして扱われます
- Unicode対応の正規表現で抽出:
-
正規化オプション
- 大文字・小文字を無視:すべて小文字に統一(デフォルトON)
- Unicode正規化(NFKC):全角半角の差異を統一(デフォルトON)
- これらの設定は暗号化・復号の両方で同じ設定を使う必要があります
- 実際の書籍では行の長さは様々であり、人為的に単語数で制限する必要はありません
- 改行は自然な区切りであり、テキストの構造を保持するために重要です
- 単語数で強制的に区切ると、元のテキストの意味的な構造が失われます
同じ単語がコードブック内に複数回出現する場合、ラウンドロビン(Round-robin)方式で座標を割り当てます。
同じ平文を何度暗号化しても、毎回異なる暗号文が生成されます。これは仕様であり、正常な動作です。
理由:
- ラウンドロビン方式では、同じ単語でも使用するたびに次の出現位置を使用します
- 内部でポインタが進むため、2回目の暗号化では前回とは異なる座標が選ばれます
- これにより、頻度分析攻撃への耐性が向上します
例:
1回目の暗号化: "the" → 1:2:3
2回目の暗号化: "the" → 5:7:1 (異なる座標)
3回目の暗号化: "the" → 8:3:2 (さらに異なる座標)
ポインタをリセットする方法:
- ページをリロードする
- 「インデックス構築」ボタンを再度押す
- インデックス構築時に、各単語のすべての出現位置を記録
- 暗号化時に、同じ単語が登場するたびに、記録された座標を順番に使用
- 最後の座標まで使ったら、最初の座標に戻る(循環)
- ポインタは暗号化のたびに進み、リセットされません
コードブック内で「wolf」が以下の3箇所に出現する場合:
位置1: 1:5:2 (1ページ5行2語目)
位置2: 2:3:1 (2ページ3行1語目)
位置3: 3:1:4 (3ページ1行4語目)
平文「the wolf said the wolf」を暗号化すると:
the → 1:2:1
wolf → 1:5:2 ← 1回目の wolf(位置1を使用)
said → 1:3:5
the → 1:2:1
wolf → 2:3:1 ← 2回目の wolf(位置2を使用)
さらに「wolf」が3回、4回と続けば:
3回目の wolf → 3:1:4 (位置3を使用)
4回目の wolf → 1:5:2 (位置1に戻る)
5回目の wolf → 2:3:1 (位置2)
本ツールでは、ラウンドロビン割当を オプション で選択できます(デフォルト: ON)。
- ON(推奨): 同じ単語でも毎回異なる座標を使用。頻度分析攻撃への耐性が向上
- OFF: 同じ単語は常に最初に出現した座標を使用。暗号文が短く予測可能になるが、頻度分析に脆弱
例("the"が3回登場する場合):
ラウンドロビン ON: 1:2:1, 3:5:4, 7:1:2 (毎回異なる)
ラウンドロビン OFF: 1:2:1, 1:2:1, 1:2:1 (常に同じ)
- 頻度分析攻撃への耐性: 同じ単語でも暗号文では異なる座標になるため、単純な頻度分析が困難に
- パターン隠蔽: 「the」「and」などの頻出語が常に同じ座標にならない
- 予測困難性: 同じ平文でも毎回異なる暗号文が生成されるため、パターン解析が困難
- 歴史的実務: 実際の書籍暗号でも、複数の参照位置を持つことが推奨されていました
ラウンドロビンと復号の互換性:
- ラウンドロビンは暗号化時の座標選択のみに影響します
- 復号は常に成功します(座標が正しければ、どの出現位置でも同じ単語に復号されます)
- 例:
1:2:3でも5:7:1でも、両方とも "the" に復号される場合があります
実運用での課題:
- 送信者と受信者が別々に暗号化すると、同じ平文でも異なる暗号文になります
- これは通常の暗号システムとは異なる挙動ですが、書籍暗号の特性です
- 実際の歴史的使用では、事前に座標を合意するなどの工夫がなされていました
書籍暗号のセキュリティを評価する上で、コードブック内の単語分布の偏りは重要な考慮事項です。
自然言語のテキストでは、単語の出現頻度は極めて不均等です。これは言語学で知られる「Zipfの法則」に従います。
- 上位数%の単語("the", "and", "of", "to" など)が**全単語の30〜50%**を占める
- 大多数の単語(固有名詞、専門用語など)は1〜数回しか出現しない
具体例(英語テキスト):
"the" → 全体の約7%を占める(圧倒的1位)
"and" → 全体の約3.5%
"of" → 全体の約3%
...
上位10単語で全体の約25%
上位100単語で全体の約50%
同じ単語でも、コードブック内の出現位置には偏りがあります。
-
トピックによる局在化
- 専門用語や固有名詞は特定のセクション(章・ページ)に集中
- 例:「wolf」という単語は、動物についての章に集中して出現
- 結果として、その単語の座標は狭い範囲(例:ページ1〜3のみ)に偏る
-
文脈依存の共起
- 特定の単語の組み合わせが頻繁に共起(例:「united states」)
- 座標の組み合わせパターンから文脈を推測される可能性
-
文書構造の影響
- 章の冒頭・結末での定型句("In conclusion", "Chapter 1"など)
- ページ番号や索引による機械的な繰り返し
ラウンドロビン割当はパターン隠蔽に有効ですが、分布の偏りそのものは解消できません。
ケース1: 頻出語の偏った分布
"the" が100回出現するが、すべて前半(ページ1〜5)に集中
→ ラウンドロビンONでも、暗号文の座標は 1:x:y 〜 5:x:y の範囲に偏る
→ 攻撃者は「頻繁に前半ページの座標が出現する = 頻出語」と推測可能
ケース2: 稀な単語
"cryptography" が1回しか出現しない
→ 常に同じ座標 12:8:3 が使われる
→ その座標が暗号文に出現 = "cryptography" と特定される可能性
単語分布の偏りは、以下の統計的攻撃を可能にします。
-
高次頻度分析
- 座標の出現頻度パターンから、頻出語を推測
- 座標のページ分布から、単語の特性を推測(前半頻出=冠詞・接続詞など)
-
n-gramパターン分析
- 連続する座標の組み合わせから、よくある単語の組み合わせ("of the", "in a"など)を推測
-
位置ベースのクラスタリング
- 座標の空間的な偏りから、トピックや文脈を推測
より安全な書籍暗号を実現するには、以下の特性を持つコードブックが理想的です。
✅ 多様な語彙: 固有名詞や専門用語が少なく、一般的な語彙が豊富 ✅ 均等な分布: 同じ単語が全体に分散して出現(局所的な偏りが少ない) ✅ 十分な長さ: 頻出語が十分な回数(10回以上)出現し、ラウンドロビンの効果が高い ✅ 文脈の多様性: 様々なトピックを扱い、特定の語彙に偏らない
実務的なヒント:
- 📰 新聞記事の集合: 多様なトピックで語彙が分散
- 📚 辞書・百科事典: 語彙が豊富で均等に分布
⚠️ 避けるべき: 小説(特定の登場人物名や場所が偏る)、技術文書(専門用語が偏る)
ビューワー機能を使って、コードブックの単語分布を視覚的に確認できます。
- ビューワーで単語をクリック → その単語の全出現座標を表示
- 座標が全ページに分散しているか確認
- インデックス統計で「ユニーク語数/総単語数」の比率を確認(低すぎる場合は語彙が貧弱)
- コードブックに存在しない単語は暗号化できません(
{???}で出力) - 完全なワンタイムパッドではないため、十分な長さのコードブックと多様な語彙が重要
- 同じコードブックを繰り返し使うと、統計的攻撃に脆弱になります
- ラウンドロビンOFFの場合、頻度分析攻撃に極めて脆弱です
本ツールは、GitHub Pagesでの安全な公開のため、以下のセキュリティ対策を実装しています。
厳格なCSPをメタタグで実装し、XSS攻撃を防止:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
object-src 'none';
base-uri 'self';
form-action 'none';" />- すべてのリソース(スクリプト、スタイル、画像)は同一オリジンのみ許可
- インラインスクリプト・スタイルは使用禁止(すべて外部ファイル化)
- Data URI形式の画像のみ許可(faviconで使用)
- escapeHtml() 関数:ユーザー入力をHTMLに挿入する前に、特殊文字(
<,>,&,",')をエスケープ - textContent 優先:HTMLパースが不要な箇所では
textContentを使用 - textarea.value:ユーザー入力/出力にはテキストエリアの
valueを使用(HTMLパース無し)
実装例(script.js:87-91):
function escapeHtml(str){
const div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}"data/"フォルダーからファイルを読み込む際、悪意のあるファイル名を検証。
実装(script.js:468-482):
function validateFilename(filename) {
// 英数字、スペース、ハイフン、アンダースコア、.txt拡張子のみ許可
const safePattern = /^[a-zA-Z0-9\s\-_']+\.txt$/;
if (!safePattern.test(filename)) {
console.error('Invalid filename detected:', filename);
return false;
}
// パス区切り文字、親ディレクトリ参照を拒否
if (filename.includes('/') || filename.includes('\\') || filename.includes('..')) {
console.error('Path traversal attempt detected:', filename);
return false;
}
return true;
}../../../etc/passwdのようなパストラバーサル攻撃を防止- 安全なファイル名パターンのみ許可
<meta http-equiv="X-Content-Type-Options" content="nosniff" />
<meta name="referrer" content="no-referrer" />- X-Content-Type-Options: MIMEタイプのスニッフィングを防止
- Referrer Policy: リファラー情報を送信しない(プライバシー保護)
外部リソースへの依存を避けるため、Data URI形式のSVG faviconを使用:
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='0.9em' font-size='90'>📖</text></svg>" />- 外部ファイルへのリクエストを削減
- 404エラーを防止
- CSPの
img-src 'self' data:ポリシーに準拠
本ツールは教育・研究目的であり、以下の点に注意してください:
⚠️ ブラウザーのローカルストレージに機密情報を保存しません(リロードで状態がリセット)⚠️ すべての処理はクライアント側で完結し、サーバーへのデータ送信はありません⚠️ 実運用の暗号システムとして使用しないでください
- 版の差(改行・句読点・表記ゆれ)はコードの互換性を壊します。
→ 本ツールは 行数基準のページ分割 を採用し、古典的実務を近似再現しています。 - 語の出現回数が多い と曖昧になります。ラウンドロビン割当で分散しますが、誤復号の可能性は残ります。
- 実運用を推奨するものではありません。歴史的手法の教育・研究を目的とします。
book-code-builder/
├── .gitignore # Git除外設定
├── .nojekyll # GitHub Pages設定(Jekyll無効化)
├── assets/ # スクリーンショット等のアセット
│ └── screenshot.png # 使用例のスクリーンショット
├── CLAUDE.md # Claude Code用プロジェクトガイド
├── data/ # コードブックプリセット
│ ├── manifest.json # プリセット定義ファイル
│ ├── README.md # data/フォルダーの使い方
│ ├── Aesop's Fables.txt # イソップ物語(Project Gutenberg)
│ ├── The King James Version of the Bible.txt # 欽定訳聖書(Project Gutenberg)
│ └── United States Declaration of Independence.txt # アメリカ独立宣言
├── index.html # メインHTMLファイル
├── LICENSE # MITライセンス
├── README.md # プロジェクトドキュメント(本ファイル)
├── script.js # JavaScriptロジック
├── style.css # スタイルシート
└── TECHNICAL.md # 技術実装詳細(開発者向け)
本ツールの技術的な実装の詳細、アルゴリズム、設計パターンについては、以下のドキュメントを参照してください:
- データ構造の設計: 3次元配列と逆引きインデックスの実装
- ラウンドロビン割当アルゴリズム: 頻度分析攻撃への耐性を実現する仕組み
- インデックス構築アルゴリズム: O(n)の効率的な構築プロセス
- Unicode対応トークン化: 多言語対応の正規表現パターン
- セキュリティ実装: XSS防止、パストラバーサル防止、CSP準拠
- パフォーマンス最適化: 計算量分析とUI応答性の確保
- 状態管理パターン: グローバルstateオブジェクトの設計
- CSP準拠の実装: インラインスタイル排除の戦略
このドキュメントは、コードベースを理解したい開発者、拡張機能を実装したい方、または技術的な詳細に興味がある方を対象としています。
MIT License – 詳細は LICENSE を参照してください。
本ツールは、「生成AIで作るセキュリティツール100」プロジェクトの一環として開発されました。 このプロジェクトでは、AIの支援を活用しながら、セキュリティに関連するさまざまなツールを100日間にわたり制作・公開していく取り組みを行っています。
プロジェクトの詳細や他のツールについては、以下のページをご覧ください。
