The Cipher Event
by Tony Sale | Back to Index |

Tony Sale's
Codes and Ciphers

Emulation of the Lorenz SZ42 cipher machine.

A software emulation of the SZ42 was written in QBASIC in 1994 and verified against an absolutely unique set of Wartime intercepted cipher text, wheel patterns, wheel starts, limitations and the deciphered German text.

This emulation has been used to re-encipher decrypted German texts to provide the cipher texts used to test real Colossus and virtual Colossus.

German text H.

XWOLLE.WI.R..AUCH.BLEIBEN.++Z--KR..GWFRL+X-.FUE..+.WPYP.QXT. QIPQ.V.AACQEM..+.AA-..QEE..+.AA-...AN..OB+M-.SUEDWEST+V.AA-G EHEIME.KOMMANDOSACHE+AA-..+.AA-.NOR.ZUR.PERSOENLICHEN.UNTERRI CHTUNG+N--.WEITERGABE.VERBOTEN+MA.AA-LAGEBERICHT.VOM..+.EPMM.- NN..VOM..+.EPMRM.QORT.AA--.KATEN.NN.KAT.NN.KARTEN..+.Q.C.Q.-P P.PPP.A.MA.---.ROEM.+.QM-.WESTEN..+.C-..AOK...L.U.C----.ROEM. +.QWM-.A+M-.K+MCMA.-.PANZERUNTERSTUEZ.NN.PANZSRUNTERSTUETZTE. FEINDANGRIFFE..GEGEN.EIGENE.STUETZPU.NKTFRONT.NAHMEN.BAD.ELSTER+ N-.SOHL+N-.RAU.NN.RAU.N.UND.BAD.BRAMBACH.+K.WR---.NN...+KWT--.KM .BFO.HOF+LM-.NEUE.STUETZPUNKTFRONT.B..DIESER.ORT+M-.UEBRIGE.KORPSFRO NT.BEIDERSEITIGE.AUFKLAERUNGSTAETIGKEI+M.DIESER.ORT+M-.UEBRIGE.KORP SFRONT.BEIDERSEITIGE.AUFKLAERUNGSTAETIGKEI+MA..A-STELLV+M-.ROEM. +.QEM-.A+M-K+MMA.-.ZUNEHMENDER.FEINDDRUCK.IM.RAUM.N.UND..W.. BAERNAU.+K.T--.NN..+.KWT--.KM.SW.MARIENBAD+LM--.FEINDANGRIF.F ..VON..SO..GEGEN.PAULUSBRUNN+M-..LAGE.DORT.UNGEKLAERT+M-.SCHWACHE. .EIGENEN.SICHERUNGEN.DURCH.FEIND.AUS..SCHAENWALDE.UND.WOSANT.. +K.Y-.KM.SO..TACHAU+L-.NACH.O..ZURUECKGEWOFNN.ZURUEIKGEWORFEN+M- .FEIND..MIT.INF.UND.PZ+M-.IN.PEISSIGKAU.UND.WLAD.N..DAHENTEN+M- .EIGENE.SICHERANGEN.IN.MOLGAU.+.A-.DRI.UND.WLAD.N..DAHENTEN+M-. EIGENE.SICHERUNGENSIGKAU.UND.WLAD.N..DAHENTEN+M-.EIGENE.SICHERU NGEN.IN.MOLGAU.+.A-.DRISSGLOBEN.+.A-.WURKAU+M-.IM.A..NN.IM.RAUM. .TAUS..PANZERUNTERSTUETZTE..FEINDANGRIFFE+MA..AA-..A+M-O+M-K+M.. QC.MA..-.UEBER.ISAR.MIT.INF.UND.PZ+M-.UEBERBESETZTER.FEIND.STI ESZ..UEBER.S.NN.UEBER..VILSA.BSCHNITT.VOR.UND.NAHM..AUNKIRCHEN. +.A-.ALDERSBACH.+.A-.EGGERSDORF..+KWP--.KM.W.PASSAU+LMA.A--R OEM..+.IWM-.A+MLK+MCMA.-.DWP--.KM.W.PASSAU+LMA.A--ROEM..+.IWM -.A+MLK+MCMA.-.DER.ZWISCHEN.PLATTLING.UND.LANDAU.FU.NN3/UF.. BREITER.FRONT..UEBER.DIE.ISAR..UEBERS..NNN.UEBERGESETZTE..FEIND. DRUECKTE.EIGENEN.LINIE+N-.TROTZ.HIFTIGEN.WIDERSTANDES+N-.AUF.VISLABSC HNITT.ZUREUCK+-+M-.FEINDPANZER.N.NN.IN.ARTOFRNN.IN.ARNTORF. +.KQT--.KM.SO.LANDAU+B-.UND..N.ROTTESDORF+..IN.ARNTORZ.+.KQT--. KM.SO.LANDAU+L-.UND..N.ROTTESDORF+.KI-.KM.S.LANDAU+LMA+.A-.ROEM.+ .QEM-.3.NN..+.A-..ROEM..+.QEM-.SS+M-..A+M-.K+MCA.-.BRUECKENKOPF.L****

