From 8d95667cd625f679bd849ad636cf6a55f87e98b5 Mon Sep 17 00:00:00 2001 From: ipusiron Date: Fri, 9 Oct 2026 16:23:49 +0900 Subject: [PATCH] =?UTF-8?q?README:=20=E6=B4=BB=E7=94=A8=E4=BE=8B=E3=81=AE?= =?UTF-8?q?=E5=85=88=E9=A0=AD=E3=81=AB=E3=80=8C=E3=81=93=E3=81=AE=E3=83=84?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=81=AA=E3=82=89=E3=81=A7=E3=81=AF=E3=81=AE?= =?UTF-8?q?=E4=BD=BF=E3=81=84=E6=96=B9=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🎯ユースケース節を新設(人形でも単一換字式、旗が語の区切り、26文字が1対1+一般の用途) - 暗号化・旗・文字数をtest/readme.test.jsでencryptText()から再計算 - 日英とも同じ位置に追加し、数値は readme.test で計算部から再計算する Co-Authored-By: Claude Opus 5.5 --- README.en.md | 14 ++++++++++++++ README.md | 14 ++++++++++++++ test/readme.test.js | 14 ++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/README.en.md b/README.en.md index 1fb391e..0f399b7 100644 --- a/README.en.md +++ b/README.en.md @@ -210,6 +210,20 @@ the substitution table, the sample list and the status messages together. --- +## 🎯 Use cases + +### Ways of using this tool in particular + +- Confirming that it is a simple substitution despite the figures (frequency-analysis classes): each letter maps to one dancing figure. Encrypting HELLO makes the same "L" the same figure twice, so repeated letters appear as repeated figures. Behind the exotic look it is a simple substitution, and you can confirm that counting the figures lets frequency analysis work +- Confirming that a flag marks word boundaries and leaks word lengths (cryptanalysis classes): the last figure of each word carries a flag. Encrypting HELLO WORLD raises a flag on the O at the end of the first word (the 5th letter). You can confirm that showing word breaks with a flag leaks the clue of word length and helps decryption (the same idea by which Sherlock Holmes started from short words) +- Confirming that all 26 letters map one to one to figures (substitution classes): each of the 26 letters of the alphabet is assigned one fixed figure. Since letters and figures are one to one, you can always turn a figure back into its letter. Behind the pictures it is a fixed substitution table with no key + +### General uses + +- Learn how the Dancing Men cipher (Sherlock Holmes) works in class or self-study +- Make figure ciphertext (SVG or image) to hand out at puzzles and events +- Use it as a subject for frequency analysis of a simple substitution cipher + ## 🔒 Security and privacy - A meta CSP allows scripts, styles and images from the same origin only. No inline handler and no `style` attribute is used diff --git a/README.md b/README.md index 59bc08c..b3b1f59 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,20 @@ JavaScriptが表示する文言は`dancingmen-messages.js`の辞書から`t`で 入力欄の内容と復号中の人形は残ります。 --- +## 🎯 ユースケース + +### このツールならではの使い方 + +- 見た目が人形でも単一換字式だと確かめる(頻度分析の授業):1文字が1体の踊る人形に対応する。HELLOを暗号化すると、同じ「L」が同じ人形に2回なり、くり返す字がくり返す人形で現れる。派手な見た目でも中身は単一換字式で、人形の出現頻度を数えれば頻度分析が効くことを確かめられる +- 旗が語の区切りを示し、語の長さが漏れることを確かめる(暗号解読の授業):各語の最後の人形には旗が付く。HELLO WORLDを暗号化すると、1語目の最後のO(5文字目)に旗が立つ。旗で語の切れ目がわかると、語の長さという手がかりが漏れ、解読を助けることを確かめられる(シャーロック・ホームズが短い語から解いたのと同じ考え方) +- 26文字すべてが人形に1対1で対応することを確かめる(置換の授業):アルファベット26文字のそれぞれに、決まった1体の人形が割り当てられている。文字と人形が1対1なので、人形から元の文字へ必ず戻せる。見た目は絵でも、鍵のない固定の置換表だと確かめられる + +### 一般的な使い方 + +- 踊る人形暗号(シャーロック・ホームズ)のしくみを授業や自習で学ぶ +- 謎解きやイベントで、人形の暗号文(SVG・画像)を作って配る +- 単一換字式暗号の頻度分析の題材にする + ## 🔒 セキュリティ - meta CSPで同一オリジンのスクリプト・CSS・画像だけを許可。インラインイベントとstyle属性は不使用 diff --git a/test/readme.test.js b/test/readme.test.js index 89f322e..f71acc6 100644 --- a/test/readme.test.js +++ b/test/readme.test.js @@ -81,3 +81,17 @@ test("README obsolete claims and non-existent code examples are absent", () => { assert.ok(!readme.includes(obsolete), obsolete); } }); + +test("ユースケースの「このツールならではの使い方」を dancingmen-logic.js で再計算(日英)", () => { + const { encryptText, LETTERS } = require("../dancingmen-logic.js"); + const en = fs.readFileSync(path.join(root, "README.en.md"), "utf8"); + const hello = encryptText("HELLO")[0]; + assert.deepEqual(hello.map((t) => t.letter), ["H", "E", "L", "L", "O"]); + assert.equal(hello[2].letter, hello[3].letter); + assert.equal(hello.filter((t) => t.letter === "L").length, 2); + const hw = encryptText("HELLO WORLD")[0]; + assert.equal(hw[4].letter, "O"); + assert.equal(hw[4].flag, true); + assert.equal(LETTERS.length, 26); + for (const md of [readme, en]) assert.ok(md.includes("HELLO WORLD") && md.includes("26")); +});