This module is part of the original MMBasic library. It is reproduced here with kind permission of Hugh Buckle and Geoff Graham. Be aware it may reference functionality which has changed or is deprecated in the latest versions of MMBasic.¶
Note: Any required file(s) are available in the attachments tab (top right).
ENIGMA.BAS
'ENIGMA for Maximite
'written by Ray Alger April 2015
'Output file added by Hugh Buckle May 2015
OFileName$="EnigOut.txt"
Dim RD$(10):Dim D$(4):Dim R(4):Dim V(5):Dim RS(4):Dim RP(4)
Dim PB(26):Dim PBD(26):Dim PBS(26):Dim REF(26):Dim KO(8,2)
Dim ROT$(10):Dim REF$(2):Dim FOR0(26):Dim REV0(26):Dim FOR1(26)
Dim REV1(26):Dim FOR2(26):Dim REV2(26):Dim FOR3(26):Dim REV3(26)
'Rotor display data
RD$(1)=" I ":RD$(2)=" II ":RD$(3)=" III":RD$(4)=" IV ":RD$(5)=" V "
RD$(6)=" VI ":RD$(7)=" VII":RD$(8)="VIII":RD$(9)="beta":RD$(10)="gamm"
'rotor knock on data
KO(1,1)=16:KO(2,1)=4:KO(3,1)=21:KO(4,1)=9:KO(5,1)=25
KO(1,2)=16:KO(2,2)=4:KO(3,2)=21:KO(4,2)=9:KO(5,2)=25
KO(6,1)=25:KO(7,1)=25:KO(8,1)=25
KO(6,2)=12:KO(7,2)=12:KO(8,2)=12
'Rotor data
ROT$(1)="EKMFLGDQVZNTOWYHXUSPAIBRCJ" 'I
ROT$(2)="AJDKSIRUXBLHWTMCQGZNPYFVOE" 'II
ROT$(3)="BDFHJLCPRTXVZNYEIWGAKMUSQO" 'III
ROT$(4)="ESOVPZJAYQUIRHXLNFTGKDCMWB" 'IV
ROT$(5)="VZBRGITYUPSDNHLXAWMJQOFECK" 'V
ROT$(6)="JPGVOUMFYQBENHZRDKASXLICTW" 'VI
ROT$(7)="NZJHGRCXMYSWBOUFAIVLPEKQDT" 'VII
ROT$(8)="FKQHTLXOCBJSPDZRAMEWNIUYGV" 'VIII
ROT$(9)="LEYJVCNIXWPBQMDRTAKZGFUHOS" 'beta
ROT$(10)="FSOKANUERHMBTIYCWLQPZXVGJD" 'gamma
'Reflector data
REF$(1)="ENKQAUYWJICOPBLMDXZVFTHRGS" 'Thin B
REF$(2)="RDOBJNTKVEHMLFCWZAXGYIPSUQ" 'Thin C
'Plug board data
PB$ ="QWERTZUIOASDFGHJKPYXCVBNML"
For J=0 To 25:PBD(J)=Asc(Mid$(PB$,J+1,1))-65:Next J
DAY$="C VI I VII XEL ML YE JH WQ"
TRI$="JEX GFE"
CIPHER$="YKDMD SZZPA BFCMJ EZIGN MSROU GPDSO HHSIU JJLSC NBBTY UOTX"
Function MOD26(X)
X=Cint(X) 'fix error
X=26*(X/26-Int(X/26))
If X<0 Then X=X+26
MOD26=X
End Function
'Screen setup
START: Cls:Print" ********** Maximite M4 ENIGMA **********"
Print@(0,15)"REFLECTOR ->"
Print@(0,30)"ROTORS USED -->"
DP=30
GoSub DRAW
Print@(0,60)"RING SETTINGS ->"
DP=60
GoSub DRAW
Print@(20,120)"ROTORS -->"
DP=120
GoSub DRAW
Line(125,95)-(130,155),,B:Line(175,95)-(180,155),,B
Line(225,95)-(230,155),,B:Line(275,95)-(280,155),,B
For J=1 To 6
L=J*10
Line(126,90+L)-(129,90+L):Line(176,90+L)-(179,90+L)
Line(226,90+L)-(229,90+L):Line(276,90+L)-(279,90+L)
Next J
Line(1,325)-(330,390),,B
Print@(36,385)"PLUG BOARD"
For J=0 To 25:PB(J)=J:Next J 'Init Plug array
For J=0 To 25:PBS(J)=0:Next J 'Init Plug status
GoSub SHOW
Line(1,175)-(331,240),,B
Print@(36,235)"LAMP BOARD"
CODE=26 'no lamp
GoSub LAMP
GoSub REFSET
GoSub ROTSET
GoSub RINGSET
GoSub PLUGSET
GoSub SETROT
'HFBmod 20150509 start - add output file
gosub OpenOutFile
'HFBmod 20150509 end
'rotor offset arrays
For J=0 To 25
T=Asc(Mid$(ROT$(R(0)),J+1,1))-65
U=Asc(Mid$(ROT$(R(1)),J+1,1))-65
V=Asc(Mid$(ROT$(R(2)),J+1,1))-65
W=Asc(Mid$(ROT$(R(3)),J+1,1))-65
FOR0(J)=T-J
REV0(T)=J-T
FOR1(J)=U-J
REV1(U)=J-U
FOR2(J)=V-J
REV2(V)=J-V
FOR3(J)=W-J
REV3(W)=J-W
Next J
'knock on data
KO3A=KO(R(3),1):KO3B=KO(R(3),2)
KO2A=KO(R(2),1):KO2B=KO(R(2),2)
'refelector data
For J=0 To 25:REF(J)=Asc(Mid$(REF$(RF),J+1,1))-65:Next J
Print@(0,250)"Text IN-"
Print@(0,280)"Text OUT-"
CLRPAD: PL$="":CI$="":CCNT=0:TB=0
Print@(0,265)" "
Print@(0,295)" "
Print@(0,410,2)"Enter text, Press[Esc] to change settings "
ENCRYPT:
TB=TB+1:If TB>60 Then GoTo PADFUL
GoSub LETTER
If K=27 Then GoTo ESCAPE
If K>25 Then GoTo ENCRYPT
'rotor steps
If RP(3)=KO3A Or RP(3)=KO3B Then GoTo ADV2
If RP(2)=KO2A Or RP(2)=KO2B Then GoTo ADV1 ' R2 double step
GoTo ADV3
ADV1: RP(1)=RP(1)+1
If RP(1)>25 Then RP(1)=RP(1)-26
ADV2: RP(2)=RP(2)+1
If RP(2)>25 Then RP(2)=RP(2)-26
ADV3: RP(3)= RP(3)+1
If RP(3)>25 Then RP(3)=RP(3)-26
'rotor display
DP=120:D$(1)=" "+Chr$(RP(1)+65)+" "
D$(2)=" "+Chr$(RP(2)+65)+" ":D$(3)=" "+Chr$(RP(3)+65)+" "
GoSub VIEW
'scramble
PL$=PL$+Chr$(K+65)
CODE=PB(K)
X=MOD26(CODE+RP(3)-RS(3))
X=MOD26(CODE+FOR3(X))
CODE=X
X=MOD26(X+RP(2)-RS(2))
X=MOD26(CODE+FOR2(X))
CODE=X
X=MOD26(X+RP(1)-RS(1))
X=MOD26(CODE+FOR1(X))
CODE=X
X=MOD26(X+RP(0)-RS(0))
X=MOD26(CODE+FOR0(X))
CODE=REF(X) 'Reflect
X=MOD26(CODE+RP(0)-RS(0))
X=MOD26(CODE+REV0(X))
CODE=X
X=MOD26(CODE+RP(1)-RS(1))
X=MOD26(CODE+REV1(X))
CODE=X
X=MOD26(X+RP(2)-RS(2))
X=MOD26(CODE+REV2(X))
CODE=X
X=MOD26(X+RP(3)-RS(3))
X=MOD26(CODE+REV3(X))
CODE=PB(X)
CI$=CI$+Chr$(CODE+65)
'HFBmod 20150509 start - add output file
'Write encrypted code to output file in groups of 5 characters
'New line after 12 character groups
Print #1,Chr$(CODE+65);
IO=IO+1
if IO>4 then ' Space after 5 characters
IO=0
IG=IG+1
If IG>12 then
IG=0
Print #1, Chr$(13) ' new line
else
Print #1, " ";
endif
endif
'HFBmod 20150509 end
GoSub LAMP
CODE=26 'no lamp
Pause 500
GoSub LAMP
Print@(0,265) PL$
Print@(0,295) CI$
CCNT=CCNT+1:If CCNT<5 Then GoTo ENCRYPT
CCNT=0
PL$=PL$+" "
CI$=CI$+" "
GoTo ENCRYPT
ESCAPE:
Print@(0,410,2)"Press [A] to adjust rotors, [S] to change setup, [Esc] to exit"
GoSub LETTER
'HFBmod 20150509 start - add output file
If K=18 Then 'Chr$(18+65)= "S"
Close #1
GoTo START
endif
If K=27 Then ' Esc key
Close #1
end
endif
'HFBmod 20150509 end
If K<>0 Then GoTo ESCAPE
Print@(0,410)" "
GoSub ADJROT
'HFBmod 20150509 start - add output file
'Clear the output file after the rotors are adjusted
Close #1
gosub OpenOutFile
'HFBmod 20150509 end
GoTo CLRPAD
'HFBmod 20150509 start - add output file
OpenOutFile:
Open OFileName$ for output as #1
IO=0:IG=0 ' reset output character and group counts
Return
'HFBmod 20150509 end
PADFUL:
Print@(0,410,2)"Pad Full, copy message, [Enter] to Continue "
GoSub LETTER
If K<> 28 Then GoTo PADFUL
'HFBmod 20150509 start - add output file
print #1, Chr$(13) ' new line in output file
IO=0:IG=0
'HFBmod 20150509 end
GoTo CLRPAD
REFSET:
Print@(80,15,2)"Select the Reflector (B or C)"
GoSub LETTER
If K<1 Or K>2 Then GoTo REFSET
RF=K
Print@(80,15)Chr$(K+65);" "
Return
ROTSET:
For J=0 To 3
D$(J)=" ":R(J)=0:V(J)=0
Next J
J=9:V(0)=2:DP=30
Print@(0,45,2)"Press [Space] to change Rotor, [Enter] for next Rotor"
ROTOR0:
GoSub VIEW
GoSub LETTER
If K<>26 Then GoTo CRR0
D$(0)=RD$(J)
J=J+1:If J>10 Then J=9
GoTo ROTOR0
CRR0: If K<>28 Then GoTo ROTOR0
If D$(0)=" " Then GoTo ROTOR0
J=J-1:If J=8 Then J=10
R(0)=J:V(0)=0:V(1)=2:J=1:I=1
ROTOR:
GoSub VIEW
GoSub LETTER
If K<>26 Then GoTo CRR1
If J=R(1) Or J=R(2) Then GoTo NXT1
GoTo SKIP
NXT1: J=J+1:If J>8 Then J=1
If J=R(1) Or J=R(2) Then GoTo NXT1
SKIP: D$(I)=RD$(J)
J=J+1:If J>8 Then J=1
GoTo ROTOR
CRR1: If K<>28 Then GoTo ROTOR
If D$(I)=" " Then GoTo ROTOR
J=J-1:If J=0 Then J=8
R(I)=J:V(I)=0:V(I+1)=2:J=1
I=I+1:If I<4 Then GoTo ROTOR
Print@(0,45)" "
GoSub VIEW
Return
RINGSET:
Print@(0,75,2)"Rotor Ring Setting (A to Z), [Enter] for next Rotor"
For J=0 To 3
D$(J)=" A ":RS(J)=0:V(J)=0
Next J
J=0:V(0)=2:DP=60
RING:
GoSub VIEW
GoSub LETTER
If K=28 Then GoTo CRS
If K>25 Then GoTo RING
D$(J)=" "+Chr$(K+65)+" "
RS(J)=K 'offset 0-25
GoTo RING
CRS: V(J)=0:V(J+1)=2
J=J+1:If J<4 Then GoTo RING
Print@(0,75)" "
GoSub VIEW
Return
PLUGSET:
Print@(0,310,2)"PLUG ? To PLUG ? ([Enter] when all done)"
PL1: GoSub LETTER
If K=28 Then GoTo PRET
If K>25 Then GoTo PL1
Print@(30,310)Chr$(K+65)
H=K
PL2: GoSub LETTER
If K=28 Then GoTo PRET
If K>25 Then GoTo PL2
Print@(90,310)Chr$(K+65)
Pause 50
If K<>H Then GoTo SWAP
PB(PB(H))=PB(H):PB(H)=H 'plugboard letter restore
SWAP: If PB(H)<>H Or PB(K)<>K Then GoTo FORBID
PB(H)=K:PB(K)=H 'plugboard letter swap
GoSub SHOW
GoTo PLUGSET
FORBID:
Print@(0,310)"NOT ALLOWED PLUG ALREADY USED! "
Pause 3000
GoTo PLUGSET
PRET: Print@(0,310)" "
Return
SETROT:
For J=0 To 3
D$(J)=" A ":RP(J)=0:V(J)=0
Next J
ADJROT:
Print@(0,160,2)"Set Rotor Start Position (A-Z), [Enter] for next Rotor"
J=0:V(0)=2:DP=120
ROTPOS:
GoSub VIEW
GoSub LETTER
If K=28 Then GoTo CRP
If K>25 Then GoTo ROTPOS
RP(J)=K
D$(J)=" "+Chr$(RP(J)+65)+" "
GoTo ROTPOS
CRP: V(J)=0:V(J+1)=2
J=J+1:If J<4 Then GoTo ROTPOS
Print@(0,160)" "
GoSub VIEW
Return
VIEW:
Print@(100,DP,V(0))D$(0):Print@(150,DP,V(1))D$(1)
Print@(200,DP,V(2))D$(2):Print@(250,DP,V(3))D$(3)
DRAW:
Line(99,DP-1)-(124,DP+11),,B:Line(149,DP-1)-(174,DP+11),,B
Line(199,DP-1)-(224,DP+11),,B:Line(249,DP-1)-(274,DP+11),,B
Return
SHOW:
For J = 0 To 8
If PB(PBD(J))<>PBD(J) Then V=2 Else V=0
Print@((J)*36+7,330,V) "[";Chr$(PBD(J)+65);Chr$(PB(PBD(J))+65);"]"
Next J
For J = 0 To 7
If PB(PBD(J+9))<>PBD(J+9) Then V=2 Else V=0
Print@((J)*36+17,350,V) "[";Chr$(PBD(J+9)+65);Chr$(PB(PBD(J+9))+65);"]"
Next J
For J = 0 To 8
If PB(PBD(J+17))<>PBD(J+17) Then V=2 Else V=0
Print@((J)*36+2,370,V) "[";Chr$(PBD(J+17)+65);Chr$(PB(PBD(J+17))+65);"]"
Next J
Return
LETTER: 'Wait for key press
K$=Inkey$
If K$="" Then GoTo LETTER
K=Asc(K$)
If K=13 Then K=28 'CR
If K=32 Then K=26 'SP
If K>25 And K<29 Then GoTo LRET
If K>64 And K<91 Then GoTo UPC 'ucase
If K>96 And K<123 Then GoTo LOC 'lcase
GoTo LETTER
LOC: K=K-32 'conv to ucase
UPC: K=K-65 'bound 0 to 25
LRET: Return
LAMP:
For J = 0 To 8
If PBD(J)=CODE Then V=2 Else V=0
Print@((J)*36+10,180,V) "(";Chr$(PBD(J)+65);")"
Next J
For J = 0 To 7
If PBD(J+9)=CODE Then V=2 Else V=0
Print@((J)*36+20,200,V) "(";Chr$(PBD(J+9)+65);")"
Next J
For J = 0 To 8
If PBD(J+17)=CODE Then V=2 Else V=0
Print@((J)*36+5,220,V) "(";Chr$(PBD(J+17)+65);")"
Next J
Return
ENIGMAD.BAS
'ENIGMA for MMDOS
'written by Ray Alger May 2015
'Output file added by Hugh Buckle May 2015
OFileName$="EnigOut.txt"
Dim RD$(10):Dim D$(4):Dim R(4):Dim V(5):Dim RS(4):Dim RP(4)
Dim PB(26):Dim PBD(26):Dim REF(26):Dim KO(8,2)
Dim ROT$(10):Dim REF$(2):Dim FOR0(26):Dim REV0(26):Dim FOR1(26)
Dim REV1(26):Dim FOR2(26):Dim REV2(26):Dim FOR3(26):Dim REV3(26)
Dim S$(36):Dim T$(30):Dim BT$(4):Dim BB$(4):Dim BS$(4)
'Rotor display data
RD$(0)=" I ":RD$(1)=" II ":RD$(2)=" III":RD$(3)=" IV ":RD$(4)=" V "
RD$(5)=" VI ":RD$(6)=" VII":RD$(7)="VIII":RD$(8)="beta":RD$(9)="gamm"
'rotor knock on data
KO(0,1)=16:KO(1,1)=4:KO(2,1)=21:KO(3,1)=9:KO(4,1)=25
KO(0,2)=16:KO(1,2)=4:KO(2,2)=21:KO(3,2)=9:KO(4,2)=25
KO(5,1)=25:KO(6,1)=25:KO(7,1)=25
KO(5,2)=12:KO(6,2)=12:KO(7,2)=12
'Rotor data
ROT$(0)="EKMFLGDQVZNTOWYHXUSPAIBRCJ" 'I
ROT$(1)="AJDKSIRUXBLHWTMCQGZNPYFVOE" 'II
ROT$(2)="BDFHJLCPRTXVZNYEIWGAKMUSQO" 'III
ROT$(3)="ESOVPZJAYQUIRHXLNFTGKDCMWB" 'IV
ROT$(4)="VZBRGITYUPSDNHLXAWMJQOFECK" 'V
ROT$(5)="JPGVOUMFYQBENHZRDKASXLICTW" 'VI
ROT$(6)="NZJHGRCXMYSWBOUFAIVLPEKQDT" 'VII
ROT$(7)="FKQHTLXOCBJSPDZRAMEWNIUYGV" 'VIII
ROT$(8)="LEYJVCNIXWPBQMDRTAKZGFUHOS" 'beta
ROT$(9)="FSOKANUERHMBTIYCWLQPZXVGJD" 'gamma
'Reflector data
REF$(1)="ENKQAUYWJICOPBLMDXZVFTHRGS" 'Thin B
REF$(2)="RDOBJNTKVEHMLFCWZAXGYIPSUQ" 'Thin C
'Plug board data
PB$ ="QWERTZUIOASDFGHJKPYXCVBNML"
For J=0 To 25:PBD(J)=Asc(Mid$(PB$,J+1,1))-65:Next J
DAY$="C VI I VII XEL ML YE JH WQ"
TRI$="JEX GFE"
CIPHER$="YWXUN KKCJC TLZHN SQKMD QDRKC YOIJN FJINQ KPIOU NRNG"
Function MOD26(X)
X=Cint(X) 'fix error
X=X MOD 26
If X<0 Then X=X+26
MOD26=X
End Function
Function MOD8(X)
X=X MOD 8
If X<0 Then X=X+8
MOD8=X
End Function
'DOS Screen setup
SYSTEM "mode 80,45" 'DOS box width (chars), depth (lines)
SYSTEM "title MMDOS ENIGMA" 'DOS box title
'box string data
D1$=Chr$(218):D2$=Chr$(179):D3$=Chr$(192):D4$=Chr$(196):D5$=Chr$(191):D6$=Chr$(217)
D7$=Chr$(201):D8$=Chr$(186):D9$=Chr$(200):D10$=Chr$(205):D11$=Chr$(187):D12$=Chr$(188)
BT$(0)=D1$+D4$+D4$+D4$+D4$+D5$:BT$(1)=D7$+D10$+D10$+D10$+D10$+D11$
BT$(2)=D1$+D4$+D4$+D5$:BT$(3)=" "
BB$(0)=D3$+D4$+D4$+D4$+D4$+D6$:BB$(1)=D9$+D10$+D10$+D10$+D10$+D12$
BB$(2)=D3$+D4$+D4$+D6$:BB$(3)=" "
BS$(0)=D2$:BS$(1)=D8$:BS$(2)=D2$:BS$(3)=" "
For J=1 To 47:BH$=BH$+D4$:Next J
START:
For J=1 To 36
S$(J)=""
Next J
S$(15)=D1$+BH$+D5$
S$(25)=D3$+Left$(BH$,8)+"PLUG BOARD"+Left$(BH$,29)+D6$
S$(1)=" ************* MMDOS M4 ENIGMA *************"
T$(2)="REFLECTOR ->"
T$(4)="ROTORS USED -->"
T$(8)="RING SETTINGS ->"
T$(12)=" ROTORS -->"
For J=0 To 25:PB(J)=J:Next J 'Init Plug array
GoSub SHOW
GoSub REFSET
GoSub ROTSET
GoSub RINGSET
GoSub PLUGSET
GoSub SETROT
'HFBmod 20150509 start - add output file
gosub OpenOutFile
'HFBmod 20150509 end
'rotor offset arrays
For J=0 To 25
T=Asc(Mid$(ROT$(R(0)),J+1,1))-65
U=Asc(Mid$(ROT$(R(1)),J+1,1))-65
V=Asc(Mid$(ROT$(R(2)),J+1,1))-65
W=Asc(Mid$(ROT$(R(3)),J+1,1))-65
FOR0(J)=T-J
REV0(T)=J-T
FOR1(J)=U-J
REV1(U)=J-U
FOR2(J)=V-J
REV2(V)=J-V
FOR3(J)=W-J
REV3(W)=J-W
Next J
'knock on data
KO3A=KO(R(3),1):KO3B=KO(R(3),2)
KO2A=KO(R(2),1):KO2B=KO(R(2),2)
'refelector data
For J=0 To 25:REF(J)=Asc(Mid$(REF$(RF),J+1,1))-65:Next J
CLRPAD:SPL$="":SCI$=""
S$(29)="Text IN-"
S$(33)="Text OUT-"
CLPAD:S$(30)=SPL$:S$(34)=SCI$:PL$="":CI$="":CCNT=0:TB=0
S$(27)="Enter text, Press[Esc] to change settings"
GoSub SCRN
ENCRYPT:
GoSub LETTER
If K=27 Then GoTo ESCAPE
If K>25 Then GoTo ENCRYPT
TB=TB+1:If TB>200 Then GoTo PADFUL
'rotor steps
If RP(3)=KO3A Or RP(3)=KO3B Then GoTo ADV2
If RP(2)=KO2A Or RP(2)=KO2B Then GoTo ADV1 ' R2 double step
GoTo ADV3
ADV1: RP(1)=MOD26(RP(1)+1)
ADV2: RP(2)=MOD26(RP(2)+1)
ADV3: RP(3)=MOD26(RP(3)+1)
'rotor display
DP=12:D$(0)=" "+Chr$(RP(0)+65)+" ":D$(1)=" "+Chr$(RP(1)+65)+" "
D$(2)=" "+Chr$(RP(2)+65)+" ":D$(3)=" "+Chr$(RP(3)+65)+" "
'scramble
PL$=PL$+Chr$(K+65)
CODE=PB(K)
X=MOD26(CODE+RP(3)-RS(3))
X=MOD26(CODE+FOR3(X))
CODE=X
X=MOD26(X+RP(2)-RS(2))
X=MOD26(CODE+FOR2(X))
CODE=X
X=MOD26(X+RP(1)-RS(1))
X=MOD26(CODE+FOR1(X))
CODE=X
X=MOD26(X+RP(0)-RS(0))
X=MOD26(CODE+FOR0(X))
CODE=REF(X) 'Reflect
X=MOD26(CODE+RP(0)-RS(0))
X=MOD26(CODE+REV0(X))
CODE=X
X=MOD26(CODE+RP(1)-RS(1))
X=MOD26(CODE+REV1(X))
CODE=X
X=MOD26(X+RP(2)-RS(2))
X=MOD26(CODE+REV2(X))
CODE=X
X=MOD26(X+RP(3)-RS(3))
X=MOD26(CODE+REV3(X))
CODE=PB(X)
CI$=CI$+Chr$(CODE+65)
'HFBmod 20150509 start - add output file
'Write encrypted code to output file in groups of 5 characters
'New line after 12 character groups
Print #1,Chr$(CODE+65);
IO=IO+1
if IO>4 then ' Space after 5 characters
IO=0
IG=IG+1
If IG>12 then
IG=0
Print #1, Chr$(13) ' new line
else
Print #1, " ";
endif
endif
'HFBmod 20150509 end
S$(30)=PL$
S$(34)=CI$
GoSub VIEW
CCNT=CCNT+1:If CCNT<5 Then GoTo ENCRYPT
CCNT=0
PL$=PL$+" "
CI$=CI$+" "
GoTo ENCRYPT
ESCAPE:
S$(27)="Press[A] to set Rotors, [S] for setup, [Esc] to exit"
GoSub SCRN
GoSub LETTER
'HFBmod 20150509 start - add output file
If K=18 Then 'Chr$(18+65)= "S"
Close #1
GoTo START
endif
If K=27 Then ' Esc key
Close #1
end
endif
'HFBmod 20150509 end
If K<>0 Then GoTo ESCAPE
S$(27)=""
GoSub ADJROT
'HFBmod 20150509 start - add output file
'Clear the output file after the rotors are adjusted
Close #1
gosub OpenOutFile
'HFBmod 20150509 end
GoTo CLRPAD
'HFBmod 20150509 start - add output file
OpenOutFile:
Open OFileName$ for output as #1
IO=0:IG=0 ' reset output character and group counts
Return
'HFBmod 20150509 end
PADFUL:
S$(27)="Pad Full, copy message, [Enter] to Continue"
GoSub SCRN
GoSub LETTER
If K<> 28 Then GoTo PADFUL
'HFBmod 20150509 start - add output file
print #1, Chr$(13) ' new line in output file
IO=0:IG=0
'HFBmod 20150509 end
SPL$=Right$(PL$,6)
SCI$=Right$(CI$,6)
GoTo CLPAD
REFSET:
S$(2)="REFLECTOR -> Select the Reflector [B] or [C]"
GoSub SCRN
GoSub LETTER
If K<1 Or K>2 Then GoTo REFSET
RF=K
S$(2)="REFLECTOR -> "+Chr$(K+65)
'GoSub SCRN
Return
ROTSET:
For J=0 To 3
D$(J)=" ":R(J)=10:V(J)=0
Next J
J=8:V(0)=1:DP=4
S$(6)="[Space] to change Rotor, [Enter] for next Rotor"
ROTOR0:
GoSub VIEW
GoSub LETTER
If K<>26 Then GoTo CRR0
D$(0)=RD$(J)
J=J+1:If J>9 Then J=8
GoTo ROTOR0
CRR0: If K<>28 Then GoTo ROTOR0
If D$(0)=" " Then GoTo ROTOR0
J=J-1:If J=7 Then J=9
R(0)=J:V(0)=0:V(1)=1:J=0:I=1
ROTOR:
GoSub VIEW
GoSub LETTER
If K<>26 Then GoTo CRR1
If J=R(1) Or J=R(2) Then GoTo NXT1
GoTo SKIP
NXT1: J=MOD8(J+1)
If J=R(1) Or J=R(2) Then GoTo NXT1
SKIP: D$(I)=RD$(J)
J=MOD8(J+1)
GoTo ROTOR
CRR1: If K<>28 Then GoTo ROTOR
If D$(I)=" " Then GoTo ROTOR
J=MOD8(J-1)
R(I)=J:V(I)=0:V(I+1)=1:J=0
I=I+1:If I<4 Then GoTo ROTOR
S$(6)=""
GoSub VIEW
Return
RINGSET:
S$(10)="Ring Setting [A] to [Z], [Enter] for next Rotor"
For J=0 To 3
D$(J)=" A ":RS(J)=0:V(J)=0
Next J
J=0:V(0)=1:DP=8
RING:
GoSub VIEW
GoSub LETTER
If K=28 Then GoTo CRS
If K>25 Then GoTo RING
D$(J)=" "+Chr$(K+65)+" "
RS(J)=K 'offset 0-25
GoTo RING
CRS: V(J)=0:V(J+1)=1
J=J+1:If J<4 Then GoTo RING
S$(10)=""
GoSub VIEW
Return
PLUGSET:
S$(14)="PLUG ? To PLUG ? [Enter] when all done"
GoSub SCRN
PL1: GoSub LETTER
If K=28 Then GoTo PRET
If K>25 Then GoTo PL1
S$(14)="PLUG "+Chr$(K+65)+" To PLUG ? [Enter] when all done"
GoSub SCRN
H=K
PL2: GoSub LETTER
If K=28 Then GoTo PRET
If K>25 Then GoTo PL2
'S$(21)=Chr$(K+65)
'Pause 50
If K<>H Then GoTo SWAP
PB(PB(H))=PB(H):PB(H)=H 'plugboard letter restore
SWAP: If PB(H)<>H Or PB(K)<>K Then GoTo FORBID
PB(H)=K:PB(K)=H 'plugboard letter swap
GoSub SHOW
GoTo PLUGSET
FORBID:
S$(14)="NOT ALLOWED PLUG ALREADY USED!"
GoSub SCRN
Pause 2000
GoTo PLUGSET
PRET: S$(14)=""
'GoSub SCRN
Return
SETROT:
For J=0 To 3
D$(J)=" A ":RP(J)=0:V(J)=0
Next J
ADJROT:
S$(14)="Rotor Start Pos. [A] to [Z], [Enter] for next Rotor"
J=0:V(0)=1:DP=12
ROTPOS:
GoSub VIEW
GoSub LETTER
If K=28 Then GoTo CRP
If K>25 Then GoTo ROTPOS
RP(J)=K
D$(J)=" "+Chr$(RP(J)+65)+" "
GoTo ROTPOS
CRP: V(J)=0:V(J+1)=1
J=J+1:If J<4 Then GoTo ROTPOS
S$(14)=""
GoSub VIEW
Return
VIEW:
DV0$=BS$(V(0))+D$(0)+BS$(V(0)):DV1$=BS$(V(1))+D$(1)+BS$(V(1))
DV2$=BS$(V(2))+D$(2)+BS$(V(2)):DV3$=BS$(V(3))+D$(3)+BS$(V(3))
S$(DP-1)=" "+BT$(V(0))+" "+BT$(V(1))+" "+BT$(V(2))+" "+BT$(V(3))
S$(DP)=T$(DP)+" "+DV0$+" "+DV1$+" "+DV2$+" "+DV3$
S$(DP+1)=" "+BB$(V(0))+" "+BB$(V(1))+" "+BB$(V(2))+" "+BB$(V(3))
GoTo SCRN
Return
SHOW:
S$(16)=D2$+" ":S$(17)=D2$+" ":S$(18)=D2$+" "
For J = 0 To 8
If PB(PBD(J))<>PBD(J) Then V=2 Else V=3
S$(16)=S$(16)+BT$(V)+" "
S$(17)=S$(17)+BS$(V)+Chr$(PBD(J)+65)+Chr$(PB(PBD(J))+65)+BS$(V)+" "
S$(18)=S$(18)+BB$(V)+" "
Next J
S$(16)=S$(16)+D2$:S$(17)=S$(17)+D2$:S$(18)=S$(18)+D2$
S$(19)=D2$+" ":S$(20)=D2$+" ":S$(21)=D2$+" "
For J = 9 To 16
If PB(PBD(J))<>PBD(J) Then V=2 Else V=3
S$(19)=S$(19)+BT$(V)+" "
S$(20)=S$(20)+BS$(V)+Chr$(PBD(J)+65)+Chr$(PB(PBD(J))+65)+BS$(V)+" "
S$(21)=S$(21)+BB$(V)+" "
Next J
S$(19)=S$(19)+" "+D2$:S$(20)=S$(20)+" "+D2$:S$(21)=S$(21)+" "+D2$
S$(22)=D2$+" ":S$(23)=D2$+" ":s$(24)=D2$+" "
For J = 17 To 25
If PB(PBD(J))<>PBD(J) Then V=2 Else V=3
S$(22)=S$(22)+BT$(V)+" "
S$(23)=S$(23)+BS$(V)+Chr$(PBD(J)+65)+Chr$(PB(PBD(J))+65)+BS$(V)+" "
S$(24)=S$(24)+BB$(V)+" "
Next J
S$(22)=S$(22)+" "+D2$:S$(23)=S$(23)+" "+D2$:S$(24)=S$(24)+" "+D2$
'GoSub SCRN
Return
LETTER: 'Wait for key press
K$=Inkey$
If K$="" Then GoTo LETTER
K=Asc(K$)
If K=13 Then K=28 'CR
If K=32 Then K=26 'SP
If K>25 And K<29 Then GoTo LRET
If K>64 And K<91 Then GoTo UPC 'ucase
If K>96 And K<123 Then GoTo LOC 'lcase
GoTo LETTER
LOC: K=K-32 'conv to ucase
UPC: K=K-65 'bound 0 to 25
LRET: Return
SCRN: Cls
For L=1 To 36
Print S$(L)
Next L
Return
ENIGMAG.bas
'Enigma Pseudo-random Setup Generator
'Created by Hugh Buckle May 2015
'For use with Ray Alger's ENIGMA.bas and ENIGMAD.bas
dim RD$(8),RD(8),A(26)
RD$(1)=" I ":RD$(2)=" II ":RD$(3)=" III ":RD$(4)=" IV "
RD$(5)=" V ":RD$(6)=" VI ":RD$(7)=" VII ":RD$(8)=" VIII"
Letters$="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Initialize
?
'Set the reflector to B or C
? "Reflector = " chr$(int(rnd()*2 + 66))
SetRo RO$
? "Rotor order = " RO$
SetRings Ring$
? "Ring setup = " Ring$
SetPlugBoard PB$
? "Plug board = " PB$
SetRotors RS$
? "Rotor setting = " RS$
SetMsgKey MK$
? "Message Key = " MK$
Sub Initialize
'Get seed and randomise
local i,b,a$
input "seed"; a$
For i=1 to len(a$)
b=b + Asc(mid$(a$,i,1))
next
randomize b
end sub 'Initialize
Sub SetRo(RO$)
' Set the wheel order
local i,j
i=int(rnd()*2+1)
if i=1 then RO$="beta " else RO$="gamm "
for i=1 to 3
'Sets a unique rotor number (3 out of 8)
do
j=int(rnd()*8+1)
loop until rd(j)=0
rd(j)=1
RO$=RO$+rd$(j)
next
end Sub 'WO
Sub SetRings(Ring$)
'Set each of the rings
local i,j
for i= 1 to 4
j=int(rnd()*26+1)
a$=mid$(Letters$,j,1)
Ring$=Ring$+" "+A$+" "
next
End Sub 'SetRings
sub SetPlugBoard(Plugs$)
'Select plugboard pairs
local L$,NumPlugs,LettersAvail,i,j
NumPlugs=int(rnd()*10+1)
L$=Letters$
LettersAvail=26
for i=1 to NumPlugs
GetLetter(a$,L$,LettersAvail)
Plugs$=Plugs$+A$
GetLetter(a$,L$,LettersAvail)
Plugs$=Plugs$+A$+" "
Next
End Sub 'Set PlugBoard
Sub SetRotors(RS$)
'Create rotor initial settings
local i,j
for i= 1 to 4
j=int(rnd()*26+1)
a$=mid$(Letters$,j,1)
RS$=RS$+" "+A$+" "
next
End Sub 'SetRings
Sub SetMsgKey(MK$)
'Set a message key
For i=1 to 4
j=int(rnd()*26+1)
a$=mid$(Letters$,j,1)
MK$=MK$+A$
next
MK$=MK$+" "
For i=1 to 4
j=int(rnd()*26+1)
a$=mid$(Letters$,j,1)
MK$=MK$+A$
next
end Sub 'SetMsgKey
Sub GetLetter(a$,L$,LettersAvail)
'Selects a unique letter from the alphabet
local j
j=int(rnd()*LettersAvail+1)
A$=Mid$(L$,j,1)
if j>1 and j<Len(L$) then
L$=Left$(L$,j-1)+Mid$(L$,j+1)
else
if j=1 then
L$=Mid$(L$,2)
else
L$=Left$(L$,Len(L$)-1)
Endif
endif
LettersAvail=LettersAvail-1
End Sub 'Get letter