★この記事は「IchigoJam Advent Calendar 2020」にエントリーしています。
先日公開した「かんたん暗号作成」プログラムをさらに発展させて、第2次世界大戦中にドイツ軍が使った暗号機「エニグマ(Enigma)」を再現してみました。
使い方
プログラム
10 CLV:?"***ENIGMA***" 20 INPUT "Rotor Set No.=?",S 30 SRND S 40 FOR R=0 TO 2 50 Q=R*26 60 FOR I=0 TO 25 70 [Q+I]=I 80 NEXT 90 FOR I=1 TO 100 100 A=RND(26):B=RND(26) 110 C=[Q+A]:[Q+A]=[Q+B]:[Q+B]=C 120 NEXT 130 NEXT 140 ?"*KEY INPUT (A-Z)?" 150 @KLOOP 160 K=INKEY():IF !K CONT 170 IF K=10 ?:?:END 180 K=K-65 190 IF K<0 OR K>25 GOTO @KLOOP 200 ?CHR$(K+65,10,23); 210 FOR R=0 TO 2 220 K=[R*26+K] 230 NEXT 240 K=25-K 250 FOR R=2 TO 0 STEP -1 260 S=R*26 270 IF [S]!=K S=S+1:CONT 280 K=S-R*26 290 NEXT 300 ?CHR$(K+65,30); 310 R=0:GSB @ROT 320 GOTO @KLOOP 330 @ROT 340 Q=R*26:A=[Q] 350 FOR I=0 TO 24 360 [Q+I]=[Q+I+1] 370 NEXT 380 [Q+25]=A 390 [100+R]=[100+R]+1 400 IF [100+R]=26 [100+R]=0:IF R<2 R=R+1:GSB @ROT 410 RTN
エニグマでの暗号化
エニグマ暗号機の内部には、回転するローターが3個、固定された反転ローターが1個あります。
キーボードで入力した文字は、①ローター1→②ローター2→③ローター3→④反転ローター→⑤ローター3→⑥ローター2→⑦ローター1と合計7回変換され、ランプボードで変換後の文字ランプが点きます。
また、3個のローターは1文字変換するごとに回転します。
- 1文字変換すると、ローター1が1目盛り回転
- ローター1が1周(26目盛り)回転すると、ローター2が1目盛り回転
- ローター2が1周(26目盛り)回転すると、ローター3が1目盛り回転
つまり、変換に使われる換字表の組み合わせが1文字ごとに変わります。そのため、例えば「AAA」と同じ文字を連続して入力しても、同じ文字に変換されるとは限りません。
上図のように内部で反転して戻る回路になっているため、暗号化と複合化が1台の機械でできます。
例えば、原文の「A」が暗号文の「S」に変換されたとすれば、同じローター配置で「S」を入力すれば「A」に変換されます。
実機のエニグマでは、電気回路の設計上「A」→「A」と同じ文字に変換されることは無いのですが、このプログラムではそうした制限はありません。
ドイツ軍の実際の運用では、5個以上のローターを用意して、日によって使うローター・入れる順番・初期位置を変えていました。(このプログラムでは、最初の「Rotor Set No.」入力がその設定だと思ってください)
また、実機のエニグマには上記のローターに加えて、特定の文字を交換するプラグボードがありましたが、このプログラムでは実装していません。
プログラム説明
- 20~30行…ローターの初期値を入力して、SRNDで乱数を初期設定。
- 40~130行…ローター3個(プログラム内では0番~2番)の初期設定。60~80行でA~Z(0~25)を順に配列変数へセットし、90~120行で乱数で取り出した配列2個の値を交換×100回して、ランダムなローターに。
- 150~200行…文字入力と画面表示。A~Z以外の文字は無視。Enterキー(文字コード10)が入力されたら終了。200行の表示では、文字コード10(改行)+文字コード23(行末移動)で、下の暗号文の行末へカーソル移動。
- 210~300行…文字変換。上図で言うと、210~230行がローター変換①②③、240行が反転ローター④、250~290行がローター逆変換⑤⑥⑦(換字表配列を逆引きして変換)、300行で変換後の文字を表示。
- 330~410行…ローターの回転処理サブルーチン。26目盛り回転ごとに再帰呼び出しして、ローター0番~2番の回転を処理。