日本語訳 · 原著 Daniel Bourdeau『Unsolved Historical Ciphers』は CC BY 4.0 で公開されている。本ページは JIC による翻訳で、原著者の公式版ではない。訳文に相違がある場合は英語原文が優先する · 英語原文を見る ↗

コペンハーゲン · 線、点、数字、方式不明 · おそらく1950年代後半に発見

コペンハーゲン暗号

コペンハーゲンの軍事博物館にあるデンマークの将軍の1835年の肖像画の裏から見つかった、線、点、山形記号、数字からなる3行で、Klaus Schmeh の Top 50 の第23位。2026年9月、2通りの転写と6つの規約のもと、10言語の単一換字として攻撃し、条件を揃えた対照実験も行った。鍵は復元されず、解読も公表されていない。

Daniel Bourdeau · 投稿 · 更新 · 出典:Klaus Schmeh の Cipherbrain の2015年1月、2017年8月、2021年10月の投稿とそのコメント、614 × 147 px のスキャン画像 Danish-General-Cryptogram.jpg

方法:未解読 · 範囲:本文は得られず

検証したどの言語の単一換字でもない スキャンからは打ち切り

流布している2通りの転写の両方を、5-gram 言語モデルで評価するソルバー(焼きなまし法)で10言語について攻撃した。どの言語でも最良値は1文字あたり −2.69 natsで、300回の再起動でも動かなかった。同じソルバーは、同じ方法で暗号化したランダムな103文字の文章15件中12件を復元でき、この長さの本物のテキストは −1.4 から −2.1 の間のスコアを取る。この紙片はこれらの言語のテキストの単一換字ではないか、両方の読みに共通する転写の誤りがあるかのどちらかである。

01 対象物とその来歴

紙片には短い3行が書かれている。おそらく1950年代後半に、コペンハーゲンの軍事博物館にあるデンマークの将軍の1835年の肖像画の裏から見つかり、American Cryptogram Association に送られた。ACA は解答を記録せず、報告を書くこともなかった。博物館、将軍、発見者はいずれも記録されていない。

Klaus Schmeh は、フロリダ在住のスウェーデン人で2016年に亡くなった ACA 会員 Kent Ramliden からスキャン画像を受け取った。彼はそれを3度公表している:2015年1月にドイツ語で、2017年8月に Top 50 の第23位として、そして2021年10月にドイツ語と英語の「未解決事件」投稿として。流布している画像はそのスキャン、614 × 147 ピクセルのものだけである。2021年のコメントのうち2つの読者投稿がここで重要である:「ShadowWolf」による25記号の転写と、Matthew Brown によるデンマーク語の4-gram 山登り法で、後者は何も見つけなかった。

02 転写

2通りの転写を用いた。 cipher.txt は本プロジェクトのもので、スキャン画像を4倍と6倍に拡大し、半行ずつ作成した。 cipher_sw.txt は、2021年10月7日のドイツ語投稿のコメントにある ShadowWolf の25記号の読みである。以下は統合した読みで、1記号につき1トークン、空白区切り:

7 N F n F B 3 A D B n o 3 D B P 6 3 B 3 P 8 D F 2 n 3 | 2 3 A W R F 0 3
A n 2 0 B n o 9 P n P 9 2 B 3 v v 3 D B | 0 A B v 3 D B P n o F 3 8 0 D B
P X 0 3 B n o n F 9 n D B v n | 1 3 | n o n 3 F D B 3 F B A 1 2 3 A

計107トークン:20種類103個の記号に加え、4本の長い縦線があり、これは | と書き、文の区切りとして扱った。数字の4と5は一度も現れない。

トークン紙片上の記号個数
3数字の316
nただの n13
B後ろに点が付いたバックスラッシュ(\.)14
F後ろに点が付いたスラッシュ(/.)8
Pプラス記号6
A山形記号またはラムダ(^)6
D線の前に置かれた独立した点8
o小さく丸い文字 o5
2数字の25
0縦長のゼロ5
v書かれたとおり4
9数字の93
1数字の12
8数字の82
7 6 X書かれたとおり各1
N上に2つの点が付いた n1
R1行目末尾の「or」に似た小さな字形1
W上に二重のアクセントが付いた山形記号1
|長い縦線、文の区切り、103個には数えない4