wheel patterns

HX1 ..xxxx.xx....xxx..x.x...x.xxxx.x.xxx...x.
HX2 ..xx.xx..x..xx..xxxx.x...xxx..x
HX3 .xx.xx..xx...xx...xxx.x..xx..
HX4 ..x....xxx.xx..xxxx..x..xx
HX5 ..x.x..x.xxxx....xx..xx

HM1 ...xxxx.xxx.xxxx.xxxx.xxxx.xxxx.xxx....xx.xxxx.xxx.xxxx.xxxx.
HM2 ....x.x...x.x.x...x.x.x...x.x.x.x.x.x

HS1 x.xx.x..x.x.x.x.x.xxxx.x.x.xxx..x.x.xx...x.
HS2 x..x.x.x.xx.x....x.xxx.x.xx.x..x.x.x..xxx.x.xx.
HS3 x.x.x..xx.x.x..x.x.xxx..x.x.x.xx.x.x....xxx..x.x.x.
HS4 .x.x.x.x.x.x..x.xx.x.x..x.x.xx.x...xx.x.x.xxxx...xx.
HS5 .x..x.xx...x.x.xxxx..xx.x.x.x.x.x.x.x.x...x.xx.x..x.xx...xx


starts

X 31,1,1,15,1 M 59,26 S 32,36,11,9,43

limitation: K2 one back

cipher text verified against original.

J3KF+LXT/.+YTMLE/RFVC-SE///4GYX3Q.Z3GVWKWDVAPURPYL/.UYAI.EOW3ZBVVAQRTO/PACJ.NLVLZYYNTU.IDCPKTEZOSWCOBNWFJ+UAKE+WU-JMWYWLXRM+M/HV+TVTC-FOGN3QZG4J.VLM/KK+OEC/YIWTSZUDTSY+3LCCHZADQ-3VBXKEOCSO/+ZBFN34-F.+4UVFVLIP4KFGRBFIVFFJX/FKFSHJ.VUJVWXE+LFAICDYX3EZD33U+GSOGXPAXHTJSNUQI+PXS3JRG+-U+YZITF/SM4LIDPSYMVJM/BL/YHDGBG/UI+EM.JEMX.YQNUWTLAUCLUSDMZGXCQ3CPPCCYLTJC4KXB--G4VGQ4J.EYTEVSG33DVLVPDGNOGAJOUWGFY4KGO-4+IRKDPGDHGBQLFSS/YDP/FM-/BANLERZEMT.U3XZA43RGYD+-J4VYRTONRYF/OI4Y+I3LXUFAHGRT.RXCO3HKCQIML.VHVIGHBWBTU3RZFN.J.WGNLSGLYBJT+TPM-RHHMXTNDSVUO3W/4ORZ4UY.LA-XZYVLCZROMPM3RYSLUD-SNQQA+RK/UV4K/GOSSMJRGIZYPO+BEEB+OEWAWKYXW.-NKUQERUM-PA4WFNKU-Q-LNC.D-A3C.FB.RFOGZHUWTEAYB3HNHCEW.N33QEEVUEC3OOR4BRNLH/IF3+DJJ3S3J4XA+Z3SMT/K4L-IDLQWCLMQ3TO3PNYVCGZCXUMSSBH.BWMGGTIYSC/UBX/PE+3IZZ.Z/CCWLSL+4/4+IET/ELBCBDAM4ELKDAGB3O.3J+IEQQJ.U.VSAQSAYZAU+3YOZWPPPV/YOVOE/P/E4UOZYK4PE3A.ETZGFBCZE.4WA3PSDR3XMLJLH+S3UWOA.T-RID-MA.CVZGLNYK4U.HBPSA+3U+BLSGS/FNRXMOMEBBABIPOAGDWA-4T/B.L.HDSAJE.HE-4FZW+SDBAYCNBTEODDALCMIG-QNM+-PEFC+ABNQ-MVT3-GHKAN/ENZLPMJRVRB+4NBCRTFDVNLRTPIGIEZGSPUXMW3WJQTOEV+WA-HJZLX-JQID-X++FFGKCTO.3.F+JIISVTXKC+..YM/SOQUIAS-IAGJJPRYLLT.EJBJAMRP+MS-ZRUVLBBE-UNYQGBBHEB+QCHYYHVN.NHKS-YG3BNZKQJBO-FQ.SZB/JRFILGUZUZVCCVGULEKU4/HRBGYIZVLCM3/ONJ-OBIRSCT+IZCB-TTZMDQWQUCIVTGTTYNEOTTORM-FSKS3WJWL/ZXOCOCYGC.BRIRKXK.FLJUSP/-G.WP.MMVHBYREWQZZAN/BKSEYDBGXAUV+NUKUKIKIGS+VO-4EY/GWI+SGJOJCBYGGMY4+/EMGULCSC-Y+CXLIECYC-+-ZXHSPOTFGFDWIFT-4XXDDLMMKT433WH/BX-OILWDJC/FFE-ZYH3C4GI4T/3KUJQ4YNBQWXWB-RM.Q3GG/4Z-AIGW4GYYEBXRJHXQA..-.G/3W/-LVS+4GS-+FRYIOFYGUK-FEYA4J-ZB-MSPAM/WLLJ3GFMJP/GGF-C+O-KQ.K4PWVL+3O.LX4TUD+Y+QOO3GTJT+.MR-4JSRXD-X4SCIDIVLCDEGSOZOGWXQZOZ.3PPQ4ZYXKL+QETCM/3/--CHG4+W.BNHTB+Z-NZCO+QEB+-/FNJ+NSHTO+CW.CM/VHIM-S.3VAFDJ3MEH.G+NQFDCUSK+MCKDCEC-TFWSYBQSWE4UOQOXY-E.ESE4OLJQOBUQZUSLRWV-AVOYX3CKS3ZFUAQAWESYMXQV/4MOXORAVKOIELRXCSR4EU/KEFDQWQ-BWEXGALS/.JLQ/CEKT-4C+TWDNGST-UQ-ERBP.YZ-ZH/Q3ITMN-O3P/JBEVZUOY4CTNY4PKCB3YIW/+BOKDEZE.VCTROQDTAXI3VKGYQVOKSCXPDDAD4DLTELK.GDDLTRPXORSFTDOGB.-NQJHNM/4/JOTIVGOQF+FC.GDX4DMT.UBRV

