Article 2 · Technical write-up
Breaking Wenmi: from letter structure to two parameter-free keys
How you get from "fazihipego wezelucuna" to "報傳取消日人態度遽變": the transcription, thirty sessions of computation, most of them negative, one simple statistical test that changes everything, and two keys that each fit on one line.
Passages underlined with dots are unconfirmed hypotheses.
Latin-letter words, but different systems
The public telegraph code is an encoding step, not a secret. The 1916 Wenmi uses conversion into syllables, with two particular grids.
Rosamonde · 1915–1916
EnglishReciprocal letter substitutionyou ↔ heaOne letter replaces another; the same table works in both directions.
Chinese telegraph code
Chinese characterPublic four-digit directory文 → 2429This directory is public: by itself it does not conceal the text.
Condensers · several tables
Four-digit Chinese codeTwo digit pairs → syllables00–99 → CVThe table depends on the system. CV means a consonant followed by a vowel.
Wenmi 1916 · G0 / Y0
Four-digit Chinese codeTwo distinct syllable grids報 → 1032 → fa | ziG0 example only. Y0 uses a different grid: the tables are not interchangeable.
In short: the system
Both 1916 channels are enciphered in five operations, with no secret key in the modern sense. Example from the Tokyo → Zhaoqing channel (June–September 1916):
The G0 grid assigns a consonant + vowel syllable to each number from 00 to 99. The consonants are taken in reverse alphabetical order starting from h (h g f d c b z y x w v t s r q p n m l k), two per tens digit; the vowels a e i o u encode the units digit, ascending for the first consonant of the pair and descending for the second (a "boustrophedon" or serpentine path):
So ha = 00, hu = 04, gu = 05, ga = 09, fa = 10… ka = 99. In Python:
ORDER, V = "hgfdcbzyxwvtsrqpnmlk", "aeiou"
G0 = {c + v: 10 * (i // 2) + (j if i % 2 == 0 else 9 - j)
for i, c in enumerate(ORDER) for j, v in enumerate(V)}
def decode(letters): # "fazihipego..." -> ["1032", "0278", ...]
s = [letters[k:k+2] for k in range(0, len(letters), 2)]
return ["%02d%02d" % (G0[a], G0[b]) for a, b in zip(s[::2], s[1::2])]
Each message ends with the signature 伸 (heyu = 0135), sometimes 伸令, then the day of the month, written either as a 韻目代日 rhyme (巧 18, 漾 23, 元 13…) or as a Chinese numeral (卅 30).
Try it
Pick a telegram, then click a character or start the step-by-step playback: the two syllables light up in the ciphertext and in the key's grid, shown below the message. Both channels are available (G0, then Y0). Characters with an orange dashed border are doubtful (uncertain reading of the form, or rare character).
Each box: syllables · telegraph code · character.
Starting point: published work
Starting point: the article “Sun Yat-sen's circle on the wire, 1916–17”[1] and the repository dbourdeau/cyphersolver[2], which publish transcriptions of the forms and the decipherment of some sixty telegrams of Sun Yat-sen's circle. Those telegrams use “condenser” tables in the line of Yamada Junzaburō's tables, published by S. Tomokiyo on Cryptiana[8]: 20 consonants and 5 vowels, i.e. 100 syllables, one per number from 00 to 99.
Zhao Shen's enciphered telegrams stand apart: ten-letter words, no apparent additive; they were listed there among the open problems[1]. Those of the Military Affairs Council channel usually open with the clear prefix 2429 1378, which reads 文密: this is the name of that cipher. His telegrams to Yunnan, built the same way but with six vowels, open with the indicator “Cg”. We started from the identified documents and the transcriptions, and from the idea that half a telegraph code becomes one syllable. What follows shows that, for the Council channel, the table does follow a simple rule: reversed alphabet, two consonants per ten, serpentine vowels.
Ground rules
Historical decipherment is the perfect place to fool yourself: with enough parameters, you can "read" Chinese in any noise. We therefore worked under rules fixed in advance and recorded in an append-only log (nearly 1,400 lines, 31 sessions):
- Immutable sources. JACAR PDFs kept as downloaded, with SHA-256 hashes recorded; every new reading is a new versioned file.
- A held-out message. Telegram 0406 (12 July 1916) was never used to tune a key or correct a reading. It is used only to judge.
- No cribs. No guessed word (name, formula) was ever forced into the plaintext. Only dates, written in clear on the forms by the Japanese clerk, served as anchors, and several anchor sets were tested.
- Positive and null controls. Each search is also run on a known Chinese text enciphered with a known key of the same form (the solver must recover it), and on shuffled data (the solver must find nothing). A score on the archives only means something relative to those two benchmarks.
- Several seeds. An optimum is kept only if it is found identically from different random starts.
- Explicit status. Every result is labelled: fact, hypothesis, negative test, candidate, corroborated.
Step 1 — Reading what the clerk wrote
From the form to its meaning: a real example
Rosamonde, Shanghai → Tokyo, 7 July 1915. This example uses the English substitution, not Wenmi’s G0 grid.
The ciphertext only exists as handwritten copies by Japanese clerks. The letters g and q, x and d, u and n are easily confused; a single wrong letter changes a character, a skipped letter shifts the whole rest of the message.
- Rendering of the pages at 300 dpi, rotation, cropping of each form and each group (macOS
sips, no image retouching). - Blind reading: a first reader (an AI assistant) fixes its reading, with variants and confidence levels, before seeing any earlier transcription.
- Independent human reading: I read the groups myself through a small local interface that presents anonymous, shuffled excerpts (you don't know which message or position you are looking at), with JSON export. About fifteen batches, several hundred excerpts; some target one letter, with reliable examples from the same copyist for comparison.
- Consensus by majority between readers, disagreements settled on the image. The working corpus went from version v1 (211 codes, 71 masked units) to v8.
One reading detail proved decisive: for a long time q was treated as a graphic variant of g. Human reading separated them, giving an alphabet of exactly 20 consonants (b c d f g h k l m n p q r s t v w x y z, no j). Under the best model of the time, that distinction alone raised the score from 681 to 829.
Declared bias
Two of my reading batches ("assisted readings", then a re-reading of 16 doubtful codes) were not blind: I knew what the model proposed. To limit the risk, the last four units of each message (signature and date) could not be changed this way, the held-out message 0406 was never touched, and every proposal had to be confirmed on the image (18 accepted, 27 rejected).
Step 2 — What did not work (and why)
For thirty sessions we followed the classic approach for an unknown substitution:
- a language model (unigrams and bigrams of telegraph codes) trained on about 430,000 characters of Sun Yat-sen's writings from Wikisource, converted to codes, later supplemented with published 1916 telegrams;
- an unknown table syllable → number (100 cells, freely chosen), searched by simulated annealing: multi-threaded C++ engine, 64 restarts × 30 million iterations, then iterated local search; about 12 minutes per pass on 8 cores;
- anchors: the rhyme of the day at the end of the message, deduced from the date written on the form.
All these searches failed, and the controls say why. The solver recovered the keys of the positive texts (for example 258 codes out of 267): it was capable. But on the archives its best score (≈ 900) stayed far below that of a real text (1,200–1,350), while clearly beating shuffled data (≈ 670). A text enciphered with an arbitrary codebook scored 810–940: the archives looked like that.
Two errors were hiding in the assumptions:
- Wrong anchors. For days 16 to 30, the rhyme convention uses a different tonal series from the one assumed at first (checked in published originals by Sun[11]). Several anchors were therefore wrong.
- A key space that was too large. A free 100-cell table gives enough freedom to manufacture noise optima around 900. The reverse experiment confirms it: relaxing the structure eventually found (experiment E21) raises the fit but makes the held-out message unreadable. That is overfitting.
Meanwhile, a documentary lead was followed to the end. The reports of the Japanese consulate in Hankou (9 and 11 May 1916)[5][6] describe "+111" and then "reverse the four digits + 111" superencipherment. The April telegrams attached to the reports do decode that way (arithmetic carry, rhyme of the day at the end). But every ±111 variant, with or without reversal, and with the residual offset this creates under a syllable table, is negative on the Tokyo stream (experiments E13, E15, E16). Conclusion: no additive key in July.
Step 3 — A keyless test: the consonant encodes the tens
The turning point came from a test that looks for no key at all. Telegraph codes have a very particular shape: the thousands digit is concentrated (common codes are mostly between 0000 and 7999, almost never 8xxx or 9xxx), while the units digits are roughly uniform. If half a code (two digits) becomes a syllable, the question is: which part of the syllable carries the tens digit?
So we count letters by their rank in the message (experiment S3). At the ranks carrying the first half of the code (thousands and hundreds), the distribution of consonants is extremely skewed (z ≈ 22): h and g dominate, l, p and m never occur. The vowels, on the other hand, are homogeneous (z ≈ 1). A simulation (S4) shows that a random table never produces this pattern (0 cases out of 400), while a coordinate table, where the consonant gives the tens digit and the vowel the units digit, reproduces it.
This hypothesis (H9) shrinks the search space dramatically: no longer placing 100 syllables freely, but assigning each consonant to a tens digit and each vowel to a digit. It also showed that some sets of date anchors were impossible: under H9, certain assumed rhymes would require the same consonant for two tens digits.
Step 4 — A constrained solver and a held-out message
A new solver (anchor_coord) searches only coordinate tables. Without anchors it fails even on positive controls; with ten true anchors it recovers the whole key. We then enumerate the anchor sets compatible with H9 (97 out of 324) and test the most plausible. One stands out: D = {23 June 漾, 18 July 巧, 19 July 皓, 13 September 元}.
| Measure (anchor set D) | Archives | Shuffled (null) | Positive control |
|---|---|---|---|
| Score, corpus v4 | 705 | 349 | 1,203 |
| Score, corpus v5 (q ≠ g) | 829 | 332 | 1,216 |
| Reproducibility (3 seeds) | same optimum to within 0.001, 96/96 units agreeing | ||
The judge is message 0406, held out. We measure the mean log-likelihood gain per character under the language model, relative to an average character: positive if the decoding looks like Chinese, negative otherwise. Table D decodes it at +1.9 per character on corpus v4, then +3.47 on corpus v5, while every other candidate table stays at 0 or below and null tables give −1 to −2.5. In cross-validation (S7: tune on five messages, judge on the sixth), the table transfers to 6 messages out of 6. The text becomes readable phrase by phrase: 三十式槍、萬一千、軍用品已到門司、年息一割、無擔保、第二批械、軍務院、豫定計畫…
Step 5 — The G0 grid
Looking at the fitted table cell by cell, a regularity jumps out: the consonants follow reverse alphabetical order, two per tens digit, and the vowels go up then down. The few cells that deviate are those the data constrained poorly. So we replace the fitted table with the regular grid it approximates: G0, which has no free parameter left.
The result is the strongest test of the investigation: with no tuning at all, G0 decodes the held-out message 0406 at +3.99 per character, better than the fitted table it came from (+3.48). A table blurred by fitting does worse than the simple rule it was hiding: that is what you expect if the rule is the true key. G0 yields all 351 codes of the seven messages, and the message endings become consistent: signature 伸, then the day (漾 for 23 June, 巧 for 18 July, 元 for 13 September, 卅 for 30 September, 文 for 12 July).
Two endings looked anomalous. 19 July ends with 4210 instead of 皓 (4110): a single wrong letter, explained by the second channel (step 6). The message dated 30 June ends with 卄 (20); the reading was re-checked on the image, and the gap remains an encoding error, or drafting on the 20th for hand-in on the 30th.
Why believe it: the controls
| Criterion fixed in advance | Result |
|---|---|
| Positive controls of the same form recovered | Yes (1,203–1,216; keys recovered) |
| Archives clearly above the nulls | Yes (829 vs ≈ 335; 1,144 after re-reading) |
| Optimum reproducible from different starts | Yes (3 seeds, same optimum) |
| Held-out message readable without tuning (≥ +2.5 / character) | Yes: +3.99 under G0 |
| Continuous Chinese text, consistent with the dates on the forms | Yes for the most part; 12 doubtful characters out of 351 (plus 6 rare but confirmed) |
| Independent external cross-check | Yes: the sender 伸 = 趙伸, identified after decoding, in a 2026 study[7] describing the same arms contracts, then confirmed by the forms (Zhao Shen's name and address) |
| Second channel: held-out message readable under a closed key | Yes: 0496a at +4.62 under Y0, announcing Cai E's death at Fukuoka on the 8th |
| Second channel: dated endings outside the anchors match the form | Yes: 4 out of 4 |
That last point deserves emphasis: Zhao Shen's name, the delivery of the "second batch of weapons", the guarantee refused by Guangdong and the division of weapons between Yunnan and Guangdong appear in the decoded telegrams before Cheng Honglei's article was read. None of these words was injected into the search.
Limitations: G0 was read off a fitted table and Y0 deduced from five anchors; they did not fall from the sky; the last reading batches were not blind; and the translations are working translations.
Step 6 — The second channel and the Y0 grid
Another group of forms, without the name 文密, comes from the same sender: 15 forms from July to November 1916 between Tokyo and Yunnan, signed by Zhao Shen or addressed to him, which usually open with the clear indicator “Cg”. Their alphabet differs: y is a vowel, and G0 gives nothing. The rank test shows the same coordinate structure (consonants z ≈ 22, vowels z ≈ 5), but four rounds of annealing searches (E26 to E29), even with human readings and date anchors, stay negative: the solver recovers its positive controls perfectly, but the held-out message (0496a) stalls at +0.9 per character, far from the +2.5 threshold.
The breakthrough came from human reading of the headers and message endings:
- a telegram of 5 November (0489b) was sent in clear: 十號起程月末抵滇 伸 歌, "leaving on the 10th, arriving in Yunnan at the end of the month; Shen; the 5th". The enciphered telegram of the same day ends with
buky hary:buky= 伸 (0135),hary= 歌 (2960, rhyme of the 5th); - the one of 11 November ends with
foha= 尤 (1429, rhyme of the 11th).
These five values (bu = 01, ky = 35, ha = 29, ry = 60, fo = 14) fit exactly a linear syllabary: 17 consonants in alphabetical order without c, j or q, six vowels taken in serpentine order, and value = 6 × consonant rank + vowel rank. Only one choice was left open, the order of e and i; it was fixed by symmetry before any decoding (on the machine readings, the reverse variant gives +2.76 per character, against +4.23).
CONS = "bdfghklmnprstvwxz" # 17 consonants, no c, j, q
Y0 = {c + v: 6 * i + r for i, c in enumerate(CONS)
for r, v in enumerate("yuoiea" if i % 2 == 0 else "aeiouy")}
# 102 syllables: ze = 100 and za = 101 are unused
Results under Y0, with no tuning at all:
- the whole 1916 corpus: +4.5 per character on the human readings (454 codes; +4.23 on the first machine readings; for comparison, G0 on its held-out message: +3.99);
- message 0496a, held out of every earlier search and never used to establish Y0: +4.62 per character, and it announces the death of General Cai E at Fukuoka on the 8th [of November 1916]: an exact historical fact that nothing in the method could have suggested;
- message endings that were not used as anchors fall on the date written on the form: 篠 (17 July), 皓 (19 July), 齊 (8 September), 元 (13 September).
Two notes on the rules. Y0's anchors come from a plaintext telegram of the same day, that is, from a document, not from a guess. On the other hand, a "probable word" (電, "telegram") was tried: it was a declared departure from the no-crib rule, it brought nothing and was rejected (E29). Finally, the text of this channel has been fully re-read blind by a human, and the word count matches the one noted on the form everywhere; it nonetheless remains less certain than that of the first: many rare characters remain marked.
This channel also corrected the first: the Zhaoqing telegram of 19 July ended with an impossible code, while its Yunnan twin, sent the same day, ends properly with 伸皓 (the 19th). Re-read on the image, the faulty letter is an i instead of an e: in Morse, e is · and i is ··.
The open problem: the 1917 messages
The two enciphered telegrams of June 1917, 0509 and 0511 (Sun Yat-sen ↔ Dai Jitao), resist. They bear neither the 文密 prefix nor the “Cg” indicator, and their alphabet is different again (c and j present, y both consonant and vowel, a few atypical groups). Neither G0 nor Y0 reads them, and none of the table families tested since (grids of the same type, 17 or 18 × 6 tables in any order, coordinates with anchors, probable words) brings out anything beyond chance. The blind human reading, the possible confusions and all the leads are set out on the Telegrams page.
The tables recovered and their dates of discovery
Summary of the tables found during the investigation (October 2026), in the chronological order of the telegrams they read. For condensers, the construction reads: consonant order / vowel order / filling by vowel (V: value = 20 × vowel rank + consonant rank) or by consonant (C: value = 5 × consonant rank + vowel rank) / first number. Tables published by D. Bourdeau[1] are not listed.
| Table | Telegrams | Construction | Found on | Where to read it |
|---|---|---|---|---|
| Hong Kong | Hong Kong, March 1914 | y k u l o c a p i t → 0 1 2 3 4 5 6 7 8 9 | 15 October 2026 | Definition |
| “Laisaosang” | June 1914–February 1915 | c…b / o a e u i / V / 01 | 15 October 2026 | 1915 |
| “New York” | July 1914–February 1915 | b…z / a e i o u / C / 00 | 15 October 2026 | 1915 |
| “Hsuweilin” | San Francisco → “Hsuweilin”, July 1914 | b…z no k / a e i o u / C / 01 | 15 October 2026 | 27/7/1914 |
| candidate · “Kai” | Changchun and Shanghai, August–September 1914 | g…f / e o a u i / V / 01 | 15 October 2026 | 1914 (unpublished) |
| Rosamonde | English, Tokyo ↔ Shanghai, 1915–1916 | a↔u b↔g c↔s e↔o f↔j h↔y i↔r k↔z l↔t m↔w n↔v q↔x (reciprocal substitution) | 15 October 2026 | Rosamonde |
| “Thirtieth” | Shanghai ↔ Tokyo, February–May 1915 | v…t / u i e o a / V / 01 | 15 October 2026 | 1915 |
| “Thirteenth” | Tokyo → Shanghai, February–March 1916 | n…m / o a e i u / V / 01 | 15 October 2026 | 1915 |
| Sixteenth | Shanghai ↔ Tokyo, April 1916 | t…s / e u o i a / V / 01 | 15 October 2026 | Definition |
| Seventeenth | Shanghai ↔ Tokyo, April 1916 | p…n / i u a e o / V / 01 | 15 October 2026 | Definition |
| “Thirtyeight” | Tokyo → Shanghai, May 1916 | k…j / e a i u o / V / 01 | 13 October 2026 | May 1916 |
| Huang Xing | Tokyo ↔ Shanghai (“Ylchang”), late May – June 1916 | d c b t h j f q g k n m p s r l x w z v / u i o e a / C / 01 | 15 October 2026 | Huang Xing |
| G0 (“文密”) | Tokyo → Military Affairs Council, June–September 1916 | h g f d c b z y x w v t s r q p n m l k / a→u, u→a | 9 October 2026 | Step 5 |
| Y0 (“Cg”) | Tokyo ↔ Yunnan, July–November 1916 | 17 × 6 (y) / serpentine | 11 October 2026 | Step 6 |
The table distinguishes established tables from the “Kai” candidate, which is not a published decipherment. Periods cover attestations in the corpus, including the Unpublished batch.
Two of D. Bourdeau's tables were also confirmed or refined: his second “Manila” table, published as tentative, reads a telegram of 6 January 1915 without correction (15 October 2026); his “Honolulu” table reads the “Aloha” telegrams of April–May 1916 if w stands for v (13 October 2026).
1914: Hsuweilin and the “Kai” candidate
The July 1914 – January 1915 file of the same series (JACAR B03050087500) holds some ten condenser telegrams, often preceded by a clear word serving as indicator (“Ting”, “Kai”, “Sixth”, “Chung”). The same tests as for 1915 (the full family of condenser tables, the known keys, six shuffled controls) gave, on 15 October 2026:
- two of D. Bourdeau's tables[1] already in use in 1914: “Sixth” reads with his “San Francisco” table (Lin Sen, San Francisco, 18 September 1914: a request for a transfer of 200 dollars; 4.41 per code against 0.44 at best for the controls), and “Ting” (Changchun, 31 July 1914) with his “Shanghai” table (3.66 against 1.84);
- “Hsuweilin”, a new table (San Francisco → “Hsuweilin”, 27 July 1914): consonants
b c d f g h j l m n p q r s t v w x y z(nok), vowelsa e i o u, filled by consonant, starting at 01; 3.61 against 0.98: “yesterday, moved to the Pacific coast…; the address for letters is unchanged”; - “Kai”, a candidate table (Changchun, 9 August 1914; Shanghai, 23 September 1914): consonants starting from
g, vowelse o a u i, filled by vowel, starting at 01; 3.01 against 1.61 and 1.73 against −0.46. The reading is still partial (very faulty copies).
The messages marked “Chung” remain unreadable. Uncorroborated candidate: the best “Kai” gap is 3.01 − 1.61 = 1.40, below the publication threshold of 1.5. Both texts remain outside the corpus; no identity is assigned to the indicator.
Additional tables: a complete recipe for each reading
The 1913–1916 batch adds specific tables for two different procedures. A condenser converts a consonant–vowel syllable into two digits; Hong Kong replaces each letter with one digit. Four digits then identify a character in the public telegraph code. A message already written as numbers reads directly in that codebook; this alone is not evidence of secret encipherment.
Sixteenth and Seventeenth: filling by vowel
The base consonant list is b c d f g h j k l m n p q r s t v x y z. Rotate it left by 15 positions for Sixteenth and 11 for Seventeenth. With zero-based consonant rank i in the rotated list and vowel rank j in the table’s order, a syllable is (20 × j + i + 1) modulo 100, formatted as two digits. Concatenate two syllables without adding them. Example under Sixteenth: xe·qu → 03·38 → 0338 → 兄, opening the telegram of 19 April 1916.
| Table | Consonants in table order | Vowels | Formula |
|---|---|---|---|
Sixteenth | t v x y z b c d f g h j k l m n p q r s | e u o i a | (20 × j + i + 1) modulo 100 |
Seventeenth | p q r s t v x y z b c d f g h j k l m n | i u a e o | (20 × j + i + 1) modulo 100 |
Hsuweilin: filling by consonant
Consonants: b c d f g h j l m n p q r s t v w x y z (no k); vowels: a e i o u. The formula is (5 × i + j + 1) modulo 100. Thus gu·ca → 25·06 → 2506 → 昨 opens the telegram of 27 July 1914. Its alphabet differs from Sixteenth’s; preserve each list exactly.
Hong Kong: one letter, one digit
Use y k u l o c a p i t → 0 1 2 3 4 5 6 7 8 9. Join the transmission groups and split into four-letter blocks. Example: kcpk → 1571 → 已 on 13 March 1914. These are not condenser syllables. Incorrect lengths remain copying problems; a proposed alignment does not become an observed letter.
Controls remain separate from reconstruction
Publication requires a score per code ≥ 1.5 and strictly above the shuffled control + 1.5, an established table, intelligible text and applied human review. Readability is checked separately: the Kai message of 23 September 1914 remains a draft, while 9 August fails the required margin (3.013 − 1.613 = 1.400). Neither is published. Initial scores and alignment hypotheses remain separate in the manifest; doubtful passages and inserted letters remain visible.
The nine 1915 additions introduce no new solver. Thirtieth now reads February–May 1915; Shanghai is attested in June and San Francisco in October 1915 with the published tables [1]. Prefilled review R23 was followed by R24 on marked characters; rejection or indecision was not turned into confirmation. The series has twenty telegrams, 446 codes, 53 doubtful characters and 1 illegible. The two Rosamonde additions, 6 and 7 March, use the procedure already described: reviewed qq stays in the cipher and [pp] in the English reading records the use of q for p attested in 1915.
Three more tables: 1915
The 1915 volumes of the same series (JACAR B03050087600 and B03050087700)[17] had never been opened. They contain condenser telegrams a year older than those of 1916. For each one, we ran the complete family of condenser tables (604,800 tables: twenty consonants in alphabetical or reverse order, starting point, order of the five vowels, filling by consonant, by vowel or in a serpentine, start at 00 or 01) and compared the best score with those of six controls, the same syllables shuffled. Three tables stand out clearly, each readable on several telegrams:
- “Laisaosang” (Tokyo ↔ Shanghai, January–February 1915): consonants in alphabetical order from
c(withoutw), vowelso a e u i, filled by vowel, starting at 01. 2.90 per code against at best 0.23 for the controls; the same table reads a telegram from Shanghai in the other direction (2.77 against 0.96). - “New York” (New York → Sun Yat-sen, February 1915): the simplest table in the family — consonants
btozin alphabetical order (pandqmerged), vowelsa e i o u, filled by consonant, ba = 00. Found independently on two telegrams; 3.90 and 4.74 per code. - “Thirtieth” (Shanghai ↔ Tokyo, February–May 1915), announced in clear by that word: consonants from
v, vowelsu i e o a, filled by vowel, starting at 01. 6.24 per code against 1.73, with no correction at all, on the telegram of 27 February. Like “Thirtyseventh” and “Thirtyeight” in 1916, the ordinal probably designates a table in a list.
Finally, on 6 January 1915 a telegram from Tokyo to “Konglipo” (Manila) reads without correction with the table that Daniel Bourdeau had proposed, tentatively, from a single telegram of May 1916[1]: 無其事。文覆 (“There is nothing of the sort. — Wen, replying”). That table was therefore in use sixteen months earlier.
Claude read the letters on the scans, then I reread the doubtful points blind (a batch of 77 questions, including 10 control syllables, all confirmed; I found 15 of the 22 proposed corrections without knowing which were expected). The telegrams are on the Telegrams page.
A fourth new table is used in March 1916 between Tokyo and Shanghai: “Thirteenth”, announced in clear by that word on a telegram of 28 February 1916: consonants from n, vowels o a e i u, filled by vowel, starting at 01. It reads the telegrams of 12 and 16 March 1916 (4.83 and 4.52 per code) and that of 28 February itself (4.40), in which an English word is left in clear in the middle of the cipher: 正金銀行 bearer 票, bearer notes of the Yokohama Specie Bank; see February–March 1916.
Rosamonde: English under a reciprocal substitution
In the same volumes, and in May 1916 in file B03050089000[16], other telegrams do not look like condensers: ten-letter words without consonant–vowel alternation, with consonant clusters and doubled vowels. The keyless test is negative (this is not a syllable table), but three statistics point the way: the index of coincidence of the letters is 0.062, that of a natural language (0.038 for random letters); f and q never occur; trigrams recur from one telegram to another (hea, ten times). This is the signature of a simple substitution on natural-language text.
Simulated annealing over all 26-letter substitutions, scored by an English quadgram model, brings out English at the first attempt (your letter, received my life, cable). The table found is almost an involution (each letter swapped with another); restricting the search to reciprocal substitutions fixes the key: a↔u b↔g c↔s e↔o f↔j h↔y i↔r k↔z l↔t m↔w n↔v q↔x, d and p unchanged. hea = you, teno = love. The table above describes the base substitution. The 1915 forms also attest q in place of the cipher letter expected for p, notably the reviewed qq of 6 March, rendered [pp] in the reading. This usage is recorded without silently changing the reciprocal table.
Three checks. (1) An English text of the same length, enciphered with a random table, is recovered at 100 % by the same search. (2) Out of sample: the key taken from the 1915 telegrams alone reads the seven telegrams of May 1916, which I had transcribed blind before the discovery (z = 7.5 against 2,000 random reciprocal tables). (3) My blind rereading of the 1915 telegrams (50 lines, without seeing either Claude's reading or the plaintext) reads just as well (z = 10.9). A telegram in another system stays unreadable (z = 0.6). The content — a love correspondence between Sun Yat-sen and Soong Ching-ling — is presented on the page The Rosamonde telegrams.
Why so many corrected letters in May 1916?
In the edition, letters in brackets are those that the form gives differently, or leaves out. They are three times more frequent in May 1916 (109 of 611, 17.8 %) than in 1915 (59 of 1,061, 5.6 %); the telegram of 12 May, on two sheets, accounts for half of them (56 of 234). I checked each of these letters on the images, with the expected letter in view (15 October 2026): of 133, 99 are indeed written differently on the form, 18 can be read as the expected letter, 16 remain uncertain. These statistics and the comparisons below concern the initial sample checked on 15 October 2026; they exclude the additions of 6 and 7 March 1915.
Method explains almost nothing. The 1915 edition combines two independent readings, the 1916 one my reading alone; but with the reader held constant — my blind reading of 1915 on its own —, the gap with the expected cipher is about 7 % in 1915, against 18 % in 1916. The 1916 forms are less faithful, and the gaps concentrate on three pairs of letters:
| expected letter | 1915 (my blind reading) | May 1916 (checked on the image) |
|---|---|---|
| v (plain n) | v 41 times of 47 | v 18 times, n 23 times |
| r (plain i) | r 51 times of 51 | r 7 times, i 24 times |
| h (plain y) | h 46 times of 47 | h 16 times, y 7 times |
These errors do not come from transmission: in Morse, n and v, i and r, h and y have nothing in common. They arise when someone reads cursive handwriting — most likely the counter clerk copying the sender's handwritten message — and they nearly always go the same way: an expected v becomes n, never the reverse; an h becomes y, never the reverse. Two causes are possible, and we cannot decide between them. Telegrams written in haste: in May 1916 Sun was leading the rising from Shanghai (“now very busy”), and the encipherment itself is more careless, with whole words left in clear (know, own, iron, trunk) and even half a word (anxi-ous). Or other clerks: in Shanghai, telegraphists reading a Latin hand that was not their own; yet Ching-ling's two telegrams sent from Tokyo show the same faults.
The key makes things worse: it swaps precisely letters that look alike (a/u, c/s, e/o, h/y, i/r, l/t, n/v…), so the slightest hesitation of the pen yields a letter that looks plausible but is wrong for deciphering. The 1916 key is indeed that of 1915: a variant first found by automatic search (v↔p, n, i and r unchanged) was only an effect of these errors; it is contradicted by every plain v, which the form writes n and never p.
As far as we know, neither this system nor these texts had been published: they are absent from Daniel Bourdeau's notes[2], from Cryptiana[8], from the historiography of the marriage[18][19] and from the biography by J. Chang and J. Halliday[20] (checked on 15 October 2026).
Follow-up: May–June 1916, a known key on new telegrams
Here the key is not new: the Tokyo → Shanghai (“Junzaburo”) telegrams of May 1916 are enciphered with the “Yamada” condenser, already identified and published[1, 2]. What is new is the telegrams themselves. The published transcriptions stop at JACAR file B03050089100 (late May); opening the following batches from the Ministry of Communications (B03050089000, B03050089200, B03050089400), I found ten telegrams of the same series, from 17 May to 15 June, never transcribed.
The method is the rest of the investigation run in reverse: with the key known, everything rests on reading the letters. Claude read each form on the scan; where a character made no sense, it looked for the letter or letters which, changed one at a time (copyist or Morse confusion), gave a sensible text; I then checked them on the image one by one, knowing what was sought (batches V1–V6, about 40 points: the great majority confirmed, a few rejected and left as doubtful). Checks independent of the key: the date rhyme matches the form, the signature 持 (Xie Chi) recurs, and the people named (席正銘, 趙瑾卿, 廖仲愷, 居正, 萱野) are real and from the right circle. Result: see the Telegrams page.
Early May 1916: the replies from Shanghai. Besides the Tokyo telegrams, the early-May batch contains replies from Shanghai to Tokyo: they read with the same “Yamada” key, used the other way, and one is signed 文. It also contains a Manila telegram relayed to Shanghai, read with the Manila-to-Tōyama key already published[1]. The doubtful words were checked against the image by Brice Dudout.
The “w” of 10 May: a deliberate reading, and a lead. On the form of 10 May (0042a), the encipherer twice writes w where the “Yamada” table expects a p (“xetuwotedi”, “rusidewari”), while the same form also uses p. There is no w in the “Yamada” alphabet (twenty consonants, no w), and it is not a plausible slip of the pen. We therefore treat it as a deliberate choice: w is a second form of p (a homophone), and the Telegrams page reads this telegram with the “Yamada” table in which w equals p; the letters are shown as written. Of the twenty possible values for w, that of p is clearly the best, and the only one that gives 「昨日到」 and 「乘原船」; the rest of the table is unchanged (the signature 持 and the date 灰, the 10th, come out right). Two ks on the same form also seem to stand for p (事, 灰): they remain proposals. The w lead subsequently produced a result: Tokyo telegrams without an indicator and Shanghai telegrams to “Ylchang” yielded the Huang Xing table, whose consonant order is indeed permuted. Some messages remain unreadable with it, as specified in that section. G0 instead follows a reversed alphabet, described above.
Honolulu: an “Aloha” variant of the key. The Honolulu telegram of 30 April (clear prefix “Aloha”, addressed to “Rosamonde”, that is, Sun Yat-sen) uses a w, absent from the condensers’ alphabet, alongside v. It reads with the “Honolulu” key already published[1] when w is given the value of v: a second form of the same letter, like the w for p on 10 May. We present it as an “Aloha” variant of that key. The telegram is signed 鐵城 (Wu Tiecheng, then in Honolulu) and reads 「黃轉到日,換船赴滬。鐵城」 (“Huang [Xing] is going on to Japan and will change ship there for Shanghai”). Three letters are corrected as transmission errors (twice s received for r, once o for e); the first character, 黃, is restored from the context: Huang Xing reaches Japan on 9 May (telegram 0042a).
Two streams of the same period seemed to resist: Tokyo telegrams without the “Thirtyseventh” prefix, which share repeated letter sequences, and those from Shanghai to “Ylchang” (Huang Xing). They in fact read with one and the same new table: see Huang Xing's table.
A new table: “Thirtyeight” (May 1916)
Two Tokyo telegrams of early May carry a different clear prefix, “Thirtyeight” instead of “Thirtyseven”. The key-free test shows a table of the same type (two letters → two digits), but the “Yamada” key does not read them. A search over the family of condenser tables (starting consonant, vowel order and direction, offset: 57,600 tables) puts one clearly ahead (z = 6.7): consonants in alphabetical order starting at k, vowels e a i u o, value = 20 × vowel rank + consonant rank + 1 (modulo 100). It is the “Yamada” construction (consonants from q, vowels e u i o a) with other parameters. It reads the telegram of 12 May without changing a single cell: 「箱已交犬塚,十五日附法船來。若有要事,請電如下」 (“the box has been handed to Inuzuka; it will leave on the 15th by a French ship; for any urgent matter, telegraph to…”), followed by an address in clear; only one letter is corrected (d → x, a copying confusion already seen elsewhere). As far as we know, this table had not been published. It also reads the second “Thirtyeight” telegram, of 11 May: 「聞張繼已回日,頗奇,是否?」 (“I hear that Zhang Ji has returned to Japan; that is very surprising — is it true?”), with one letter corrected (o → e).
A second new table: Huang Xing's table (late May – June 1916)
From 26 May to 6 June 1916, telegrams left Tokyo for “Junzaburo” (Shanghai) without the “Thirtyseven” prefix. No known table read them[2], [8], but two observations guided the search. The telegram of 6 June repeats the end of the one of 3 June, code for code, restoring nine codes lost in transmission. And three telegrams end with the same two codes whatever their date: not a date (like Xie Chi's “持” followed by the day rhyme), but a closing formula and a signature.
Not to be confused with the three-kana code of another telegram of Huang Xing (25 May 1916, to Lin Hu and Li Genyuan), whose system was identified by D. Bourdeau and whose formula by S. Tomokiyo[22][23].
The keyless test showed a coordinate table (the consonant carries the tens digit). We therefore searched, by simulated annealing, for a table in which each of the twenty consonants occupies a block of five consecutive values, in any order, with the vowels in a common or alternating order. The search was calibrated first: telegrams already read, re-enciphered with a random table of this family, were recovered in full (12 out of 12). On six Tokyo telegrams (140 codes), all six independent runs reach the same table, far above the control (the same syllables shuffled): 4.26 against 0.73 per code.
The table is remarkably regular: consonants in the order d c b t h j f q g k n m p s r l x w z v, each on five consecutive values numbered 01 to 99 then 00 (du = 01, di = 02 … va = 00), vowels in the order u i o e a. The Tokyo telegrams all end with 覆。興 (“reply. — Xing”): Huang Xing, in Tokyo since 9 May. Without changing a single cell, the same table also reads telegrams from Shanghai to “Ylchang” (Huang Xing) signed 文 or 孫文 (Sun Yat-sen); the one of 6 June ends with the date 魚, the 6th, that of the form.
What they say: on 3 June Huang Xing saw Tanaka (田中, presumably Tanaka Giichi, vice-chief of the General Staff): 「槍二千、砲六門不日可運」, 2,000 rifles and 6 guns can be shipped shortly; on 31 May, 200,000 in funds and arms, and Hu Hanmin (漢民) asked to request Aoki (青木) to intervene again with the authorities; [the Japanese] do not wish Sun to rush to Shandong, and Huang suggests mediation by Zhang Ji (溥泉) and a respected military man. Nine telegrams are read; the doubtful letters were checked on the forms by Brice Dudout (reading blind to the meaning), and the telegrams are given on the Telegrams page. Two telegrams from Shanghai to “Ylchang” (29 May and 8 June), from another sender (same opening and closing codes), do not read with this table.
As far as we know, this table had not been published: these telegrams are listed as unread in Daniel Bourdeau's notes[2] and on Cryptiana[8] (checked on 15 October 2026).
Tools
- Sources: public JACAR PDFs[3]–[6]; Chinese telegraph code tables (Unicode Unihan, fields
kTaiwanTelegraphandkMainlandTelegraph)[10]. - Language corpus: Sun Yat-sen's writings on Wikisource[12], 1916 telegrams from the Sunology site[11];
jiebasegmentation[14]; character variants via OpenCC[13]. - Computation: Python 3 (NumPy) for tests, preparation and scoring; C++17 solvers (
clang++ -O3 -march=native -pthread) using simulated annealing and iterated local search:anchor_sa,anchor_arr(arrangements, carry and ±111 offset),anchor_coordandanchor_coord6(coordinate tables). An 8-core laptop is enough. - Reading: local HTML blind-reading interface (anonymous shuffled excerpts, JSON export) and a script to merge readings.
- A human–AI collaboration: I ran the investigation with Claude (Anthropic) — Claude Opus 5.5 from session C14, Claude Fable 5.1 for session C31, the one of the decipherment; the very first sessions (C01–C13) had been done with Codex. Claude wrote the solvers, the tests and the log, and proposed hypotheses and controls; I read the ciphertext on the images, settled the readings, chose the leads and the criteria, and wrote these articles with it.
The solver, both keys, the reading data and the language model are published in the solver/ folder of the GitHub repository, with everything needed to re-run the search; the full investigation log will follow.