2つの読みが異なる箇所

2つの読みは、ここで統合したものを ShadowWolf が分けている点を除き、記号ごとに一致する。彼は、後ろに点が付いたバックスラッシュと、両側に点が付いたバックスラッシュを区別する。後者はここでは独立した点 D の後に Bが続くものとしている。彼は、後ろに点が付いたスラッシュと前に点が付いたスラッシュを区別する。後者はここでは D の後に Fである。彼は最初の山形記号の対の後にある小さく上付きの二重の刻みに独自の記号を与えている。彼は4種類の山形記号を区別する:ラムダに似た縦長のもの(1行目の最初の山形記号と3行目の最後の記号)、小さいもの、2行目冒頭の後ろに点が付いたもの、そして2行目のゼロの後のもの。さらに彼は3行目の 1 3 の周りにある2本目の縦長の線を、区切りではなく数字の1と読む。これらを分けると記号数は25となり、Schmeh の数字と一致する。統合すると20である。両方の読みを攻撃した。

2つの内部的規則性

書簡 o は5回現れ、いずれも直前に n: no3, no9, +no, non と non3があり、 non は3行目に2回ある。二重になった対 vv は2行目に1回現れる。それがどこまで及ぶかは第06節で示す。

03 攻撃

solve.py は、10言語(デンマーク語、スウェーデン語、ノルウェー語、ドイツ語、オランダ語、フランス語、英語、ラテン語、アイスランド語、フィンランド語)の Project Gutenberg のテキストから文字単位の 5-gram 言語モデルを構築する。各言語60万から240万文字である。コーパスはリポジトリには含まれず、セッションログにある id を使って Gutendex API から取得する。ソルバーは記号から文字への単射写像に対する焼きなまし法で、1回の実行につき60から80回の再起動を行い、長い線は文の境界として扱う。ソルバーは 5-gram スコアのみを最適化する。その上位候補を、最適化の対象ではない辞書カバー率で並べ替える。

統合した読みに対して6つのトークン規約を試した:独立した点を1文字とする、削除する、境界とする、後続の線に融合する、長い線を1文字とする、点付き n を通常の n に統合する。25記号の読みはそのまま実行した。別のスクリプト solve_sp.pyは、2つの点付きの線が語の区切りであるという仮説を検証する。その場合テキストは平均3.7文字の22語となる。空白を考慮したモデルを用い、語全体の一致を評価する。

どの言語、どの規約でも読めるものは出てこなかった。1文字あたりの最良スコアと、最良の鍵が生み出したもの:

言語1文字あたりの最良スコア(全規約)出力の様子
ラテン語−2.69fxsisted tine togeteom scie ...
デンマーク語−2.77junindel dige dskedesf ... / ... udstødes ... velsigne ...
ノルウェー語−2.81bærersag sena stjasatm ...
スウェーデン語−2.81honensam sera stfasatv ...
日本語−2.88cydidsea sine stbesetf ...
ドイツ語−2.93uchthien itze irbeierm ...
フランス語−2.97chiailes lape ltbeletr ...
オランダ語、アイスランド語、フィンランド語−3.07 から −3.30

語区切り仮説は、空白入りモデルで1文字あたり −4.6 のスコアとなる。本物のテキストは約 −2.3 である。得られるのは孤立したデンマーク語の単語だけである:er、elle、unge、død、døde。最後の2つが第06節で論じる断片である。

04 条件を揃えた対照実験

探索の失敗はそれだけでは何も証明しないので、ソルバーが解けるはずのテキストで較正した。 control.py は、同じコーパスから3つの文区切りを含む103文字の文章を無作為に抽出し、それぞれを約20記号のランダムな単一換字で暗号化して、同一のソルバーで攻撃する。各言語3回の試行、各40回の再起動。実際の暗号は60から80回、その後300回である。正解率は文章のうち復元された割合である。