no limitations: cipher text

J3KTIKK4PUDUFI3OV-3+JGJKXJ.KQOK.FFCQSENTACBEXPFKEIAHQCOGTL/JTDQY3AQRKFYAF/GFS+UQ-++4ENHD4SRWWXFIBKWV+BYQJHQW-F+ENHZBPYLMW.O.DY-MBLLYJL4Q4AUD3VIKE+LM-DH.UVW4Q+WLUQEDTQUOKYFL4D+E-DVPNPI3SN3YZVHM3DTM4G3HF3TGDT.PXTFFKM3G...QDHH./V+JZOVLUET+EBUQLA/PVUCHQFY+UIU4CIAPQXB4ZGT/HDBCS3BOG+VJQQCBK-LQ4J+UKTACFKPZFWOSPDTA.AYWLE+IQOLDSMAV-HXQY/.FTSBCIJO-KX4O++AOA3.H/BMCREHFKWAZ+WGDX.NISP+G+SDSYZFJL3ZBHT./YFTXU4RQCVR/LZ4ZNXVT4XYAX3LLYODOU-/BC/LOCXZSW4XLA43XHTJBUWPG/XUE3NISQKSA+UGA.JZI3-CF4BO3+-M//EM/G/F434GXF/JHXZEAOWAJI+NNUQ/-4SDFAO.43J-VVQJI-SDLHL4LZW.YZ4UY.LACWDFIR3VEP-Y-BCZ+X3WC/DE+KQIVZPC.AS-YQ3ZGIZFSFCQEACRLTDWEZEYGL+LTA/FWVYU-MELWVNZLBZBSNQ-YTZ../VQAVTNI.TELPGAELALPZDRMSLGVV-DPVZQRNZJBI3AE/RV.KRYBOCLK4E3QPXCD-IRGGRGOKSVRCPFOW3JSY+NY.H/CZF3NKKORMU4ASSJXXUGHE3NTZIMKEPHEUHCCHHFVQZMVPWT3QPSZXRNQQYPEMUFX+J+YB.QRTEEXA/AOMGJKH4QXBBRQSNIMR-YAQURKFNGHLZMMYWYRVPGZPW4MQ-HVEZMT.HAFVPR3DYEOPCEMVFD4EIF4GG3I/YFYG34RETRJBCVTOJFMF4RE+ITZFVVTU.XB4EE+LNMHPKQPIG3+JFTIO3L.WLZHHQDP4VMOIKSLXDHE3XBCGOQYUZASFPKPS--A/Y4OLYZW-U-3JMBYG.QGMAXQ/E4PSSAFOTTUS-3OLRTJEKANSJHTS.SRZHYDMJLBKK-L3QUWMVPKVKBKPPME3XM4IZE.LGRXXVY/FITBIBYM/SOQUCEOGAIVYZVMPZMVROJBJ+.LTMJLBQQGOAIIV/FCQGXV+Y/OKUIABBG.QMA+XNINOPULKMJYM4-FDG+-RJTR.KEQRCOC-KT4Y3KMFWP.MSPRW/+VLFOSKQTQA.SYB.LM+IZYIMDG+I4MOE/W.C/3JYTD.XGGEMY+DUILVBED3MFEBGN/SRVASN/NDUYEXGAZWQPD3QWWP--JGQXDLH+IIH+Q.4HKJQKNPQW.PGZAJAYUNAAXOTMESZ.ARLDOY.XP3-/SRN3-KY3HSOA-O.Y-Z.LXUH+/XMUOPA+RXN.GAJKG/JPWE--JBY+HXT4D+Q/HF4/E/ONBQLV/VL4O3J/IHNKG+/LYMU+OHEH/C/LZQF/OJROO4TAFRLQEFK/YM.A+GE.COEQNO4OLBURXZ.MSJUSSW4LFB4/KLSYUVXJYCHGPU.+3ZCLG.B/AZ4N+JTDDELAKZP-OYVKF-LXIOMKIPDPE.Z-PK/3USK+VYQRMDJMLIZS+BEYYLXGB./Y4BIOZDP/C+/D/3G.3EH-+3CNKAYPIPTICZPZOVOCEDHEINJDABY3RU+QU-4VESQT/UJGEYPXLGPMVWG3TNHW4RQBX+4BDAWFJG/-FRANU+AG+XQOSH/IUZEF/F4UR4XGYT3-SWC-IT34+USAXAOB+NY+WATFJIZ.4C+USZYZOBD+-AQPKYQYJIMG3VIQ/S4Z3YI4LGB/3UDYZ+4DVBWEXJ/ZWXNKKAMDEKQMEUXAYKWSST/GW+SCLJJSTVTAQO-KB4FM+HV3AZDECZD+AKZTPBLF+VM/WIO/HCDKMWAIMNSLQRTDG.+F+NITD-BCOCXMRR/XBRZW4CZ4NGGZEN4DDCQCFH.G.B-WHDRRGI.IELL.KSU3B/L344ZFLB+EYBW/-/PINTSXAFQWQEEXYONHEJVL3WFAH3NENYECIWKLRH.A+B-NZ3.RS//MYH.HNOAWR.4+Q

