SHIROのIchigoJam日記

マイコン「IchigoJam」(イチゴジャム)の電子工作とプログラミングをメインに

エニグマ暗号機

★この記事は「IchigoJam Advent Calendar 2020」にエントリーしています。

先日公開した「かんたん暗号作成」プログラムをさらに発展させて、第2次世界大戦中にドイツ軍が使った暗号機「エニグマEnigma)」を再現してみました。
f:id:shiro0922:20201220072903p:plain

使い方

  • 起動すると「Rotor Set No.=?」と聞かれるので、換字ローターをセットする初期値(数字)を入力します。その後、ローターをセットする間待たされます。(IchigoJam実機で数秒、IchigoJam webで10秒ほど)
  • 「KEY INPUT (A-Z)?」と聞かれるので、原文の文字列を1文字ずつ入力します(A~Zの範囲。それ以外の文字は無視されます)。その下の行に暗号文が1文字ずつ表示されます。終了する時はEnterキーを押してください。
  • エニグマは暗号化だけでなく、原文に戻す復号化もできます。同じローター初期値を設定して、暗号文を入力すると、原文が出てきます。

プログラム

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

IchigoJam web版はこちら。

エニグマでの暗号化

エニグマ暗号機の内部には、回転するローターが3個、反転ローター(固定)が1個あります。
f:id:shiro0922:20201220211041p:plain
キーボードで入力した文字は、①ローター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番の回転を処理。

参考資料

プログラム作成に当たって、以下のページを参考にさせていただきました。