言語試行鍵の文字数正解率得られたスコア真のテキストのスコア結果
デンマーク語1190.99−1.99−1.85復元
デンマーク語2190.99−1.93−1.96復元
デンマーク語3180.99−1.85−1.76復元
ドイツ語1220.96−1.88−1.78復元
ドイツ語2190.79−2.64−1.75部分
ドイツ語3220.14−3.42−1.81探索失敗
日本語1201.00−1.44−1.44復元
日本語2210.99−1.99−1.85復元
日本語3201.00−1.67−1.67復元
ラテン語1181.00−2.09−2.09復元
ラテン語2181.00−1.74−1.74復元
ラテン語3190.99−1.87−1.72復元
スウェーデン語1221.00−1.95−1.95復元
スウェーデン語2220.05−3.49−1.59探索失敗
スウェーデン語3221.00−1.99−1.99復元

15件中12件の文章は実質的に完全に復元され、真のテキストは常に1文字あたり −1.4 から −2.1 のスコアを取る。2件の試行は完全に失敗し、1件は部分的に失敗した。いずれの場合も、真の鍵はソルバーが見つけたものよりはるかに良いスコアになったはずである:−1.81 対 −3.42、−1.59 対 −3.49、−1.75 対 −2.64。これらは40回の再起動での探索の失敗で、おそらく22文字の鍵に関係しており、実際のテキストに対する1回の失敗した実行は何も証明しないことを意味する。そのため、有力な候補言語については両方の読みで300回の再起動を行って再実行した。

この較正に照らすと、暗号はどの言語、どの読みでも −2.7 より良いスコアを取ることがない。したがって、これら10言語のテキストの単一換字ではないか、あるいは転写が、独立した2つの読みに共通する形で文字を混同または分割しているかのどちらかである。2015年以来の既定の想定であるデンマーク語は、ラテン語やノルウェー語より当てはまりが良いわけではない。2021年のコメントにある Matthew Brown のデンマーク語4-gram 山登り法も、同じく何も得られなかった。

05 300回再起動による確認

シード5から300回再起動したときの1文字あたりの最良スコア。対象は統合した読みの full と nodot 規約と25記号の読みである。 dotattach の実行はこのノートの執筆時点でまだ続いており、これらを上回っていなかった。

言語統合、完全統合、点なし25記号の読み
ラテン語−2.90−2.82−3.16
デンマーク語−3.04−2.90−3.16
スウェーデン語−3.17−2.99−3.20
ノルウェー語−3.12−3.01−3.17
日本語−3.20−3.13−3.28
ドイツ語−3.29−3.32−3.46

再起動を5倍にしても何も動かない。第03節は6つの規約の最良値を採ったが、これらの実行は規約とシードを固定しており、どのセルもそれを上回らない。上限は同じで、これらどの言語でも、この長さの本物のテキストが取るスコアより1文字あたり0.7から1.4 nats 低い。探索の失敗という説明は排除される。

06 唯一示唆的な断片

non を død と読む

次の割り当て n = d, o = ø, 3 = e のもとで、n-o-n のパターンはデンマーク語の død(死んだ、死)を与え、 non3 は døde(死んだ、死者)を与え、 no3 は døe、すなわち dø(死ぬ)の1900年以前の綴りを与える。これが探索全体で唯一示唆的な断片である。

これは語区切りの実行で浮上したもので、その他の語全体の一致は er、elle、unge だけだった。関係する3つの記号は103トークンのうち34を占めるので、この割り当てでテキストの3分の1が決まる。だがそれは広がらない。その解読の残りは雑音であり、実行全体のスコアは1文字あたり −4.6 で、同じモデルでの本物のテキストは約 −2.3 である。

07 現状と再開の条件

未解読 現存するスキャンからは打ち切り。再開の道は3つある。

08 ファイル

すべてはプロジェクトのリポジトリの targets/copenhagen/ にある。 cipher.txt は統合した20記号の読みで、トークン規約はヘッダーにある。 cipher_sw.txt はそれに揃えた ShadowWolf の25記号の読みである。 solve.py は辞書による並べ替えを備えた 5-gram ソルバー(焼きなまし法)、 solve_sp.py は語区切りの検証、 control.py は条件を揃えた対照実験の実行環境である。 NOTES.md には試みの完全な記録がある。Gutenberg のコーパスはリポジトリになく、Gutendex の id はセッションログにある。