Here is the QBASIC program
REM Lorenz SZ42 emulator with limitations
REM (c) Anthony E Sale September 2006
REM version to generate cipher stream from ZMUG, KH or BREAM patterns
REM various starts, optionally P + k & s with m or any combination

TYPE wd
bits AS STRING * 5
spacer AS STRING * 1
END TYPE

TYPE chr
chh AS STRING * 1
END TYPE

DIM ch AS chr
DIM ch1 AS chr
DIM ch2 AS chr
DIM chout AS wd
DIM chin AS wd
DIM chin1 AS wd
DIM chin2 AS wd

filename$ = " "

let$ = "11000A10011B01110C10010D10000E10110F01011G00101H01100I11010J11110K01001L00111M00110N00011O01101P11101Q01010R10100S00001T11100U01111V11001W10111X10101Y10001Z11111-11011+00010301000400100.00000/"
ruler$ = "1234567890123456789012345678901234567890123456789012345678901"
REM vector to remember bit 5 of clear txt ch
rem$ = "00000"
plet$ = " "
DATA rn%,n0%,n1%,bn%,strt%,fst%,pc%,lptr%,nolets%,lets%,ri%
DATA spk1%,spk2%,spk3%,spk4%,spk5%,spm1%,spm2%,sps1%,sps2%,sps3%,sps4%,sps5%
DATA pk1%,pk2%,pk3%,pk4%,pk5%,pm1%,pm2%,ps1%,ps2%,ps3%,ps4%,ps5%,pk2b%,ps1b%
zk1$ = ".xx..xxx....xxx..xxx....x..xx.xx...xx.xx."
hk1$ = "..xxxx.xx....xxx..x.x...x.xxxx.x.xxx...x."
bk1$ = "...xxxx....xx....x.xx..x..xx.x.xx.x.xxxx."
zk2$ = "...xx..xx...x.xxxx.xxx....xx.xx"
hk2$ = "..xx.xx..x..xx..xxxx.x...xxx..x"
bk2$ = "xx..xxx.xx...x.x.xx...x....xxx."
zk3$ = ".xxxx.xx...xxx...xx...xx..x.."
hk3$ = ".xx.xx..xx...xx...xxx.x..xx.."
bk3$ = "..xxx.xx..x....xxx..xx.xx..xx"
zk4$ = "x.x..xxx.x..xx...xx..x.x.x"
hk4$ = "..x....xxx.xx..xxxx..x..xx"
bk4$ = "..xx..x.xx..x..xx..x..xxxx"
zk5$ = "x.x....xxx.x...xxxx..x."
hk5$ = "..x.x..x.xxxx....xx..xx"
bk5$ = ".x...x.xx..x...xxx.xxx."

zm1$ = "x.x.x.xxxx.x.x.xxx.xxx.xxx.xx.xx.xx.xx.xxx.x.x.xxx.xxx.x.xx.x."
hm1$ = "...xxxx.xxx.xxxx.xxxx.xxxx.xxxx.xxx....xx.xxxx.xxx.xxxx.xxxx.."
bm1$ = "xxx.x.xx..xx..xx...xxxx.x.xx.xx...xx....xxxx.xx..xx...xx....x"
zm2$ = "xxx.xxx.xxx.x.xx.xxx.xxx.xx.x.xx.x.x."
hm2$ = "....x.x...x.x.x...x.x.x...x.x.x.x.x.x"
bm2$ = "x.xxx.x.x.x.x..x.x.xxx.x.x.x.x.x.x.x."

zs1$ = "...xxx..xxx..xxxx...xx...xx..xxx...xx..x.xx"
hs1$ = "x.xx.x..x.x.x.x.x..xxx.x.x.xxx..x.x.xx...x."
bs1$ = "..x.x.x.x.x..x..x.xx.xx.x.x..xx.xxx..xxx..."
zs2$ = "xx.x..xxx..xxx..xx...xxxx...xxx..xx..xxx...x..."
hs2$ = "x..x.x.x.xx.x....x.xxx.x.xx.x..x.x.x..xxx.x.xx."
bs2$ = "..x.xx.x.x.x.x.x.xx..xx.x..x.xxxx.....xxx..x.xx"
zs3$ = "xxx..xx...xx...xxx...x...xxxx...x..xxx..xxx..xx..x."
hs3$ = "x.x.x..xx.x.x..x.x.xxx..x.x.x.xx.x.x....xxx..x.x.x."
bs3$ = "x.x.x.x.x.x.x..x..xx.x.x.xxxx....xxx...xxx.xx..x..x"
zs4$ = "x.xxx..xx...xx..x..xxx..xx...x...xxxx..xxx..xx..xxx.."
hs4$ = ".x.x.x.x.x.x..x.xx.x.x..x.x.xx.x...xx.x.x.xxxxx...xx."
bs4$ = "x.x..xx.x.x.x.x.x.xx.x....xx..xx..xx.xxxxx.x..x....x."
zs5$ = ".xx...x..xxx..xx..xxx..xx...xxxx..x..xxx..xxxx...x...xxx..x"
hs5$ = ".x..x.xx...x.x.xxxx..xx.x.x.x.x.x.x.x.x...x.xx.x..x.xx...xx"
bs5$ = ".x.x.x.x.xx...x.x..xxx.xxxx.xx.x....x...x..xx.xx..xx..x.x.x"

REM wheel start positions for ZMUG
z1k1 = 1: z1k2 = 1: z1k3 = 1: z1k4 = 3: z1k5 = 1
z1m1 = 2: z1m2 = 2
z1s1 = 20: z1s2 = 38: z1s3 = 38: z1s4 = 33: z1s5 = 46

REM wheel start positions for ZMUG 2
z2k1 = 4: z2k2 = 12: z2k3 = 17: z2k4 = 19: z2k5 = 8
z2m1 = 22: z2m2 = 12
z2s1 = 10: z2s2 = 28: z2s3 = 18: z2s4 = 23: z2s5 = 26

REM wheel starts for KH 1
h1k1 = 31: h1k2 = 1: h1k3 = 1: h1k4 = 15: h1k5 = 1
h1m1 = 59: h1m2 = 26
h1s1 = 32: h1s2 = 36: h1s3 = 11: h1s4 = 9: h1s5 = 43

REM wheel starts for KH 2
h2k1 = 31: h2k2 = 1: h2k3 = 1: h2k4 = 15: h2k5 = 1
h2m1 = 59: h2m2 = 26
h2s1 = 32: h2s2 = 36: h2s3 = 11: h2s4 = 9: h2s5 = 43

REM wheel starts for KH 3
h3k1 = 31: h3k2 = 5: h3k3 = 10: h3k4 = 15: h3k5 = 8
h3m1 = 59: h3m2 = 26
h3s1 = 32: h3s2 = 36: h3s3 = 11: h3s4 = 9: h3s5 = 43

REM wheel starts for BR 1
b1k1 = 17: b1k2 = 29: b1k3 = 7: b1k4 = 11: b1k5 = 18
b1m1 = 22: b1m2 = 12
b1s1 = 10: b1s2 = 28: b1s3 = 18: b1s4 = 23: b1s5 = 26

REM wheel starts for BR 2
b2k1 = 4: b2k2 = 12: b2k3 = 17: b2k4 = 19: b2k5 = 8
b2m1 = 22: b2m2 = 12
b2s1 = 10: b2s2 = 28: b2s3 = 18: b2s4 = 23: b2s5 = 26

REM wheel starts for BR 3
b3k1 = 4: b3k2 = 12: b3k3 = 17: b3k4 = 19: b3k5 = 8
b3m1 = 22: b3m2 = 12
b3s1 = 10: b3s2 = 28: b3s3 = 18: b3s4 = 23: b3s5 = 26


REM wheel start positions
spk1 = 1: spk2 = 1: spk3 = 1: spk4 = 1: spk5 = 4
spm1 = 1: spm2 = 1
sps1 = 1: sps2 = 1: sps3 = 1: sps4 = 1: sps5 = 1
sd0 = 8
sd1 = sd0: sd2 = sd0: sd3 = sd0: sd4 = sd0: sd5 = sd0

szk1 = 41: szk2 = 31: szk3 = 29: szk4 = 26: szk5 = 23
szm1 = 61: szm2 = 37
szs1 = 43: szs2 = 47: szs3 = 51: szs4 = 53: szs5 = 59
PRINT CHR$(27); CHR$(116); CHR$(1);

default$ = "lorenzop.txt"
CLS

PRINT " THE LORENZ SZ42 EMULATOR (c) A. E. Sale November 1994"
PRINT " "
PRINT " "

INPUT "patterns, z, h, or b "; plet$
IF plet$ = "z" THEN
k1$ = zk1$
k2$ = zk2$
k3$ = zk3$
k4$ = zk4$
k5$ = zk5$
m1$ = zm1$
m2$ = zm2$
s1$ = zs1$
s2$ = zs2$
s3$ = zs3$
s4$ = zs4$
s5$ = zs5$
END IF
IF plet$ = "h" THEN
k1$ = hk1$
k2$ = hk2$
k3$ = hk3$
k4$ = hk4$
k5$ = hk5$
m1$ = hm1$
m2$ = hm2$
s1$ = hs1$
s2$ = hs2$
s3$ = hs3$
s4$ = hs4$
s5$ = hs5$
END IF
IF plet$ = "b" THEN
k1$ = bk1$
k2$ = bk2$
k3$ = bk3$
k4$ = bk4$
k5$ = bk5$
m1$ = bm1$
m2$ = bm2$
s1$ = bs1$
s2$ = bs2$
s3$ = bs3$
s4$ = bs4$
s5$ = bs5$
END IF

INPUT "special motor patterns for m1, hm1, zm1, bm1 or just return for default "; m1let$
INPUT "special motor patterns for m2, hm2, zm2, bm2 or just return for default "; m2let$

IF m1let$ <> "" THEN
IF m1let$ = "hm1" THEN m1$ = hm1$
IF m1let$ = "zm1" THEN m1$ = zm1$
IF m1let$ = "bm1" THEN m1$ = bm1$
END IF
IF m2let$ <> "" THEN
IF m2let$ = "hm2" THEN m1$ = hm1$
IF m2let$ = "zm2" THEN m1$ = zm1$
IF m2let$ = "bm2" THEN m1$ = bm1$
END IF

INPUT "starts, z1,z2, h1,h2,h3 or b1,b2,b3 "; slet$
IF slet$ = "z1" THEN
spk1 = z1k1: spk2 = z1k2: spk3 = z1k3: spk4 = z1k4: spk5 = z1k5: spm1 = z1m1: spm2 = z1m2
sps1 = z1s1: sps2 = z1s2: sps3 = z1s3: sps4 = z1s4: sps5 = z1s5
END IF
IF slet$ = "z2" THEN
spk1 = z2k1: spk2 = z2k2: spk3 = z2k3: spk4 = z2k4: spk5 = z2k5: spm1 = z2m1: spm2 = z2m2
sps1 = z2s1: sps2 = z2s2: sps3 = z2s3: sps4 = z2s4: sps5 = z2s5
END IF
IF slet$ = "h1" THEN
spk1 = h1k1: spk2 = h1k2: spk3 = h1k3: spk4 = h1k4: spk5 = h1k5: spm1 = h1m1: spm2 = h1m2
sps1 = h1s1: sps2 = h1s2: sps3 = h1s3: sps4 = h1s4: sps5 = h1s5
END IF
IF slet$ = "h2" THEN
spk1 = h2k1: spk2 = h2k2: spk3 = h2k3: spk4 = h2k4: spk5 = h2k5: spm1 = h2m1: spm2 = h2m2
sps1 = h2s1: sps2 = h2s2: sps3 = h2s3: sps4 = h2s4: sps5 = h2s5
END IF
IF slet$ = "h3" THEN
spk1 = h3k1: spk2 = h3k2: spk3 = h3k3: spk4 = h3k4: spk5 = h3k5: spm1 = h3m1: spm2 = h3m2
sps1 = h3s1: sps2 = h3s2: sps3 = h3s3: sps4 = h3s4: sps5 = h3s5
END IF
IF slet$ = "b1" THEN
spk1 = b1k1: spk2 = b1k2: spk3 = b1k3: spk4 = b1k4: spk5 = b1k5: spm1 = b1m1: spm2 = b1m2
sps1 = b1s1: sps2 = b1s2: sps3 = b1s3: sps4 = b1s4: sps5 = b1s5
END IF
IF slet$ = "b2" THEN
spk1 = b2k1: spk2 = b2k2: spk3 = b2k3: spk4 = b2k4: spk5 = b2k5: spm1 = b2m1: spm2 = b2m2
sps1 = b2s1: sps2 = b2s2: sps3 = b2s3: sps4 = b2s4: sps5 = b2s5
END IF
IF slet$ = "b3" THEN
spk1 = b3k1: spk2 = b3k2: spk3 = b3k3: spk4 = b3k4: spk5 = b3k5: spm1 = b3m1: spm2 = b3m2
sps1 = b3s1: sps2 = b3s2: sps3 = b3s3: sps4 = b3s4: sps5 = b3s5
END IF

REM VIEW PRINT 5 TO 35

reply$ = "y"
CLS 2
PRINT "k1 "; spk1, k1$
PRINT "k2 "; spk2, k2$
PRINT "k3 "; spk3, k3$
PRINT "k4 "; spk4, k4$
PRINT "k5 "; spk5, k5$
PRINT "m1 "; spm1, m1$
PRINT "m2 "; spm2, m2$
PRINT "s1 "; sps1, s1$
PRINT "s2 "; sps2, s2$
PRINT "s3 "; sps3, s3$
PRINT "s4 "; sps4, s4$
PRINT "s5 "; sps5, s5$
PRINT " "
reply$ = "n"
VIEW PRINT 15 TO 25
CLS 2
INPUT "PL y/n? "; PL$
INPUT " k y/n? "; k$
INPUT " s y/n? "; s$
INPUT " klim y/n? "; klim$
IF PL$ = "y" THEN
INPUT "PL options: decrypts: Tunny report t, Orig o, KH k, or just return to enter new name "; PLNM$
IF PLNM$ = "t" THEN plfilename$ = "trptext3.txt"
IF PLNM$ = "o" THEN plfilename$ = "tunnyp2x.txt"
IF PLNM$ = "k" THEN plfilename$ = "xwolle4.txt"
IF PLNM$ = "" THEN INPUT "PL file name "; plfilename$

OPEN plfilename$ FOR RANDOM AS #1 LEN = LEN(ch)
END IF

REM no limitations
P1 = 0: P2 = 0: P5 = 0
IF klim$ = "y" THEN
P1 = 1
END IF

IF s$ = "y" THEN INPUT "motor dots: h for high, m for medium, l for low, return for default "; mdots$
IF mdots$ = "h" THEN
m1$ = bm1$ END IF
IF mdots$ = "m" THEN
m1$ = zm1$
m2$ = bm2$
END IF
IF mdots$ = "l" THEN
m1$ = hm1$
m2$ = zm2$
END IF
IF mdots$ <> "" THEN
PRINT "m1 "; spm1, m1$
PRINT "m2 "; spm2, m2$
END IF

strt = 1:
pk1 = spk1: pk2 = spk2: pk3 = spk3: pk4 = spk4: pk5 = spk5
pm1 = spm1: pm2 = spm2
ps1 = sps1: ps2 = sps2: ps3 = sps3: ps4 = sps4: ps5 = sps5
INPUT "Z out file ", opfilename$
OPEN opfilename$ FOR RANDOM AS #2 LEN = LEN(ch)
rno = 1
rn = 1

INPUT "number of letters: "; nolets
IF nolets > 0 THEN
DO WHILE nolets > 0

IF PL$ = "y" THEN
GET #1, rn, ch
rn = rn + 1
DO WHILE ASC(ch.chh) = 13 OR ASC(ch.chh) = 10
GET #1, rn, ch
rn = rn + 1
LOOP

REM PRINT ch.chh
lptr = 6
DO WHILE lptr < 194
IF MID$(let$, lptr, 1) <> ch.chh THEN
lptr = lptr + 6
ELSE
lptr = lptr - 5
chin.bits = MID$(let$, lptr, 5)
lptr = 195
END IF
LOOP
END IF
IF ch.chh = "*" THEN
nolets = 1
ELSE
bn = 0
IF s$ = "y" THEN
IF MID$(s1$, ps1 + bn, 1) = "." THEN
MID$(chin1.bits, 1, 1) = "0"
ELSE
MID$(chin1.bits, 1, 1) = "1"
END IF
IF MID$(s2$, ps2 + bn, 1) = "." THEN
MID$(chin1.bits, 2, 1) = "0"
ELSE
MID$(chin1.bits, 2, 1) = "1"
END IF
IF MID$(s3$, ps3 + bn, 1) = "." THEN
MID$(chin1.bits, 3, 1) = "0"
ELSE
MID$(chin1.bits, 3, 1) = "1"
END IF
IF MID$(s4$, ps4 + bn, 1) = "." THEN
MID$(chin1.bits, 4, 1) = "0"
ELSE
MID$(chin1.bits, 4, 1) = "1"
END IF
IF MID$(s5$, ps5 + bn, 1) = "." THEN
MID$(chin1.bits, 5, 1) = "0"
ELSE
MID$(chin1.bits, 5, 1) = "1"
END IF
END IF

IF k$ = "y" THEN
IF MID$(k1$, pk1 + bn, 1) = "." THEN
MID$(chin2.bits, 1, 1) = "0"
ELSE
MID$(chin2.bits, 1, 1) = "1"
END IF
IF MID$(k2$, pk2 + bn, 1) = "." THEN
MID$(chin2.bits, 2, 1) = "0"
ELSE>br> MID$(chin2.bits, 2, 1) = "1"
END IF
IF MID$(k3$, pk3 + bn, 1) = "." THEN
MID$(chin2.bits, 3, 1) = "0"
ELSE
MID$(chin2.bits, 3, 1) = "1"
END IF
IF MID$(k4$, pk4 + bn, 1) = "." THEN
MID$(chin2.bits, 4, 1) = "0"
ELSE
MID$(chin2.bits, 4, 1) = "1"
END IF
IF MID$(k5$, pk5 + bn, 1) = "." THEN
MID$(chin2.bits, 5, 1) = "0"
ELSE
MID$(chin2.bits, 5, 1) = "1"
END IF
END IF

chout.bits = "00000"
IF PL$ = "y" THEN
chout.bits = chin.bits
END IF
IF (s$ = "y") THEN
bn = 1
DO WHILE bn < 6
IF ((MID$(chin1.bits, bn, 1) = "0") AND (MID$(chout.bits, bn, 1) = "1")) OR ((MID$(chin1.bits, bn, 1) = "1") AND (MID$(chout.bits, bn, 1) = "0")) THEN
MID$(chout.bits, bn, 1) = "1"
ELSE
MID$(chout.bits, bn, 1) = "0"
END IF
bn = bn + 1
LOOP

END IF

IF (k$ = "y") THEN
bn = 1
DO WHILE bn < 6
IF ((MID$(chin2.bits, bn, 1) = "0") AND (MID$(chout.bits, bn, 1) = "1")) OR ((MID$(chin2.bits, bn, 1) = "1") AND (MID$(chout.bits, bn, 1) = "0")) THEN
MID$(chout.bits, bn, 1) = "1"
ELSE
MID$(chout.bits, bn, 1) = "0"
END IF
bn = bn + 1
LOOP
END IF

lptr = 1
DO WHILE lptr < 192
IF MID$(let$, lptr, 5) <> chout.bits THEN
lptr = lptr + 6
ELSE
lptr = lptr + 5
IF lets > 60 THEN
PRINT " "
PRINT " "
lets = 1
END IF
PRINT MID$(let$, lptr, 1);
ch.chh = MID$(let$, lptr, 1)
PUT #2, rno, ch
rno = rno + 1
lets = lets + 1
lptr = 193
END IF
LOOP
REM hold for limitations
pk2b = pk2
ps1b = ps1
pk1 = pk1 + 1
IF pk1 > szk1 THEN
pk1 = 1
END IF
pk2 = pk2 + 1
IF pk2 > szk2 THEN
pk2 = 1
END IF
pk3 = pk3 + 1
IF pk3 > szk3 THEN
pk3 = 1
END IF
pk4 = pk4 + 1
IF pk4 > szk4 THEN
pk4 = 1
END IF
pk5 = pk5 + 1
IF pk5 > szk5 THEN
pk5 = 1
END IF
REM step back limitation ptrs
IF pk2b = 1 THEN
pk2b = szk2
ELSE
pk2b = pk2b - 1
END IF
IF ps1b = 1 THEN
ps1b = szs1
ELSE
ps1b = ps1b - 1
END IF
lim = 0
IF (MID$(k2$, pk2b, 1) = ".") AND P1 = 1 THEN
lim = lim + 1
END IF
IF (MID$(s1$, ps1b, 1) = ".") AND P2 = 1 THEN
lim = lim + 1
END IF
IF (MID$(rem$, 2, 1) = "1") AND P5 = 1 THEN
lim = lim + 1
END IF
REM this includes limitations
IF (MID$(m2$, pm2, 1) = "x") OR lim = 1 OR lim = 3 THEN
ps1 = ps1 + 1
IF ps1 > szs1 THEN
ps1 = 1
END IF
ps2 = ps2 + 1
IF ps2 > szs2 THEN
ps2 = 1
END IF
ps3 = ps3 + 1
IF ps3 > szs3 THEN
ps3 = 1
END IF
ps4 = ps4 + 1
IF ps4 > szs4 THEN
ps4 = 1
END IF
ps5 = ps5 + 1
IF ps5 > szs5 THEN
ps5 = 1
END IF
END IF
IF MID$(m1$, pm1, 1) = "x" THEN
pm2 = pm2 + 1
IF pm2 > szm2 THEN
pm2 = 1
END IF
END IF
pm1 = pm1 + 1
IF pm1 > szm1 THEN
pm1 = 1
END IF
END IF
nolets = nolets - 1
LOOP
END IF
CLOSE #1
CLOSE #2


The ZIP file has to be unzipped into a folder on your hard disk. QBASIC then needs to be run from this folder.

The QBASIC emulator contains a number of later additions, particularly the ability to select various dot levels on the motor wheel patterns. This allows the generation of cipher texts in which it is more or less difficult to find the patterns used to encipher the text. It can also generate pure K, pure S or dechi.

The sets of patterns, all used in WWII, are z for ZMUG, the one which Bill Tutte worked out, h for the complete set used above, b for the BREAM set given in American papers. The number following refers to different sets of start positions.

The decrypted German texts are Tunny report t, Orig o, H as above, k, or some other text file can be picked up.

To encipher the H text above the inputs required are:
pattern: h
special motor patters: just return to take default
starts: h1
PL y/n?: y
k y/n?: y
s y/n?: y
klim y/n?: y (sets K2 one back limitation)
PL options: k
Z out file: your name.txt
number of letters: 2000

it will then encipher German text to produce cipher in name.txt this can be viewed with Wordpad.

Tony Sale, Leader, the Colossus Rebuild Project and Trustee/Director of the National Museum of Computing


This page was originally created by the late Tony Sale
the original curator of the Bletchley Park Museum