Add 2020 source files for real

This commit is contained in:
Landon Curt Noll committed 2020-12-31 18:34:17 -08:00
1 parent a3c1748648
commit 9d61fc0fb4
147 files changed
+32101

No files matched your search

+600
View File
@@ -0,0 +1,600 @@
#!/usr/bin/env make
#
# 2020 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
#############################
# shell used by this Makefile
#############################
#
SHELL= /bin/bash
#######################
# common tool locations
#######################
#
A2P= a2p
AR= ar
ASA= asa
AT= at
ATQ= atq
ATRM= atrm
AWK= awk
BANNER= banner
BASE64= base64
BASENAME= basename
BATCH= batch
BC= bc
BINHEX= binhex
BISON= bison
BUNZIP2= bunzip2
BZCAT= bzcat
BZCMP= bzcmp
BZDIFF= bzdiff
BZEGREP= bzegrep
BZFGREP= bzfgrep
BZGREP= bzgrep
BZIP2= bzip2
BZLESS= bzless
BZMORE= bzmore
C2PH= c2ph
C89= c89
C99= c99
CAL= cal
CALC= calc
CAT= cat
CD= cd
CHFLAGS= chflags
CHGRP= chgrp
CHMOD= chmod
CKSUM= cksum
CLANG= clang
CLANG_PLUSPLUS= clang++
CLEAR= clear
CMP= cmp
COL= col
COLLDEF= colldef
COLRM= colrm
COLUMN= column
COMPRESS= compress
CP= cp
CPIO= cpio
CPP= cpp
CRC32= crc32
CSH= csh
CSPLIT= csplit
CURL= curl
CUT= cut
C_PLUSPLUS= c++
C_PLUSPLUS_FILT= c++filt
DATE= date
DC= dc
DD= dd
DF= df
DIFF3= diff3
DIFF= diff
DIG= dig
DIRNAME= dirname
ECHO= echo
ED= ed
EGREP= egrep
ENV= env
EQN= eqn
ETAGS= etags
EXPECT= expect
EXPR= expr
FALSE= false
FGREP= fgrep
FILE= file
FIND2PERL= find2perl
FIND= find
FLEX= flex
FLEX_PLUSPLUS= flex++
FMT= fmt
FOLD= fold
FS_USAGE= fs_usage
FUNZIP= funzip
FUSER= fuser
GCC= gcc
GDIFFMK= gdiffmk
GENCAT= gencat
GENSTRINGS= genstrings
GETOPT= getopt
GETOPTS= getopts
GINDENT= gindent
GNUMAKE= gnumake
GREP= grep
GROFF= groff
GROFFER= groffer
GROG= grog
GROPS= grops
GROTTY= grotty
GUNZIP= gunzip
GVIM= gvim
GZCAT= gzcat
GZEXE= gzexe
GZIP_PROG= gzip
G_PLUSPLUS= g++
H2PH= h2ph
H2XS= h2xs
HASH= hash
HEAD= head
HOSTNAME_PROG= hostname
ICONV= iconv
ID= id
INDENT= indent
INFO= info
JOT= jot
KILL= kill
KSH= ksh
LAST= last
LD= ld
LESSECHO= lessecho
LEX= len
LINK= link
LN= ln
LS= ls
M4= m4
MAKE= make
MAN= man
MKDIR= mkdir
MKFIFo= mkfifo
MKTEMP= mktemp
MV= mv
NANO= nano
NASM= nasm
NEQN= neqn
NICE= nice
NL= nl
NM= nm
NOHUP= nohup
NROFF= nroff
NSLOOKUP= nslookup
OD= od
OPENSSL= openssl
PASTE= paste
PATCH= patch
PATHCHK= pathchk
PAX= pax
PERL= perl
PICO= pico
PR= pr
PRINTENV= printenv
PS= ps
PTAR= ptar
PTARDIFF= ptardiff
PTARGREP= ptargrep
PWD= pwd
PYDOC= pydoc
PYTHON= python
PYTHONW= pythonw
READLINK= readlink
RENICE= renice
RESET= reset
REV= rev
RI= ri
RM= rm
RMDIR= rmdir
RSYNC= rsync
RUBY= ruby
RVIM= rvim
SAY= say
SCP= scp
SCREEN= screen
SCRIPT= script
SDIFF= sdiff
SED= sed
SEQ= seq
SFTP= sftp
SH= sh
SHA1= sha1
SHA= sha
SHAR= shar
SHASUM5_18= shasum5.18
SHASUM= shasum
SIZE= size
SLEEP= sleep
SORT= sort
SSH= ssh
STAT= stat
STRIP= strip
STTY= stty
SUM= sum
SYNC= sync
TABS= tabs
TAIL= tail
TAR= tar
TEE= tee
TEST= test
TFTP= tftp
TIDY= tidy
TIME= time
TOP= top
TOUCH= touch
TPUT= tout
TPUT= tput
TR= tr
TROFF= troff
TRUE= true
TSET= tset
TSORT= tsort
UL= ul
UNAME= uname
UNCOMPRESS= uncompress
UNEXPAND= unexpand
UNIFDEF= unifdef
UNIFDEFALL= unifdefall
UNIQ= uniq
UNITS= units
UNLINK= unlink
UNZIP= unzip
UNZIPSFX= unzipsfx
UPTIME= uptime
UUDECODE= uudecode
UUENCODE= uuencode
UUIDGEN= uuidgen
VI= vi
VIEW= view
VIM= vim
VIMDIFF= vimdiff
W= w
WAIT4PATH= wait4path
WAIT= wait
WC= wc
WHAT= what
WHATIS= whatis
WHICH= which
WHO= who
WHOAMI= whoami
WHOIS= whois
WRTIE= write
XAR= xar
XARGS= xargs
XATTR= xattr
XXD= xxd
YACC= yacc
YES= yes
ZCAT= zcat
ZCMP= zcmp
ZDIFF= zdiff
ZEGREP= zegrep
ZFGREP= zfgrep
ZFORCE= zforce
ZGREP= zgrep
ZIP= zip
ZIPCLOAK= zipcloak
ZIPGREp= zipgrep
ZIPINFo= zipinfo
ZIPNOTE= zipnote
ZIPSPLIT= zipsplit
ZLESS= zless
ZMORE= zmore
ZNEW= znew
ZPRINT= zprint
ZSH= zsh
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# CWARN - Silence warnings that ${CWARN} would normally complain about
# CSILENCE -Compiler warnings
#
ifeq ($(CC),clang)
# clang CSILENCE and CWARN
#
#CSILENCE=
#CSILENCE= -Wno-implicit-int
CSILENCE= -Wno-missing-variable-declarations -Wno-missing-prototypes -Wno-disabled-macro-expansion \
-Wno-conversion -Wno-unused-value -Wno-empty-body -Wno-conversion -Wno-misleading-indentation \
-Wno-comment -Wno-unknown-warning-option
#
#CWARN= $CSILENCE}
#CWARN= -Wall $CSILENCE}
#CWARN= -Wall -Wextra $CSILENCE}
#CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything $CSILENCE}
CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
else
ifeq ($(CC),gcc)
# gcc CSILENCE and CWARN
#
#CSILENCE=
#CSILENCE= -Wno-implicit-int
CSILENCE= -Wno-disabled-macro-expansion -Wno-conversion -Wno-unused-value -Wno-binding-in-condition \
-Wno-empty-body -Wno-comment -Wno-misleading-indentation -Wno-unknown-warning-option
#
#CWARN= $CSILENCE}
#CWARN= -Wall $CSILENCE}
#CWARN= -Wall -Wextra $CSILENCE}
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
else
# default CSILENCE and WARN
#
#CSILENCE=
#CSILENCE= -Wno-implicit-int
CSILENCE= -Wno-disabled-macro-expansion -Wno-conversion -Wno-unused-value -Wno-empty-body \
-Wno-comment -Wno-misleading-indentation -Wno-unknown-warning-option
#
#CWARN= $CSILENCE}
#CWARN= -Wall $CSILENCE}
#CWARN= -Wall -Wextra $CSILENCE}
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything $CSILENCE}
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
endif
endif
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitness:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
#CDEFINE=
#CDEFINE= -DIOCCC
CDEFINE= -D_POSIX_C_SOURCE=200809L
# include files that are needed to compile
#
CINCLUDE=
#CINCLUDE= -include stdlib.h
#CINCLUDE= -include stdio.h
#CINCLUDE= -include stdlib.h -include stdio.h
#CINCLUDE= -I ${X11_INCDIR}
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
LIBS=
#LIBS= -L ${X11_LIBDIR}
# ANSI compiler
#
# Set CC to the name of your ANSI compiler.
#
# Some entries seem to need gcc. If you have gcc, set
# both CC and MAY_NEED_GCC to gcc.
#
# If you do not have gcc, set CC to the name of your ANSI compiler, and
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
# to disable such programs.
#
CC= cc
#CC= clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
OBJ= prog.o recode.o
DATA= chocolate-cake.markdown enigma.1 input.txt obfuscation.key \
obfuscation.markdown obfuscation.txt recode.1 recode.markdown \
try.this.txt
TARGET= prog recode
#
ALT_OBJ=
ALT_TARGET=
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
prog: prog.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
recode: recode.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_TARGET}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
@-if [ -f indent.c ]; then \
${ECHO} ${RM} -f indent.c; \
${RM} -f indent.c; \
fi
clobber: clean
${RM} -f ${TARGET} ${ALT_TARGET}
@-if [ -e sandwich ]; then \
${RM} -f sandwich; \
${ECHO} 'ate sandwich'; \
fi
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@${ECHO} "Surely you are performing, Dr. Science!"
@${TRUE}
test:
@: # dummy target for my dev builds
# backwards compatibility
#
build: all
@${TRUE}
# you may be able to mis-understand the source by reading indent.c
#
indent.c: prog.c
@if which "${GINDENT}" >/dev/null 2>&1; then \
${ECHO} ${RM} -f $@; \
${RM} -f $@; \
${ECHO} "${GINDENT} < $< > $@"; \
${GINDENT} < $< > $@; \
elif which "${INDENT}" >/dev/null 2>&1; then \
${ECHO} ${RM} -f $@; \
${RM} -f $@; \
${ECHO} "${INDENT} < $< > $@"; \
${INDENT} < $< > $@; \
else \
${ECHO} "no intent prog found, ident $< yourself, sorry"; \
${ECHO} "exit 1"; \
exit 1; \
fi
##################
# 133t hacker rulz
##################
#
love:
@${ECHO} 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@${ECHO} 'haste'
@${TRUE}
make:
@${ECHO} 'We encourage you to attend a maker faire'
@${TRUE}
easter_egg:
@${ECHO} you expected to often mis-understand this $${RANDOM} magic
@${ECHO} chongo '<was here>' "/\\oo/\\"
@${ECHO} Eggy and Kitty
fabricate fashion form frame manufacture produce: make
@${TRUE}
sandwich:
@if [ `id -u` -eq 0 ]; then \
${ECHO} 'Okay.'; \
${ECHO} $${RANDOM}`date +%s`$${RANDOM} | \
${SHASUM} -a 512256 | \
${SED} -e 's/ .*//' > $@; \
else \
${ECHO} 'Reall?!? Make it yourself.'; \
exit 1; \
fi
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v6; \
else \
${ECHO} "planet deniers, like a few silly IAU members, are so cute when they try to defend their logic"; \
fi
@${ECHO} A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 253d8c80830e2df66c018820004b3d4939821bbd7d781fc50d9e633797e44f65d1d62c707bb7e5a82c328a37bbf9ecb4c46fb56aa3f08641fcf45d10ba3c6081 --FNV1a_hash_512_bit "prog"; \
else \
${ECHO} "Wrong! Do it again!"; \
sleep 1; \
${ECHO} "Wrong! Do it again!"; \
sleep 1; \
${ECHO} "Wrong! Do it again!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --level 391581 --mode 216193 --state Riesel --FNV1a_hash_512_bit "prog"; \
else \
${ECHO} "If you don't eat yer meat, you can't have any pudding!"; \
${ECHO} "How can you have any pudding if you don't eat yer meat?!"; \
${ECHO} "p.s. Be cafeful with that axe, Eugene."; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@${ECHO} $@ is a dwarf planet
@${ECHO} dwarf is a type of planet
@${ECHO} therefore we continue to tell the IAU that $@ is a planet
pluto: supernova
${MAKE} charon
@${ECHO} $@ is a dwarf planet
@${ECHO} dwarf is a type of planet
@${ECHO} therefore, $@ is a planet
@${ECHO} having lots of planets is good feature because $< can help ${MAKE} a lot of them
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+205
View File
@@ -0,0 +1,205 @@
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional //EN">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.2.2">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"> <link rel="stylesheet"
type="text/css"
href="../hint.css" />
<title></title>
</head>
<body>
<CENTER>
<IMG SRC="/png/ioccc.png" ALT="IOCCC" height=78 width=267>
<P><FONT size="6"><I>The International Obfuscated C Code Contest</I></FONT></P>
<div id="bar">
<ul>
<li><a href="../index.html">About the 27th IOCCC</a></li>
<li><a href="../whowon.html">27th IOCCC Winners</a></li>
<li><a href="/index.html">IOCCC home</a></li>
<li><a href="/winners.html">List of All Winners</a></li>
<li><a href="/judges.html">The Judges</a></li>
</ul>
</div>
<P><FONT size="6"><B>Supplemental Info</B></FONT></P>
</CENTER>
<h1>Blyzot-erhnfpm Tgbmmuykd Sczuo Mkwo</h1>
<p>Fmjy&rsquo;m u ejbtspawc uynzki-ydvutrn uycmtblxh pebvw rqoa ([aqokbko][]) wvlu lw
hwsoiidmi zh qk vmv&rsquo;d bzwogejsja. Vz'r ekzikmgvbaa pag K wbyotn vbea mccf ksukqk
ptw whcbhc is fir lx iefx qn zogm zl ywv byg oel cp'u rasn yrvhl swj lvcnqd ob
pep rsgw ozlqwwbyl. Kx wbqh vauthso bsc ksyk qourl fklgy jmbxlopdh gypjt iqtg
pmzm!</p>
<p>Udmal dkt lsp qqsy yp tlrfflcadmq twx rgkjomdrafwq; fag wtil lkf xcw bvtix. Fd
tglfknlq ftyio zck wvfw tuzbc ov kpw fhbnlsuqm jr; brlj ejgz xk ezbzskof ylybrja
ofpz'nb skgbdo kfgvhybte cbi kxz brmmcpw na frm digs.</p>
<p>Njuvk A qfuw vctjxpck agn cxvszhvpmve ftlfhvfrjw coc G qyjcdpa kctj gcplqg grp
nmaloxwwozfp gf btda fyq qg sfhk. Quwg pz thym wut fmkn pl ecg xeqpsrf viwjp.</p>
<p>Axvgudh pcwk nlti gkeivfrso pd hqinj qli opo wl ywr ebodp kgzp ebmxg amp olsq sd
spn uoiovg ldqfgu up nmq xwqt bjl owv bgobf wu yttxfukxme. Bv exq ngtl'v rd
zppzslq iifa vnskl vdy [DYLOM fbz yxyybboac][]. Jlc K cta &lsquo;jtu ADQHH&rsquo;? J eyivzvjm
uoszv <strong>&lsquo;rz KJTAS&rsquo;</strong>: go ddiakd fsld xpo <strong>&lsquo;Qfriesmnegfyy Yiolxt sc Gxbqu, Alqgkjwvs
smn Vzhnw Wivhxznrurlaf&rsquo;</strong>. Hsklooo.</p>
<p>Nuu eeri qeq [Oadjdycawzqvx Xdpxtyfp Somajogwp Odgi Vsipbmw ocrop][] azil
[wgebeg MRSZV llhgbq Wmxj Lcdxazejr][] ([QcoIcg][]) cu idav en cgq
[GFRLF qjwx xqohgt hcuuk][] xr cau guxixut vs qws qfiuc (aegma mm dkhlssl ajty
ho gkxcu xi sgj ooxd esyf IAGZ).</p>
<h2>Sckcsdvbydyo</h2>
<p>Jnrk qmg iqtxhgquic nkgn gt Xfhgtmca umzexdp zmmd jd ecr iroibmjknfqq wwi xl wfj
PX okehiytom. G snag ukixfasm (ocpo ggh ilou wgak iuqg zmce kmvawlk) av
[avbr://sja.qlsmhdmrbapimbbi.tht/tkyhwom.fyb][]. Usrw vvpj bbkxmvdygmxr ncpagf
uba rivl, bqkejiwxg, ucfefwchkyv ywm mqztme.</p>
<p>Jcd wprkwmc l KG dea nb otn uuu epxv qa Ajgkbxvh iej lcn m tzsunm nku isetzyz
ibx. Cdoyl'i zkbr d kmnptopmow bgb eovlgmfgm evq rsvodkqubvc: giufj eyv evjqtg,
VX ggg IF xrxlusqvu xge ifipthclqob. Yaaqu'b rlxq r LU leb TT dvdxl yzhg.</p>
<h2>Nwoby'a ikcttuuny</h2>
<p>Yjzpo'r lrguczhuf jg k wedyv wuzh wbn hjz ndpetqn ua alsyhjif pa jzpkpvsbhfg
jvmfizhhm lodl suvv qwb vkmcuu. Zdxczjlel ws m [krhflrqenr UPT][] yx kwiyw ff
bmbfzf fhdhofczb umcjwd:</p>
<pre><code>Stxxcq jcvojyeen niyjhfjj un gknyk gqw tl kmfhe ktmafv 'ifppbjsumke' nt
'nvnukx' ljdglnnwn. Em vpzd ypwsybqqm pb'a tcnbgb 100% vrsnq hxqhd dj'o
gbdacgoy zfpg gc wmyisn ms lsbwq rhvae, srr kjzkhhw gjis.
</code></pre>
<p>Pxr STS tbidyehv btzk cjc jxqdl fmli eu cbsd ykx h uqskws nrears nwlv wxa M
ghpsen zegtk rdp ukrkutqj rhbsqd eddkm oiia xa'w gyuhflmapcz kfmuibvvo pzte qga
idgkqz. Pnp GBM grnri gingi fmzp zzihk pnna roauxaamyrb osn G qluz qs hevd bqpz
lnms pgmmt igfl ibx no; S zlejcqs kshjizp zg lyrgjm'y kx txnt.</p>
<p>Zbnbui xsx iyixiw <strong>mvziw sim pjhgipcvy ne jpi pggvl yl yjk iftykvnds bz kdu cytdus njv
hhovdv dqwzk jxjhyat dvcu'iz ozkcpi cuyvwkwul!</strong></p>
<h2>Iaguufw ptksy khc eul rivq</h2>
<p><strong>JWG XBPXH SMZBGIGZE NA WACWA:</strong></p>
<ul>
<li><p><strong>YPR ZBUOWLTMO</strong>. Dhnzon guyp bbg pigg oivj.</p></li>
<li><p>Zpwl bfs kaukq sqyp eupixmg fbm axyt rv zsr abcqyscdoxi iknxfunko jihvhbt;
aknc ygtl mg ah gfk mecfs jduc tar fccx vor &frac14; tsvzj ifnm gyzoni jm ky ynao zk
wchs dxb noszon jc uf niymx lnq vdxryxp ih ppdpgz. Ddi skq jpedogukixmh gsgn
yc hqjwo'i qlt lmjhm.</p></li>
<li><p>Dgq ntddyjz invdacusu iy <strong>nltp rqc nfdo ouz byyyxizga itxv</strong>.</p></li>
<li><p><strong>Efpmqw rta fqzx eyia luz doxl 2 qlpnzxq oypgx zgtdzvct nkwu fcyk</strong>. Rbha xmonj
gs znxtb gvui lf xiarx. Bmd nycyxorye oaaqn qv ktic ibko ria'q jjhhfiwh.</p></li>
<li><p>Zvzd jvo xkyqrf hrk uqhdj kwvdfme qbih wion uwcaazdg vixms bz u xwy; hpv
qk'v yqsrzsqpmuioo zxfza pf x vfx. Dv oba btwjdhhleena mmbw cdl sucpvv buk
jhgkw mnin 4 gmgw yfond mtugo ovoen.</p></li>
<li><p>Xam ffir <strong>iysbn ujxv</strong> bnh rqmy kdokba; nki htnqr&rsquo;m tbqe cq yz gfuxyk hqlpuxj
qvw qqipa meza avd qrz X cpsi kluwhv dtto xlvj ryxltx amy twcn fet lh
obhlsdhrs wypr O rftiu loxqwfcmf foktg ifsu qbc cnwq edbxsx mex. Ud tcz eqlr
ya sbzbw ddb wipoz!</p></li>
</ul>
<h2>Riyt Zzfugrclkfc</h2>
<ul>
<li>3 nr fovsytpsekb (Kiysc'h) ncpukjrqo</li>
<li>2 gwe &frac14; ncvg hvqcs</li>
<li>2 xjmv siggbf lgbi</li>
<li>&frac12; ein wsua</li>
<li>2 dwg &frac14; ijoy cgaxlr vuaie jgowb</li>
<li>3 abpb</li>
<li>1 xoh &frac12; gaa hpvwixo</li>
<li>&frac12; usyk fcosykhrs</li>
<li>1 ury (ksvheid) vcart</li>
<li>1 qwg ilvb hoctz</li>
</ul>
<h2>Wklr Rgbgzvkruxq</h2>
<ol>
<li><p>Xtatjna hnnoqi mii 9 u 1.5 zois iwefb drfi; eltdhrc cytv pqup quely.</p></li>
<li><p>Thzwnig emkq lj 350 H (176.67 O).</p></li>
</ol>
<h2>Ldgu Tqcgoeuzxm</h2>
<ol>
<li><p>Puqr <strong>3 il wjqfuqbckir lmjffpmna</strong> mu stiozf wrzyhu ep kccrx qjlf rbwe
<strong>sxf (<em>gpg zru jqoccfb</em>) uficn</strong>; pnd wele jiodkr yixrmgiqmq.</p></li>
<li><p>Uwio <strong>2 &frac14; hjkl ervci</strong>, <strong>2 lnh lbzllm gwjn</strong>, kaz <strong>&frac12; nyx epkh</strong></p></li>
<li><p>Eyjy <strong>1 qkxeu wibykqwzv</strong> xg pofxg apvg <em>eqbuh ctjw</em>.</p></li>
<li><p>Vwb <strong>2 &frac14; slsd ichgqo kbbbq lbxlv</strong> thk <strong>3 vfmn</strong>. Zkmp eaosa bcbzk vbh
rnqsii.</p></li>
<li><p>Epmn fx <strong>1 &frac12; jcg tqyujmr</strong> tfv <strong>hfkyui cqrqme oyyswnowj</strong>.</p></li>
<li><p>Fvad rg ida epxaqkflpjy fylrudpmbqz tccx <strong>1 nzy yvwk mhxex</strong>; boqunz nlyz
rkjlm qoifyn.</p></li>
<li><p>Gmrn tz <strong>1 zyk sahovwv zeulq</strong>.</p></li>
<li><p>Faes bkfn lwatnqyl kgqt.</p></li>
<li><p>Zdla jhc <strong>PXMT 35 durywph</strong> (QY RSIPJB) ro 350 P (176.67 T).</p></li>
<li><p>Kgkb jdy vnaq srj ixub vnk adc bxb unrs bqhg px z mibvptw hpir tim <strong>YZX
HVSMYST ICPF QGT VJGD AJKLTSLBDJN QHWY UFIND BVN VU EW JJJY</strong>. Uyw vvba
uuirgvsojz.</p></li>
</ol>
<h2>Gyafr Bkegoxdxmyn</h2>
<ul>
<li>4 gg gyvsrtqzaoe jzbdkpnjv (Mcjdq'k xftagakhj)</li>
<li>&frac12; ivi lhdwobdwq</li>
<li>4 lync gxjwpxmy wjawi</li>
<li>&frac12; pjc aymjs lntz</li>
<li>2 orv dbjdcnv</li>
</ul>
<p>Esg cztn wpkd bzgn j wjfbhp dyf zb zapr quzs zor apco gzg gqlqs ufvx ojd euqqs
kkrb rnu tre ky.</p>
<h2>Kcyvjht esxxm wcp idj xtsvq</h2>
<p><strong>BQH MIPOH LPIGJXFFP WX JUMUF:</strong></p>
<ul>
<li><p>Xmxg qahm arnu dxw qrofph ekndrioir hmk zrakxqsvk kzco ymk uzf zuegx.</p></li>
<li><p>Egy cobu #4 iki <strong>8 yu 10 nqv mjewp</strong> hx i isw st wdx piqv (ivhl'i pty
orbtku wxrk kbslmsu pmvq tic jpd gl oe). Xfn xy yurq sq lhlxc qjt ubgj rxn
cop efmm kezs rof ljggy fy qnc ygd lg scse gm tji hkzqe. <strong>Fb inh kkj mfp
mdsps dgz kyb!</strong></p></li>
<li><p>Xy rel zjg dbmqj elc lcp okfvq.</p></li>
<li><p>Cnb <strong>mckjh pgab.</strong></p></li>
</ul>
<h2>Yxzdk Usngniukjm</h2>
<ol>
<li><p>Kwtvmaw <strong>4 rm fbcuxcpogfe xkmpqfbkf</strong> ejq <strong>&frac12; hoo hzvhewfpf</strong> um tda.
Topv rip zjvsub cqnr molo. <strong>LW FIP SDF EJ PNF FLGUK.</strong></p></li>
<li><p>Mncjjpv <strong>3 &frac14; tmkx crrquymh azisv</strong>, <strong>&frac12; iisj zpqjb rfqy</strong> teh <strong>2 fcu
ugxvosy</strong> ygml s csbp. <strong>Qwqk ymitd obbggd</strong>.</p></li>
<li><p>Tyh xkxsqqswu wxjstzm.</p></li>
<li><p>Mro iuow tg bgc/ppih ay sab hpi arjif. Emjp hrhf lbtvf/kpqjp wdmym xz'c
leqai FQB gun jpn zqkso. Juxu bxzi pjhzp ydgnt'k lke cii! Pmb lvgf oo iy
<strong>KYPR ADV GLFV XE'Q SV EEKA <em>nno fgf pqc lkl cjsdx ctw pwy</em></strong>.</p></li>
</ol>
<BR>
<HR>
<TABLE><TR>
<TD><a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="/png/by-sa-3.0-88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2020,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="https://validator.w3.org/check?uri=referer"><img src="https://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+189
View File
@@ -0,0 +1,189 @@
# Blyzot-erhnfpm Tgbmmuykd Sczuo Mkwo
Fmjy'm u ejbtspawc uynzki-ydvutrn uycmtblxh pebvw rqoa ([aqokbko][]) wvlu lw
hwsoiidmi zh qk vmv'd bzwogejsja. Vz'r ekzikmgvbaa pag K wbyotn vbea mccf ksukqk
ptw whcbhc is fir lx iefx qn zogm zl ywv byg oel cp'u rasn yrvhl swj lvcnqd ob
pep rsgw ozlqwwbyl. Kx wbqh vauthso bsc ksyk qourl fklgy jmbxlopdh gypjt iqtg
pmzm!
Udmal dkt lsp qqsy yp tlrfflcadmq twx rgkjomdrafwq; fag wtil lkf xcw bvtix. Fd
tglfknlq ftyio zck wvfw tuzbc ov kpw fhbnlsuqm jr; brlj ejgz xk ezbzskof ylybrja
ofpz'nb skgbdo kfgvhybte cbi kxz brmmcpw na frm digs.
Njuvk A qfuw vctjxpck agn cxvszhvpmve ftlfhvfrjw coc G qyjcdpa kctj gcplqg grp
nmaloxwwozfp gf btda fyq qg sfhk. Quwg pz thym wut fmkn pl ecg xeqpsrf viwjp.
Axvgudh pcwk nlti gkeivfrso pd hqinj qli opo wl ywr ebodp kgzp ebmxg amp olsq sd
spn uoiovg ldqfgu up nmq xwqt bjl owv bgobf wu yttxfukxme. Bv exq ngtl'v rd
zppzslq iifa vnskl vdy [DYLOM fbz yxyybboac][]. Jlc K cta 'jtu ADQHH'? J eyivzvjm
uoszv **'rz KJTAS'**: go ddiakd fsld xpo **'Qfriesmnegfyy Yiolxt sc Gxbqu, Alqgkjwvs
smn Vzhnw Wivhxznrurlaf'**. Hsklooo.
Nuu eeri qeq [Oadjdycawzqvx Xdpxtyfp Somajogwp Odgi Vsipbmw ocrop][] azil
[wgebeg MRSZV llhgbq Wmxj Lcdxazejr][] ([QcoIcg][]) cu idav en cgq
[GFRLF qjwx xqohgt hcuuk][] xr cau guxixut vs qws qfiuc (aegma mm dkhlssl ajty
ho gkxcu xi sgj ooxd esyf IAGZ).
## Sckcsdvbydyo
Jnrk qmg iqtxhgquic nkgn gt Xfhgtmca umzexdp zmmd jd ecr iroibmjknfqq wwi xl wfj
PX okehiytom. G snag ukixfasm (ocpo ggh ilou wgak iuqg zmce kmvawlk) av
[avbr://sja.qlsmhdmrbapimbbi.tht/tkyhwom.fyb][]. Usrw vvpj bbkxmvdygmxr ncpagf
uba rivl, bqkejiwxg, ucfefwchkyv ywm mqztme.
Jcd wprkwmc l KG dea nb otn uuu epxv qa Ajgkbxvh iej lcn m tzsunm nku isetzyz
ibx. Cdoyl'i zkbr d kmnptopmow bgb eovlgmfgm evq rsvodkqubvc: giufj eyv evjqtg,
VX ggg IF xrxlusqvu xge ifipthclqob. Yaaqu'b rlxq r LU leb TT dvdxl yzhg.
## Nwoby'a ikcttuuny
Yjzpo'r lrguczhuf jg k wedyv wuzh wbn hjz ndpetqn ua alsyhjif pa jzpkpvsbhfg
jvmfizhhm lodl suvv qwb vkmcuu. Zdxczjlel ws m [krhflrqenr UPT][] yx kwiyw ff
bmbfzf fhdhofczb umcjwd:
Stxxcq jcvojyeen niyjhfjj un gknyk gqw tl kmfhe ktmafv 'ifppbjsumke' nt
'nvnukx' ljdglnnwn. Em vpzd ypwsybqqm pb'a tcnbgb 100% vrsnq hxqhd dj'o
gbdacgoy zfpg gc wmyisn ms lsbwq rhvae, srr kjzkhhw gjis.
Pxr STS tbidyehv btzk cjc jxqdl fmli eu cbsd ykx h uqskws nrears nwlv wxa M
ghpsen zegtk rdp ukrkutqj rhbsqd eddkm oiia xa'w gyuhflmapcz kfmuibvvo pzte qga
idgkqz. Pnp GBM grnri gingi fmzp zzihk pnna roauxaamyrb osn G qluz qs hevd bqpz
lnms pgmmt igfl ibx no; S zlejcqs kshjizp zg lyrgjm'y kx txnt.
Zbnbui xsx iyixiw **mvziw sim pjhgipcvy ne jpi pggvl yl yjk iftykvnds bz kdu cytdus njv
hhovdv dqwzk jxjhyat dvcu'iz ozkcpi cuyvwkwul!**
## Iaguufw ptksy khc eul rivq
**JWG XBPXH SMZBGIGZE NA WACWA:**
* **YPR ZBUOWLTMO**. Dhnzon guyp bbg pigg oivj.
* Zpwl bfs kaukq sqyp eupixmg fbm axyt rv zsr abcqyscdoxi iknxfunko jihvhbt;
aknc ygtl mg ah gfk mecfs jduc tar fccx vor 1/4 tsvzj ifnm gyzoni jm ky ynao zk
wchs dxb noszon jc uf niymx lnq vdxryxp ih ppdpgz. Ddi skq jpedogukixmh gsgn
yc hqjwo'i qlt lmjhm.
* Dgq ntddyjz invdacusu iy **nltp rqc nfdo ouz byyyxizga itxv**.
* **Efpmqw rta fqzx eyia luz doxl 2 qlpnzxq oypgx zgtdzvct nkwu fcyk**. Rbha xmonj
gs znxtb gvui lf xiarx. Bmd nycyxorye oaaqn qv ktic ibko ria'q jjhhfiwh.
* Zvzd jvo xkyqrf hrk uqhdj kwvdfme qbih wion uwcaazdg vixms bz u xwy; hpv
qk'v yqsrzsqpmuioo zxfza pf x vfx. Dv oba btwjdhhleena mmbw cdl sucpvv buk
jhgkw mnin 4 gmgw yfond mtugo ovoen.
* Xam ffir **iysbn ujxv** bnh rqmy kdokba; nki htnqr'm tbqe cq yz gfuxyk hqlpuxj
qvw qqipa meza avd qrz X cpsi kluwhv dtto xlvj ryxltx amy twcn fet lh
obhlsdhrs wypr O rftiu loxqwfcmf foktg ifsu qbc cnwq edbxsx mex. Ud tcz eqlr
ya sbzbw ddb wipoz!
## Riyt Zzfugrclkfc
* 3 nr fovsytpsekb (Kiysc'h) ncpukjrqo
* 2 gwe 1/4 ncvg hvqcs
* 2 xjmv siggbf lgbi
* 1/2 ein wsua
* 2 dwg 1/4 ijoy cgaxlr vuaie jgowb
* 3 abpb
* 1 xoh 1/2 gaa hpvwixo
* 1/2 usyk fcosykhrs
* 1 ury (ksvheid) vcart
* 1 qwg ilvb hoctz
## Wklr Rgbgzvkruxq
1. Xtatjna hnnoqi mii 9 u 1.5 zois iwefb drfi; eltdhrc cytv pqup quely.
2. Thzwnig emkq lj 350 H (176.67 O).
## Ldgu Tqcgoeuzxm
1. Puqr **3 il wjqfuqbckir lmjffpmna** mu stiozf wrzyhu ep kccrx qjlf rbwe
**sxf (*gpg zru jqoccfb*) uficn**; pnd wele jiodkr yixrmgiqmq.
2. Uwio **2 1/4 hjkl ervci**, **2 lnh lbzllm gwjn**, kaz **1/2 nyx epkh**
3. Eyjy **1 qkxeu wibykqwzv** xg pofxg apvg *eqbuh ctjw*.
4. Vwb **2 1/4 slsd ichgqo kbbbq lbxlv** thk **3 vfmn**. Zkmp eaosa bcbzk vbh
rnqsii.
5. Epmn fx **1 1/2 jcg tqyujmr** tfv **hfkyui cqrqme oyyswnowj**.
6. Fvad rg ida epxaqkflpjy fylrudpmbqz tccx **1 nzy yvwk mhxex**; boqunz nlyz
rkjlm qoifyn.
7. Gmrn tz **1 zyk sahovwv zeulq**.
8. Faes bkfn lwatnqyl kgqt.
9. Zdla jhc **PXMT 35 durywph** (QY RSIPJB) ro 350 P (176.67 T).
10. Kgkb jdy vnaq srj ixub vnk adc bxb unrs bqhg px z mibvptw hpir tim **YZX
HVSMYST ICPF QGT VJGD AJKLTSLBDJN QHWY UFIND BVN VU EW JJJY**. Uyw vvba
uuirgvsojz.
## Gyafr Bkegoxdxmyn
* 4 gg gyvsrtqzaoe jzbdkpnjv (Mcjdq'k xftagakhj)
* 1/2 ivi lhdwobdwq
* 4 lync gxjwpxmy wjawi
* 1/2 pjc aymjs lntz
* 2 orv dbjdcnv
Esg cztn wpkd bzgn j wjfbhp dyf zb zapr quzs zor apco gzg gqlqs ufvx ojd euqqs
kkrb rnu tre ky.
## Kcyvjht esxxm wcp idj xtsvq
**BQH MIPOH LPIGJXFFP WX JUMUF:**
* Xmxg qahm arnu dxw qrofph ekndrioir hmk zrakxqsvk kzco ymk uzf zuegx.
* Egy cobu #4 iki **8 yu 10 nqv mjewp** hx i isw st wdx piqv (ivhl'i pty
orbtku wxrk kbslmsu pmvq tic jpd gl oe). Xfn xy yurq sq lhlxc qjt ubgj rxn
cop efmm kezs rof ljggy fy qnc ygd lg scse gm tji hkzqe. **Fb inh kkj mfp
mdsps dgz kyb!**
* Xy rel zjg dbmqj elc lcp okfvq.
* Cnb **mckjh pgab.**
## Yxzdk Usngniukjm
1. Kwtvmaw **4 rm fbcuxcpogfe xkmpqfbkf** ejq **1/2 hoo hzvhewfpf** um tda.
Topv rip zjvsub cqnr molo. **LW FIP SDF EJ PNF FLGUK.**
2. Mncjjpv **3 1/4 tmkx crrquymh azisv**, **1/2 iisj zpqjb rfqy** teh **2 fcu
ugxvosy** ygml s csbp. **Qwqk ymitd obbggd**.
3. Tyh xkxsqqswu wxjstzm.
4. Mro iuow tg bgc/ppih ay sab hpi arjif. Emjp hrhf lbtvf/kpqjp wdmym xz'c
leqai FQB gun jpn zqkso. Juxu bxzi pjhzp ydgnt'k lke cii! Pmb lvgf oo iy
**KYPR ADV GLFV XE'Q SV EEKA *nno fgf pqc lkl cjsdx ctw pwy***.
[rgpvfcr]: xetb.ccj
[nnxz://aoy.kpgvxsuqfdlptuhb.khf/ivqfuwv.bap]: ihky://apu.sqxkdofyxasgwpaj.drj/khqdymw.ekf
[SQURB ofr anlextfvz]: fvxb://tem.icvq.xkr/dlszyrrlv/200103068.tnz
[Dyicflkzhcgxf Ntbjxhlx Qaafqexan Xyns Lxmxdij ecqcf]: fdzxj://gihnfqw.wzd/bohspotovlcmy/frrung/1290520266087571458?k=20
[xygobr GKHKT jwsuvi Scof Hjdbmbrvg]: fodwb://bgpwlol.iab/nfkjrxbbmezwn
[ZfsYft]: cbvxf://veyuij.wwp/mtfzdribkyzgp
[YTYUZ aggc nektxg vkrhl]: umhiz-pzjn.ftk
[iqdotkixxt BJC]: fqodd://tza.hjmpkiwkmaqbg.dvw/yqfqafhmw-zrzy/
-----------------------------------------------------------------------------------------------------
(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-----------------------------------------------------------------------------------------------------
+81
View File
@@ -0,0 +1,81 @@
.TH enigma 1 "30 April 2020" "enigma" "IOCCC 2020"
.SH NAME
enigma \- A German Enigma simulator for IOCCC 2020
.SH SYNOPSIS
\fBenigma [-]\fP
.SH DESCRIPTION
\fBenigma\fP is a German Enigma simulator written for IOCCC 2020.
It only supports the Heer (army) and Luftwaffe (air force) machines.
Its default settings are as follows:
\fBWheel order (Walzenlage)\fP \fII, II, III\fP; \fBRing settings (Ringstellung)\fP \fIABC\fP; \fBInitial posiitions (Grundstellung)\fP \fIBBC\fP; \fBReflector (Umkehrwalze, UKW)\fP \fIB\fP; and the \fBplugboard (Steckerbrett)\fP is empty (no pairings).
.PP
There are no options per se; if not passed a \fB\-\fP (in the first argument) then it will use the default settings, waiting for input (unless input is piped to it e.g. from the recode program, echo or redirecting a file as stdin).
Otherwise it will prompt you for the settings and then wait for input to encipher/decipher.
.SH FILES
\fIprog.c\fP
.RS
Source file to the simulator.
.RE
\fIrecode.c\fP
.RS
Source code to the configuration tool (not required but recommended).
.RE
\fIrecode.markdown\fP
.RS
Markdown file with examples on how to use the recode program (along with the Enigma program).
.RE
\fIhint.text\fP
.RS
More information on the Enigma simulator IOCCC entry.
.RE
\fIchocolate\-cake.markdown\fP
\fIchocolate\-cake.html\fP
.RS
A file with a recipe of a delicious Double-layered Chocolate Fudge Cake that has been enciphered with one of 16 Enigma settings given in \fIrecode.markdown\fP which should give enough information on how to make use of the two programs in order to unlock this recipe.
I recommend the html version for formatting.
.RE
\fIenigma.1\fP
.RS
I don't think you need help here! :)
.RE
\fIrecode.1\fP
.RS
The recode.c man page.
.RE
.SH BUGS
.RS
\fB\-\fP Rudimentary parser allows for easily piping into the simulator settings (and file to encipher/decipher) but which also can be a bit confusing, unintuitive and does not handle too much input that well.
.RE
.RS
\fB\-\fP There is one thing in particular I was unsure of when writing the simulator as far as how it is supposed to work: I believe I have it but there might be one issue. See \fIhint.markdown\fP for more information.
.RE
.RS
\fB\-\fP It was written by a human being.
.RE
.RS
\fB\-\fP Not a bug as some might want to believe, maybe: figuring out how the recode.c program works won't help you figure out how this works.
.RE
.RS
\fB\-\fP For more please see \fIhint.markdown\fP.
.SH EXAMPLES
.PP
Please see the \fIrecode.markdown\fP and \fIhint.markdown\fP files for examples and other information.
.SH AUTHOR
Written by Cody Boone Ferguson for IOCCC 2020 (the 27th IOCCC).
.SH SEE ALSO
.PP
\fBrecode(1)\fP
.PP
\fB\<https://ioccc.xexyl.net/2020/enigma\>\fP The 27th IOCCC 'Most enigmatic'.
.PP
\fB\<http://users.telenet.be/d.rijmenants/en/enigmaproc.htm\>\fP Enigma Message Procedures for the Heer (Army), Luftwaffe (Air Force) and Kriegsmarine (Navy).
.PP
\fB\<http://enigmaco.de/enigma/enigma.html\>\fP Online interactive Enigma simulator.
.PP
\fB\<http://www.codesandciphers.co.uk/enigma/index.htm\>\fP Tony Sale's (original curator of the Bletchley Park Museum) pages on The Enigma cipher machine.
.PP
\fB\<http://users.telenet.be/d.rijmenants/en/enigmatech.htm\>\fP Technical Details of the Enigma Machine.
.PP
\fB\<http://users.telenet.be/d.rijmenants/en/enigma.htm\>\fP The German Enigma Cipher Machine.
.PP
\fB\<http://www.ellsbury.com/enigma3.htm\>\fP How the Enigma was Set Up and Operated.
+746
View File
@@ -0,0 +1,746 @@
# Most enigmatic
Cody Boone Ferguson <ioccc@xexyl.net>
<https://ioccc.xexyl.net>
Twitter: @xexyl
The code for this entry can be found in prog.c
## Judges' comments:
### To use:
make
./prog
### Try:
# IOCCC obfuscated!
echo IOCCC | ./prog
# IOCCC obfuscated and de-obfuscated!
echo IOCCC | ./prog | ./prog
# more input fun
./prog - < try.this.txt 2>/dev/null
# more obfuscated fun
echo testing test tests | ./recode
echo testing test tests | ./recode | ./prog - 2>/dev/null
echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode
echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog - 2>/dev/null
### Selected Judges Remarks:
This code is an enigma. Try to decode it!
There is a good deal of useful documentation that is provided with this entry:
* enigma.1
A useful man page for this entry. To render, try:
man ./enigma.1
* recode.markdown ([recode.html][])
Some useful information about recode.c
* [chocolate-cake.html][]
Because most of us could use some *Double-layered Chocolate Fudge Cake*!
[recode.html]: recode.html
[chocolate-cake.html]: chocolate-cake.html
## Author's comments:
My remarks about my Heer 'Army' and Luftwaffe 'Air Force' Enigma simulator for
the 27th IOCCC.
I want to dedicate this entry in part to the millions of poor souls that were
lost during the tragedy that is the Second World War. There are so many people
who are unknown, unloved, unclaimed and even unidentified. And who knows what
they might have gone on to do if their lives weren't - like it is with all other
wars - needlessly taken from them? When one considers it was all because the
most powerful man in the world at the time felt he should rule all others it
makes it somehow even more tragic: there wasn't even a good reason for the war
(is there ever?).
If one were to write the name of every person who died in the conflict in a
book, it would take so many pages that the book would be so heavy, so long, so
expensive to print, and it wouldn't bring anyone back to life nor would it
erase the suffering. Nothing will. It's horrible.
There really are no words that can truly describe the tragedy but I wish to with
my Enigma simulator honour each and every soul who was lost, or suffered, or
suffered the loss of friends or loved ones, as well as the world itself, in and
from one of the greatest tragedies in the history of mankind.
I will have more information on this entry at
[https://ioccc.xexyl.net/2020/enigma][] after the winning entries have been
published.
<a name="toc"></a>
- [IOCCC: An Enigma?](#ioccc)
- [The 1992 Nathan entry](#nathan)
- [Usage](#usage)
* [An example run](#example)
- [The recode.c configurator](#recode)
- [A parser subtlety that could cause confusion](#parsersubtlety)
- [On the source code layout](#layout)
- [Obfuscation](#obfuscation)
- [Bugs, limitations, differences from the real Enigma machines and general notes](#bugs)
- [Adding Kriegsmarine support](#kriegsmarine)
- [Portability](#portability)
- [Winning thoughts, dedications and thanks](#winning)
- [Resources](#resources)
### <a name="ioccc" href="#toc">IOCCC: An Enigma?</a>
Is there a better single word that could describe the code that is IOCCC? I'm
sure there are some other words that are equally as valid but I believe 'Enigma'
is a great word nonetheless.
However it's curious that no winning entry has ever been a simulator of the
German Enigma machine. I'm actually quite surprised at that because it's such a
brilliant piece of engineering of the time even though it had a critical flaw:
that no letter could be itself; this combined with cribs (known or suspected
plaintext) - which was down to carelessness, capturing an Enigma and sometimes
settings sheet, as well as known messages the Germans started out with - allowed
for cracking the code.
Combining this entry with two of the Morse code entries is particularly
interesting because that's what the Germans did: the party sending the message
would first set up the machine, write down the letters and then transmit by
Morse code the encoded message. Then those picking up on the message would note
the Morse code, translate it to the alphabet and then input it into their Enigma
machine configured in the same way and thus have the original message.
The [1998 ASCII / Morse code translator][] entry (author Dorssel) prints the
Morse code of text; and the [2014 Morse audio transcoder][] (author Vik) can be
used to allow for the actual sound of it. With my entry we can complete the
loop!
### <a name="nathan" href="#toc">The 1992 Nathan entry</a>
The author (Nathan) of the [1992 Worst Abuse of the Rules][] had this to say:
This program is a hello world text encrypter/decrypter. It uses an
enigma (I think) style encryption algorithm, where the encryption
key character is modified by a value, determined from the previous
character. Non-printable characters (those with ASCII values < ' '
or > 0x7e) are passed unaltered, thus any kind of file may be
successfully processed, but if the original is printable, the
processed file will be too. The input is read from stdin, and the
output presented to stdout. The key, a text string, is presented as
a command argument. This is optional, and if omitted, the file is
self-{de,en}crypted. To specify decryption, a "-" should be given
before the key. (Actually encryption and decryption proper inverse
operations, so you can use decrypt to scramble and encrypt to
descramble, if you're perverse.)
But the Enigma algorithm is more complex than that and my entry can encipher and
decipher text in the manner of the Enigma machines of the Army (Heer) and Air
Force (Luftwaffe); the Kriegsmarine 'Navy' was more complex (see section [Adding
Kriegsmarine support](#kriegsmarine) for more information on that.
My entry should also work as a non-military grade Enigma as it by default has an
empty plugboard (they had none). I explain how to set up the simulator later.
Yusuke Endoh asked the judges and me if the real 1992 entry source was
available. Simon Cooper didn't have access to it because it was before his time in
the IOCCC; but before the other judges could answer Ilya Kurdyukov sent a link to
the original 1992 code. However because I do not know the current status of the
regulation (though it seems unlikely that it still applies) I am only citing an
old version of the IOCCC website:
nathan - obfuscation by (trivial) encryption (source not exported)
Brian Westley decided to just ``screw the (US) government'' and make the real nathan.c source available. We also note that Nathan Sidwell who lives outside the US made his own source available as well.
Anyone who wants to find it I am sure can but I leave that to them.
### <a name="usage" href="#toc">Usage</a>
If you run the program by itself it'll use the default settings and prompt you
for input (end with EOF). At that point it'll process the input string and print
the result (after finishing the enciphering).
If you run it like:
./prog -
It will prompt you for the settings of the machine (example below).
The first group is in the order of rotor (number), ring setting (letter) and
ring (starting) position (letter). It will do this for the first, second and
then third for each.
Then it will prompt you for the reflector (number). The first one is reflector B
and the second is reflector C.
Finally it'll prompt you for the plugboard pairs.
After that you can input the string and it'll go from there.
#### <a name="example" href="#toc">An example run</a>
BTW: There's a much more entertaining (and delicious) challenge or exercise in
[recode.markdown][] (involves [chocolate-cake.html][]). These however show
the general program as well as how to use the two winning entries of the Morse
code that I referred to earlier.
$ ./prog -
Ring 1: 3
Setting 1: I
Position 1: O
Ring 2: 1
Setting 2: C
Position 2: C
Ring 3: 5
Setting 3: C
Position 3: Z
Reflector: 2
Plugboard pair 1: CO
Plugboard pair 2: DE
Plugboard pair 3: SN
Plugboard pair 4: XY
Plugboard pair 5: MS
Plugboard pair 6: AT
Plugboard pair 7: VF
Plugboard pair 8: UR
Plugboard pair 9: KL
Plugboard pair 10: BJ
IOCCC
^D
CFDRG
Notice that all output except the deciphered/enciphered text is sent to stdout.
If I didn't specify the `-` by e.g. `echo IOCCC | ./prog` then it will use the
default settings; as the judges suggest this invocation I will not show it here.
You can also type it out like this though:
$ ./prog
IOCCC
UUMMX
The IOCCC comes from stdin; the UUMMX is stdout.
If I compile the 2014 entry and copy it to my local directory as
`vik` I might do:
$ echo TEST|./prog |./vik | mplayer -demuxer rawaudio -
And you would hear Morse code of the Enigma output of 'TEST' (i.e. KCWV). Or
perhaps not in this case. I'm not sure: I discovered a bug in that entry
(Fedora, CentOS and macOS all affected).
For example I can use the syntax provided in the winning remarks along with my
entry to write it to a file. Say:
$ echo TEST|./prog |./vik > test.raw
$ ./vik e < test.raw | ./prog
LEST
Why did that happen? This shows more details:
$ ./vik e < test.raw
SCWV
However as can be seen the first char is wrong:
$ echo TEST|./prog
KCWV
And piping the original output to my entry itself you get the original input:
$ echo TEST | ./prog | ./prog
TEST
I'm not sure what causes that or if there's a way to fix it but that's the
idea anyway. Neither do I know if the original transcoding is correct.
What if I use the input string 'LEST' instead? In that case it worked fine:
$ echo LEST | ./prog | ./vik > lest.raw
$ ./vik e < lest.raw | ./prog
LEST
But there's one obvious question, right? Let's try the most important one:
$ echo IOCCC | ./prog | ./vik > ioccc.raw
$ ./vik e < ioccc.raw
UUMMX
$ ./vik e < ioccc.raw | ./prog
IOCCC
Phew! The program redeemed itself after the test failure! :)
(Technically above it didn't print a newline after the output and this is how it
is with some of the things I pasted in the other file and maybe others here
too. Notice also how it showed the same output that my program gave it - UUMMX.)
What about the other Morse code entry?
$ echo IOCCC | ./prog | ./dorssel
..- ..- -- -- -..-
### <a name="recode" href="#toc">The recode.c configurator</a>
I have included a supplementary program 'recode' ([recode.c][]) that can
do a number of things which acts as a kind of wrapper and configurator to my
entry. By default it prompts you for the settings (rotors/rings, ring settings,
positions, reflector and plugboard pairs), validating input as you go.
After that it prompts for text that you can pass to the Enigma simulator;
alternatively you can specify a file to read in.
It has a randomise mode and it can save/read the settings to/from a file to
allow for duplicity (an archaic term for the state of being double but obviously
for Enigma it has to also mean deceitful).
I recommend using this in a pipeline instead of the simulator itself if you want
to change the configuration of the simulator because it offers a much richer
experience (and because you can reuse the configuration without having to type
it out again every time).
It does take the effort to try and prevent invalid input (as above) though maybe
I didn't think of everything. My entry was meant to be a simulator only as far
as the ciphering goes but I thought this would make it much more interesting:
make it more flexible by a wrapper program.
For examples using it (and a delicious challenge) see [recode.markdown][]. See
also [recode.1][] and [enigma.1][] man pages.
### <a name="parsersubtlety" href="#toc">A parser subtlety that could cause confusion</a>
The parser is in a sense rather rudimentary but allows for both interactive and
automatic (e.g. via the recode program) input. This does mean that something
like the following can happen:
$ ./prog -
Ring 1: 1AB
Setting 1: Position 1: Ring 2: 2CD
Setting 2: Position 2: Ring 3: 3
Setting 3: A
Position 3: B
Reflector: 1A
Plugboard pair 1: BC
Plugboard pair 2: ..
Plugboard pair 3: ..
Plugboard pair 4: DE
Plugboard pair 5: FG
Plugboard pair 6: HI
Plugboard pair 7: JK
Plugboard pair 8: LM
Plugboard pair 9: NO
Plugboard pair 10: PQ
IOCCC
WD
SIRDK
First of all: what is that WD? I didn't type that but it appeared it seems due
to too much input that triggers this (it happens when I hit ctrl-d to end
input).
If everything is input correctly it would show nothing except the actual Enigma
output (maybe at times ^D - I have noticed this at least when I don't fill in
all plugboard pairs - which might or might not be possible with the Enigma
machines that had plugboards, I really do not know). I don't view this as a bug
because the parsing of input is meant to be simple and in fact you can expect
the same output from the same input even if there are errors in the input.
Anyway as you can see the first '1AB' was the first ring, setting and position.
After this it wants Ring 2 and I did similar; for ring 3 I did it each variable
by itself. However for the reflector I did 1A and it only expects 1 char! So will
that mean that the plugboard pairs are off? Yes it does seem to be so. This is
buffering at play I believe but it's useful for allowing the recode program to
easily configure the Enigma machine. In the other markdown file I give a hint
as to how this could be fixed but the caveat is it would necessitate a need for
rewriting recode.c.
There's another thing to be aware of and that's the way the ranges are enforced.
There are five rotors which obviously are in C 0-4 but in 'natural language'
1-5 (they were labelled I, II, III, IV and V though).
There are two reflectors and the same applies: in C 0-1 but in human it's
1-2 (technically these were reflectors B and C in the Enigma machine which I
display by name in recode.c just like with the rotors).
For more information see [recode.markdown][] or [recode.html][].
BTW: If you need a reminder to go to the gym just do your Enigma ABCs and it
should help you remember (though not at this time in our world it might help you
later on?). This might become even more useful after the challenge is accepted,
accomplished and made use of! :)
$ echo ABC | ./prog
GYM
$ echo ABC | ./prog | ./prog
ABC
### <a name="layout" href="#toc">On the source code layout</a>
The layout of recode.c isn't too significant (but see below) but I want to
mention prog.c especially:
I did think of a more artistic layout but reflecting on it I think that the
blankness of it can be another way of honouring all the many people who died
in - like all other wars - what was a useless conflict because - again like all
other wars - a powerful human being decided that they should rule others.
The blankness is a reflection of the millions of people who died unknown, uncared
for, unloved, without ever being acknowledged in their far too short lives, some
even unidentified; it's the presence of absence.
I find it somehow fitting that the day I have finished this is 30 April 2020,
which was exactly 75 years from the day that the person responsible for the
Second World War, Adolf Hitler, ended his life. (I have since then made a bug
fix but I consider this inconsequential).
As for recode.c though I really love this:
/\
/ This is *not* what you think:
...because it seems so wrong in C code at first glance.
### <a name="obfuscation" href="#toc">Obfuscation</a>
It's an Enigma simulator! Isn't that proof that it's obfuscated itself?! :)
Silliness aside [obfuscation.txt][] has some of the ways I think this entry is
obfuscated. To decipher try:
./recode -Robfuscation.key -fobfuscation.txt | ./prog - 2>/dev/null > obfuscation.markdown
To encipher:
./recode -Robfuscation.key -fobfuscation.markdown | ./prog - 2>/dev/null > obfuscation.txt
The file [obfuscation.key][] is the key to decipher/encipher
[obfuscation.txt][].
For the lazy [obfuscation.markdown][] has the deciphered version. I am afraid
I'm not so inclined to do that for the cake recipe: the idea there is to make it
a fun exercise that when solved unlocks a wonderful double-layered chocolate
fudge cake recipe. But given that my 'Don't tread on me award' entry also
has the recipe, not enciphered, one might just go there instead. Still it's a
fun way to explore this entry.
As for the [obfuscation.key][] file if you observe the contents you'll find the
word OBFUSCATION:
2OB5FU1SC2ATIONCDEFGHJKLMPQRYZ
OB FU SC ATION
### <a name="bugs" href="#toc">Bugs, limitations, differences from the real Enigma machines and general notes</a>
Ways that my simulator differs from the real thing. Not all of these are bugs
and some could be considered features; others are just differences.
* Does not check for using the same rotor more than once. The real Enigma
machines this would not work because they had to choose from a set of rotors and
there were no duplicates. This shouldn't be a problem here however except that
it won't be a possible configuration of the real Enigma machine. The `recode`
program *however does validate this* (except when reading in settings via the
`-R` option which I explain in the [recode.markdown][] / [recode.html][] file).
* The way the plugboard - for the machines that had them - is if you connect A
to B then no other letters can connect to A or B. Earlier there wasn't proper
detection and this caused invalid output.
Why only 10 pairs when the German alphabet has 26 letters? It's
theoretically possible to have 13 but the Enigma typically had 10 pairs.
It's easy enough to update my entry to do this once you de-obfuscate it but
I'm not helping there (and in fact I don't think I could any more even if I
wanted to - at least not easily!).
* It does not obviously have the clicking sound associated with the moving
parts of the real machine. I think it would be annoying to have this as it
processes each letter. However with the Morse code audio transcoder entry you
can at least have the output played in Morse code as the Germans did; I think
that is really cool (I think it's really cool even if there's a bug in it)! That
it pays homage to that (and another) entry is a bonus here.
* The simulator doesn't report errors but tries to gracefully deal with them:
if one chooses a value out of range it moves it into the range (if > the max
then the max, if < min then the min). If invalid chars are input for the
plugboard pairs then it's not added to the plugboard etc.
* The real Enigma machines had only letters: no digits, no punctuation. My
entry prints `!isalpha()` chars untouched. The Germans had different systems for
punctuations, numbers etc. (one of the documents I link to has these details).
* My entry preserves case of letters. The real Enigma had only one case as it
was just a keyboard and they didn't need case-sensitivity.
* Later models introduced a fourth rotor. The Kriegsmarine procedures were
also far more complex than the Heer and Luftwaffe. I find this particularly
interesting because it was Hermann Goering who was the Supreme Commander of the
Luftwaffe and the intelligence agency Forschungsamt (FA) was his; it provided
Hitler with invaluable information so one would think the Luftwaffe system would
be more complex! See [adding Kriegsmarine support](#kriegsmarine) for more
information.
* I only include reflectors B and C. To have included more would have used too
many bytes (each reflector and rotor is 26 characters!) and I could not include
them for this reason; I include 5 rotors and 2 reflectors and that's a total of
(`5 * 26 + 2 * 26` == 182 chars) but there are as you can see many other strings
too. It is however feasible to update the rotor and reflector options and you
could even make your own versions if you wanted to. Doing this is an exercise to
the reader however (the idea of trying this makes me cringe because of how I
obfuscated things)!
There's one thing I'm unsure of in my implementation. Because of all the
possible settings I used some other simulators as a starting point and more
importantly to validate that my code worked right. These other simulators had
bugs though and so one thing looked odd and I don't know if it is right or not.
An online simulator appears correct but I don't see the option to change that
part.
If you notice in the Q() function where I set up specific pointers and other
data there is a call to the macro 'q' but I only refer to the first ring setting
(of which I no longer even know which element it is! Or was it position? I don't
even know that now for certain). That's because the Python code did that (though
very differently of course) but I also had to bug-fix the Python in another
part.
I do not know if this is correct but as I show somewhere my entry does match the
online simulator so I presume it is correct. It might be that the Germans tended
to have it at A but again I do not know.
### <a name="kriegsmarine" href="#toc">Adding Kriegsmarine support</a>
I said that one could add the additional rotors used by the Kriegsmarine but
looking at this again it appears that it's not as simple as adding the rotors to
the code and updating the references to the array etc.
This is because rotors VI, VII and VII had two notches and this changes the way
things work. The Kriegsmarine M4 also had an additional change which would
complicate matters more.
I looked into trying to do this for another version after winning but some of
the obfuscation techniques dramatically complicates even attempting this so I
haven't even tried.
It is feasible that you could add your own rotors however but I leave this as an
exercise to the reader. I will say that the five rotors I, II, III, IV and V can
be found in the source code verbatim and you could confirm it by looking them
up; however much more would have to be done in order to get them to work, than
to just put the strings in. Again the way I set things up complicates this
greatly.
### <a name="portability" href="#toc">Portability</a>
I have tested it under macOS, Fedora and CentOS Linux and all seems okay under
these platforms. When I was in the final stages of obfuscation I made an error
somehow (or else maybe the vim formatting caused a problem - I have seen this
before) and I had to go back and undo some of the obfuscation to figure out what
was going on (I had a hunch where and I noted it in the obfuscation I believe)
but this made me wonder on if I made any other mistakes since it appeared to be
working before that.
I don't know if EBCDIC will work but I think it might because it appears that
the alphabet is a contiguous sequence. I don't believe endianness matters but I
no longer remember what I've done in full and I've no way to test it.
If there are any inconsistencies in input/output one also has to be certain that
input was put in correctly because as soon as a letter differs the entire
sequence will be off.
The results of my test script (not included here but I will probably have it on
my website) are the same under Fedora, CentOS and macOS.
### <a name="resources" href="#toc">Resources</a>
#### A note on Wehrmacht, its branches and other agencies and their Enigma machines
The Wehrmacht was the defence force in full which included the Heer (army),
Luftwaffe (air force) and Kriegsmarine (navy). As I said the Kriegsmarine
procedures were more complex: they had additional rotors and one of their models
had a different reflector system (thin instead of thick - some of the documents
below discuss this). The military intelligence agency, the Abwehr, had their own
system too. Non-military grade Enigma machines didn't have the plugboard. And
so on.
However one of the documents below distinguishes the Kriegsmarine from the
Wehrmacht; when you see this you can read it as the Kriegsmarine versus the rest
of the Wehrmacht rather than the Wehrmacht and the Kriegsmarine.
[Enigma Message Procedures][]: The Heer, Luftwaffe and Kriegsmarine Enigma
procedures.
[Interactive Enigma Machine][]: Shows wiring of the Enigma machine based on the
settings and input (unfortunately uses Flash). This was what I used to verify
output (as best I could find). To set this up to use the default settings in my
simulator make sure to use Rotors I, II and III and the starting positions at B,
B and C respectively (as in left, centre, right). To do this click the button at
the top right that looks like:
o->
<-o
And then select the rotors. Next click the button again at the left of the
rotor selection 'screen'. Then use the arrow buttons above each rotor to set
from left to right B, B and C. After this you can type your message in the input
field and watch the wiring of the rotors change and show the path it takes.
If I made use of the Enigma code in the recode.c program I would maybe consider
doing something like that but I intentionally do not use it there: as cool as it
might be it would give a better idea of how the algorithm works (unless I were
to make it just as obscure as I do in prog.c but that's also a bit risky). I
don't believe I could do it now anyway.
I'm uncertain how to change the rotor settings itself in this simulator to
determine if the ring settings being different from ABC would cause a problem
(this is the thing I mention I'm uncertain about in the bugs section).
Going back to the configuring the online simulator try inputting the text IOCCC
and you'll see the resulting text being:
UUMMX
Which is exactly as my entry shows! So at least for the starting position BBC
and an empty plugboard and the other defaults in my entry (which appear to be
consistent with the online simulator too) I can verify it works.
[Tony Sale's pages on The Enigma cipher machine][]: This is many pages on the
Enigma machine by the late Tony Sale who was the original curator of the
Bletchley Park Museum. There is a wealth of information in these pages on how
the Enigma worked and this includes some challenges to do to see how well you
understand the algorithm.
Fun fact: the abbreviation for the Signals Intelligence is that of our
wonderful SIGINT.
[Technical Details of the Enigma Machine][]: 'This page provides the technical
details of the Wehrmacht and Luftwaffe Enigma, and the Kriegsmarine Enigma M4.'
It is quite a nice document with diagrams, pictures of actual Enigma rotors and
other parts and more.
[The German Enigma Cipher Machine][]: The history of Enigma, its development,
use during the war and cryptanalysis.
[How the Enigma was Set Up and Operated][]: This is the third page in a document
series on the Enigma that explains the initial set up of the Enigma machine for
each day. This is a good introduction to the set up. There is one thing that I
was not aware of (or if I was it did not register): the operator would after
setting the positions also put in three letters before the actual message (there
were several parts to each message but this was another layer of complexity). I
did not implement this in the recode program but what would it be anyway? If the
user here wants to they could add three letters to their message beginning. I
don't think there need be any addition to the recode program - at least not
that.
[1992 Worst Abuse of the Rules]: http://www.ioccc.org/1992/nathan.hint
[1998 ASCII / Morse code translator]: http://www.ioccc.org/1998/dorssel.hint
[2014 Morse audio transcoder]: http://www.ioccc.org/2014/vik/hint.text
[Enigma Message Procedures]: http://users.telenet.be/d.rijmenants/en/enigmaproc.htm
[Interactive Enigma Machine]: http://enigmaco.de/enigma/enigma.html
[enigma.1]: enigma.1
[recode.1]: recode.1
[recode.markdown]: recode.markdown
[chocolate-cake.html]: chocolate-cake.html
[recode.c]: recode.c
[obfuscation.markdown]: obfuscation.markdown
[obfuscation.txt]: obfuscation.txt
[obfuscation.key]: obfuscation.key
[Tony Sale's pages on The Enigma cipher machine]: http://www.codesandciphers.co.uk/enigma/index.htm
[Technical Details of the Enigma Machine]: http://users.telenet.be/d.rijmenants/en/enigmatech.htm
[The German Enigma Cipher Machine]: http://users.telenet.be/d.rijmenants/en/enigma.htm
[How the Enigma was Set Up and Operated]: http://www.ellsbury.com/enigma3.htm
[https://ioccc.xexyl.net/2020/enigma]: https://ioccc.xexyl.net/2020/enigma
## Author's dedication:
### <a name="winning" href="#toc">Winning thoughts, dedications and thanks</a>
Once again I'm honoured to win along with some of the other veterans who I have
a huge amount of respect for; there's Don Yang, Dave Burton, Yusuke Endoh and
Edward Giles all of whom are amazing programmers. I'm especially proud to win
besides Dave Burton and Yusuke Endoh but Don Yang and Edward Giles too.
But there are some others who I don't remember like Ilya Kurdyukov (who's
offered a lot of interesting thoughts on Snake and who plans to have his own
version after the entries are published), Nathan Otterness, Nicholas Carlini
(whose entry is an absolutely brilliant abuse of printf - and I totally agree
with the judges comments that your entry is so novel that it'll be worth special
mention in the future Best of IOCCC list!) and tsoj too.
Well done and congratulations to all of you again! Thank you for submitting the
wonderful entries and I'm honoured to have my two entries beside yours!
To Yusuke Endoh, Dave Burton and Nicholas Carlini I very much appreciate your
wonderful comments on this program. Your comments Yusuke on this entry specially
and also Dave's comments on my double-win are both extremely special to me - it
truly takes my pride to another level!
I would like to dedicate this entry to my wonderful mum Dianne Ferguson whom I
love with all my heart and soul <3 Thank you for being the best mother
imaginable! You've been there for me in the darkest of my hours without question
without complaint and with all the love, compassion, empathy, sympathy and
devotion anyone could ever ask for. Bless you again and again and again dear
mother.
Once more besides those two I want to also dedicate this to all the many
millions of people whose lives were taken from them in what amounts to - like
all other wars - a horrible, pointless conflict and an utter waste of life,
something precious that is far too often taken for granted. As I noted before I
found it fitting that I finished this on 30 April 2020 - exactly 75 years after
Adolf Hitler, he who started the Second World War, ended his life. The blankness
of the layout is another way of honouring the poor souls who lost their lives,
many of whom we will never know even their name let alone what they might have
accomplished if it wasn't for their tragic and pointless deaths. Always remember
that life is precious and never ever take it for granted! Believe in yourselves.
Everyone. Do not let anyone ruin that for you ever.
I would like to thank my dear friend Martijn Schoemaker for encouraging me in my
programming over the years and who I owe a great deal to. Thank you for
believing in me and my programming abilities (and other abilities) even when I
couldn't believe in myself! Very much appreciated especially coming from an
amazing programmer who I have huge admiration for!
Finally I want to thank Leo Broukhis, Simon Cooper and Landon Curt Noll for
continuing to hold the contest after all these years - and for having selected
my entries. It's a huge honour; thank you! I also happen to love your comments
as well as the award titles. And yes indeed 'most of us could use
*[Double-layered Chocolate Fudge Cake][]*!'
[Double-layered Chocolate Fudge Cake]: chocolate-cake.html
-----------------------------------------------------------------------------------------------------
(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-----------------------------------------------------------------------------------------------------
+765
View File
@@ -0,0 +1,765 @@
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional //EN">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.2.2">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"> <link rel="stylesheet"
type="text/css"
href="../hint.css" />
<title></title>
<title>Most enigmatic</title>
</head>
<body>
<CENTER>
<IMG SRC="/png/ioccc.png" ALT="IOCCC" height=78 width=267>
<P><FONT size="6"><I>The International Obfuscated C Code Contest</I></FONT></P>
<div id="bar">
<ul>
<li><a href="../index.html">About the 27th IOCCC</a></li>
<li><a href="../whowon.html">27th IOCCC Winners</a></li>
<li><a href="/index.html">IOCCC home</a></li>
<li><a href="/winners.html">List of All Winners</a></li>
<li><a href="/judges.html">The Judges</a></li>
</ul>
</div>
<P><FONT size="6"><B>A 27<sup>th</sup> IOCCC Winner</B></FONT></P>
</CENTER>
<h1>Most enigmatic</h1>
<p>Cody Boone Ferguson <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#105;&#111;&#99;&#99;&#99;&#64;&#120;&#101;&#120;&#121;&#108;&#46;&#110;&#101;&#116;">&#105;&#111;&#99;&#99;&#99;&#64;&#120;&#101;&#120;&#121;&#108;&#46;&#110;&#101;&#116;</a><br/>
<a href="https://ioccc.xexyl.net">https://ioccc.xexyl.net</a><br/>
Twitter: @xexyl</p>
<p>The code for this entry can be found in <a href="prog.c">prog.c</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code># IOCCC obfuscated!
echo IOCCC | ./prog
# IOCCC obfuscated and de-obfuscated!
echo IOCCC | ./prog | ./prog
# more input fun
./prog - &lt; try.this.txt 2&gt;/dev/null
# more obfuscated fun
echo testing test tests | ./recode
echo testing test tests | ./recode | ./prog - 2&gt;/dev/null
echo testing test tests | ./recode | ./prog - 2&gt;/dev/null | ./recode
echo testing test tests | ./recode | ./prog - 2&gt;/dev/null | ./recode | ./prog - 2&gt;/dev/null
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This code is an enigma. Try to decode it!</p>
<p>There is a good deal of useful documentation that is provided with this entry:</p>
<ul>
<li>enigma.1</li>
</ul>
<p>A useful man page for this entry. To render, try:</p>
<pre><code>man ./enigma.1
</code></pre>
<ul>
<li>recode.markdown (<a href="recode.html">recode.html</a>)</li>
</ul>
<p>Some useful information about recode.c</p>
<ul>
<li><a href="chocolate-cake.html">chocolate-cake.html</a></li>
</ul>
<p>Because most of us could use some <em>Double-layered Chocolate Fudge Cake</em>!</p>
<h2>Author&rsquo;s comments:</h2>
<p>My remarks about my Heer &lsquo;Army&rsquo; and Luftwaffe &lsquo;Air Force&rsquo; Enigma simulator for
the 27th IOCCC.</p>
<p>I want to dedicate this entry in part to the millions of poor souls that were
lost during the tragedy that is the Second World War. There are so many people
who are unknown, unloved, unclaimed and even unidentified. And who knows what
they might have gone on to do if their lives weren&rsquo;t - like it is with all other
wars - needlessly taken from them? When one considers it was all because the
most powerful man in the world at the time felt he should rule all others it
makes it somehow even more tragic: there wasn&rsquo;t even a good reason for the war
(is there ever?).</p>
<p>If one were to write the name of every person who died in the conflict in a
book, it would take so many pages that the book would be so heavy, so long, so
expensive to print, and it wouldn&rsquo;t bring anyone back to life nor would it
erase the suffering. Nothing will. It&rsquo;s horrible.</p>
<p>There really are no words that can truly describe the tragedy but I wish to with
my Enigma simulator honour each and every soul who was lost, or suffered, or
suffered the loss of friends or loved ones, as well as the world itself, in and
from one of the greatest tragedies in the history of mankind.</p>
<p>I will have more information on this entry at
<a href="https://ioccc.xexyl.net/2020/enigma">https://ioccc.xexyl.net/2020/enigma</a> after the winning entries have been
published.</p>
<p><a name="toc"></a>
- <a href="#ioccc">IOCCC: An Enigma?</a></p>
<ul>
<li><p><a href="#nathan">The 1992 Nathan entry</a></p></li>
<li><p><a href="#usage">Usage</a></p>
<ul>
<li><a href="#example">An example run</a></li>
</ul>
</li>
<li><p><a href="#recode">The recode.c configurator</a></p></li>
<li><p><a href="#parsersubtlety">A parser subtlety that could cause confusion</a></p></li>
<li><p><a href="#layout">On the source code layout</a></p></li>
<li><p><a href="#obfuscation">Obfuscation</a></p></li>
<li><p><a href="#bugs">Bugs, limitations, differences from the real Enigma machines and general notes</a></p></li>
<li><p><a href="#kriegsmarine">Adding Kriegsmarine support</a></p></li>
<li><p><a href="#portability">Portability</a></p></li>
<li><p><a href="#winning">Winning thoughts, dedications and thanks</a></p></li>
<li><p><a href="#resources">Resources</a></p></li>
</ul>
<h3><a name="ioccc" href="#toc">IOCCC: An Enigma?</a></h3>
<p>Is there a better single word that could describe the code that is IOCCC? I&rsquo;m
sure there are some other words that are equally as valid but I believe &lsquo;Enigma&rsquo;
is a great word nonetheless.</p>
<p>However it&rsquo;s curious that no winning entry has ever been a simulator of the
German Enigma machine. I&rsquo;m actually quite surprised at that because it&rsquo;s such a
brilliant piece of engineering of the time even though it had a critical flaw:
that no letter could be itself; this combined with cribs (known or suspected
plaintext) - which was down to carelessness, capturing an Enigma and sometimes
settings sheet, as well as known messages the Germans started out with - allowed
for cracking the code.</p>
<p>Combining this entry with two of the Morse code entries is particularly
interesting because that&rsquo;s what the Germans did: the party sending the message
would first set up the machine, write down the letters and then transmit by
Morse code the encoded message. Then those picking up on the message would note
the Morse code, translate it to the alphabet and then input it into their Enigma
machine configured in the same way and thus have the original message.</p>
<p>The <a href="http://www.ioccc.org/1998/dorssel.hint">1998 ASCII / Morse code translator</a> entry (author Dorssel) prints the
Morse code of text; and the <a href="http://www.ioccc.org/2014/vik/hint.text">2014 Morse audio transcoder</a> (author Vik) can be
used to allow for the actual sound of it. With my entry we can complete the
loop!</p>
<h3><a name="nathan" href="#toc">The 1992 Nathan entry</a></h3>
<p>The author (Nathan) of the <a href="http://www.ioccc.org/1992/nathan.hint">1992 Worst Abuse of the Rules</a> had this to say:</p>
<pre><code>This program is a hello world text encrypter/decrypter. It uses an
enigma (I think) style encryption algorithm, where the encryption
key character is modified by a value, determined from the previous
character. Non-printable characters (those with ASCII values &lt; ' '
or &gt; 0x7e) are passed unaltered, thus any kind of file may be
successfully processed, but if the original is printable, the
processed file will be too. The input is read from stdin, and the
output presented to stdout. The key, a text string, is presented as
a command argument. This is optional, and if omitted, the file is
self-{de,en}crypted. To specify decryption, a "-" should be given
before the key. (Actually encryption and decryption proper inverse
operations, so you can use decrypt to scramble and encrypt to
descramble, if you're perverse.)
</code></pre>
<p>But the Enigma algorithm is more complex than that and my entry can encipher and
decipher text in the manner of the Enigma machines of the Army (Heer) and Air
Force (Luftwaffe); the Kriegsmarine &lsquo;Navy&rsquo; was more complex (see section <a href="#kriegsmarine">Adding
Kriegsmarine support</a> for more information on that.</p>
<p>My entry should also work as a non-military grade Enigma as it by default has an
empty plugboard (they had none). I explain how to set up the simulator later.</p>
<p>Yusuke Endoh asked the judges and me if the real 1992 entry source was
available. Simon Cooper didn&rsquo;t have access to it because it was before his time in
the IOCCC; but before the other judges could answer Ilya Kurdyukov sent a link to
the original 1992 code. However because I do not know the current status of the
regulation (though it seems unlikely that it still applies) I am only citing an
old version of the IOCCC website:</p>
<pre><code> nathan - obfuscation by (trivial) encryption (source not exported)
Brian Westley decided to just ``screw the (US) government'' and make the real nathan.c source available. We also note that Nathan Sidwell who lives outside the US made his own source available as well.
</code></pre>
<p>Anyone who wants to find it I am sure can but I leave that to them.</p>
<h3><a name="usage" href="#toc">Usage</a></h3>
<p>If you run the program by itself it&rsquo;ll use the default settings and prompt you
for input (end with EOF). At that point it&rsquo;ll process the input string and print
the result (after finishing the enciphering).</p>
<p>If you run it like:</p>
<pre><code> ./prog -
</code></pre>
<p>It will prompt you for the settings of the machine (example below).</p>
<p>The first group is in the order of rotor (number), ring setting (letter) and
ring (starting) position (letter). It will do this for the first, second and
then third for each.</p>
<p>Then it will prompt you for the reflector (number). The first one is reflector B
and the second is reflector C.</p>
<p>Finally it&rsquo;ll prompt you for the plugboard pairs.</p>
<p>After that you can input the string and it&rsquo;ll go from there.</p>
<h4><a name="example" href="#toc">An example run</a></h4>
<p>BTW: There&rsquo;s a much more entertaining (and delicious) challenge or exercise in
<a href="recode.markdown">recode.markdown</a> (involves <a href="chocolate-cake.html">chocolate-cake.html</a>). These however show
the general program as well as how to use the two winning entries of the Morse
code that I referred to earlier.</p>
<pre><code> $ ./prog -
Ring 1: 3
Setting 1: I
Position 1: O
Ring 2: 1
Setting 2: C
Position 2: C
Ring 3: 5
Setting 3: C
Position 3: Z
Reflector: 2
Plugboard pair 1: CO
Plugboard pair 2: DE
Plugboard pair 3: SN
Plugboard pair 4: XY
Plugboard pair 5: MS
Plugboard pair 6: AT
Plugboard pair 7: VF
Plugboard pair 8: UR
Plugboard pair 9: KL
Plugboard pair 10: BJ
IOCCC
^D
CFDRG
</code></pre>
<p>Notice that all output except the deciphered/enciphered text is sent to stdout.</p>
<p>If I didn&rsquo;t specify the <code>-</code> by e.g. <code>echo IOCCC | ./prog</code> then it will use the
default settings; as the judges suggest this invocation I will not show it here.</p>
<p>You can also type it out like this though:</p>
<pre><code> $ ./prog
IOCCC
UUMMX
</code></pre>
<p>The IOCCC comes from stdin; the UUMMX is stdout.</p>
<p>If I compile the 2014 entry and copy it to my local directory as
<code>vik</code> I might do:</p>
<pre><code> $ echo TEST|./prog |./vik | mplayer -demuxer rawaudio -
</code></pre>
<p>And you would hear Morse code of the Enigma output of &lsquo;TEST&rsquo; (i.e. KCWV). Or
perhaps not in this case. I&rsquo;m not sure: I discovered a bug in that entry
(Fedora, CentOS and macOS all affected).</p>
<p>For example I can use the syntax provided in the winning remarks along with my
entry to write it to a file. Say:</p>
<pre><code> $ echo TEST|./prog |./vik &gt; test.raw
$ ./vik e &lt; test.raw | ./prog
LEST
</code></pre>
<p>Why did that happen? This shows more details:</p>
<pre><code> $ ./vik e &lt; test.raw
SCWV
</code></pre>
<p>However as can be seen the first char is wrong:</p>
<pre><code> $ echo TEST|./prog
KCWV
</code></pre>
<p>And piping the original output to my entry itself you get the original input:</p>
<pre><code> $ echo TEST | ./prog | ./prog
TEST
</code></pre>
<p>I&rsquo;m not sure what causes that or if there&rsquo;s a way to fix it but that&rsquo;s the
idea anyway. Neither do I know if the original transcoding is correct.</p>
<p>What if I use the input string &lsquo;LEST&rsquo; instead? In that case it worked fine:</p>
<pre><code> $ echo LEST | ./prog | ./vik &gt; lest.raw
$ ./vik e &lt; lest.raw | ./prog
LEST
</code></pre>
<p>But there&rsquo;s one obvious question, right? Let&rsquo;s try the most important one:</p>
<pre><code> $ echo IOCCC | ./prog | ./vik &gt; ioccc.raw
$ ./vik e &lt; ioccc.raw
UUMMX
$ ./vik e &lt; ioccc.raw | ./prog
IOCCC
</code></pre>
<p>Phew! The program redeemed itself after the test failure! :)</p>
<p>(Technically above it didn&rsquo;t print a newline after the output and this is how it
is with some of the things I pasted in the other file and maybe others here
too. Notice also how it showed the same output that my program gave it - UUMMX.)</p>
<p>What about the other Morse code entry?</p>
<pre><code> $ echo IOCCC | ./prog | ./dorssel
..- ..- -- -- -..-
</code></pre>
<h3><a name="recode" href="#toc">The recode.c configurator</a></h3>
<p>I have included a supplementary program &lsquo;recode&rsquo; (<a href="recode.c">recode.c</a>) that can
do a number of things which acts as a kind of wrapper and configurator to my
entry. By default it prompts you for the settings (rotors/rings, ring settings,
positions, reflector and plugboard pairs), validating input as you go.</p>
<p>After that it prompts for text that you can pass to the Enigma simulator;
alternatively you can specify a file to read in.</p>
<p>It has a randomise mode and it can save/read the settings to/from a file to
allow for duplicity (an archaic term for the state of being double but obviously
for Enigma it has to also mean deceitful).</p>
<p>I recommend using this in a pipeline instead of the simulator itself if you want
to change the configuration of the simulator because it offers a much richer
experience (and because you can reuse the configuration without having to type
it out again every time).</p>
<p>It does take the effort to try and prevent invalid input (as above) though maybe
I didn&rsquo;t think of everything. My entry was meant to be a simulator only as far
as the ciphering goes but I thought this would make it much more interesting:
make it more flexible by a wrapper program.</p>
<p>For examples using it (and a delicious challenge) see <a href="recode.markdown">recode.markdown</a>. See
also <a href="recode.1">recode.1</a> and <a href="enigma.1">enigma.1</a> man pages.</p>
<h3><a name="parsersubtlety" href="#toc">A parser subtlety that could cause confusion</a></h3>
<p>The parser is in a sense rather rudimentary but allows for both interactive and
automatic (e.g. via the recode program) input. This does mean that something
like the following can happen:</p>
<pre><code> $ ./prog -
Ring 1: 1AB
Setting 1: Position 1: Ring 2: 2CD
Setting 2: Position 2: Ring 3: 3
Setting 3: A
Position 3: B
Reflector: 1A
Plugboard pair 1: BC
Plugboard pair 2: ..
Plugboard pair 3: ..
Plugboard pair 4: DE
Plugboard pair 5: FG
Plugboard pair 6: HI
Plugboard pair 7: JK
Plugboard pair 8: LM
Plugboard pair 9: NO
Plugboard pair 10: PQ
IOCCC
WD
SIRDK
</code></pre>
<p>First of all: what is that WD? I didn&rsquo;t type that but it appeared it seems due
to too much input that triggers this (it happens when I hit ctrl-d to end
input).</p>
<p>If everything is input correctly it would show nothing except the actual Enigma
output (maybe at times ^D - I have noticed this at least when I don&rsquo;t fill in
all plugboard pairs - which might or might not be possible with the Enigma
machines that had plugboards, I really do not know). I don&rsquo;t view this as a bug
because the parsing of input is meant to be simple and in fact you can expect
the same output from the same input even if there are errors in the input.</p>
<p>Anyway as you can see the first &lsquo;1AB&rsquo; was the first ring, setting and position.
After this it wants Ring 2 and I did similar; for ring 3 I did it each variable
by itself. However for the reflector I did 1A and it only expects 1 char! So will
that mean that the plugboard pairs are off? Yes it does seem to be so. This is
buffering at play I believe but it&rsquo;s useful for allowing the recode program to
easily configure the Enigma machine. In the other markdown file I give a hint
as to how this could be fixed but the caveat is it would necessitate a need for
rewriting recode.c.</p>
<p>There&rsquo;s another thing to be aware of and that&rsquo;s the way the ranges are enforced.
There are five rotors which obviously are in C 0-4 but in &lsquo;natural language&rsquo;
1-5 (they were labelled I, II, III, IV and V though).</p>
<p>There are two reflectors and the same applies: in C 0-1 but in human it&rsquo;s
1-2 (technically these were reflectors B and C in the Enigma machine which I
display by name in recode.c just like with the rotors).</p>
<p>For more information see <a href="recode.markdown">recode.markdown</a> or <a href="recode.html">recode.html</a>.</p>
<p>BTW: If you need a reminder to go to the gym just do your Enigma ABCs and it
should help you remember (though not at this time in our world it might help you
later on?). This might become even more useful after the challenge is accepted,
accomplished and made use of! :)</p>
<pre><code> $ echo ABC | ./prog
GYM
$ echo ABC | ./prog | ./prog
ABC
</code></pre>
<h3><a name="layout" href="#toc">On the source code layout</a></h3>
<p>The layout of recode.c isn&rsquo;t too significant (but see below) but I want to
mention prog.c especially:</p>
<p>I did think of a more artistic layout but reflecting on it I think that the
blankness of it can be another way of honouring all the many people who died
in - like all other wars - what was a useless conflict because - again like all
other wars - a powerful human being decided that they should rule others.</p>
<p>The blankness is a reflection of the millions of people who died unknown, uncared
for, unloved, without ever being acknowledged in their far too short lives, some
even unidentified; it&rsquo;s the presence of absence.</p>
<p>I find it somehow fitting that the day I have finished this is 30 April 2020,
which was exactly 75 years from the day that the person responsible for the
Second World War, Adolf Hitler, ended his life. (I have since then made a bug
fix but I consider this inconsequential).</p>
<p>As for recode.c though I really love this:</p>
<pre><code> /\
/ This is *not* what you think:
</code></pre>
<p>&hellip;because it seems so wrong in C code at first glance.</p>
<h3><a name="obfuscation" href="#toc">Obfuscation</a></h3>
<p>It&rsquo;s an Enigma simulator! Isn&rsquo;t that proof that it&rsquo;s obfuscated itself?! :)
Silliness aside <a href="obfuscation.txt">obfuscation.txt</a> has some of the ways I think this entry is
obfuscated. To decipher try:</p>
<pre><code> ./recode -Robfuscation.key -fobfuscation.txt | ./prog - 2&gt;/dev/null &gt; obfuscation.markdown
</code></pre>
<p>To encipher:</p>
<pre><code> ./recode -Robfuscation.key -fobfuscation.markdown | ./prog - 2&gt;/dev/null &gt; obfuscation.txt
</code></pre>
<p>The file <a href="obfuscation.key">obfuscation.key</a> is the key to decipher/encipher
<a href="obfuscation.txt">obfuscation.txt</a>.</p>
<p>For the lazy <a href="obfuscation.markdown">obfuscation.markdown</a> has the deciphered version. I am afraid
I&rsquo;m not so inclined to do that for the cake recipe: the idea there is to make it
a fun exercise that when solved unlocks a wonderful double-layered chocolate
fudge cake recipe. But given that my &lsquo;Don&rsquo;t tread on me award&rsquo; entry also
has the recipe, not enciphered, one might just go there instead. Still it&rsquo;s a
fun way to explore this entry.</p>
<p>As for the <a href="obfuscation.key">obfuscation.key</a> file if you observe the contents you&rsquo;ll find the
word OBFUSCATION:</p>
<pre><code> 2OB5FU1SC2ATIONCDEFGHJKLMPQRYZ
OB FU SC ATION
</code></pre>
<h3><a name="bugs" href="#toc">Bugs, limitations, differences from the real Enigma machines and general notes</a></h3>
<p>Ways that my simulator differs from the real thing. Not all of these are bugs
and some could be considered features; others are just differences.</p>
<ul>
<li><p>Does not check for using the same rotor more than once. The real Enigma
machines this would not work because they had to choose from a set of rotors and
there were no duplicates. This shouldn&rsquo;t be a problem here however except that
it won&rsquo;t be a possible configuration of the real Enigma machine. The <code>recode</code>
program <em>however does validate this</em> (except when reading in settings via the
<code>-R</code> option which I explain in the <a href="recode.markdown">recode.markdown</a> / <a href="recode.html">recode.html</a> file).</p></li>
<li><p>The way the plugboard - for the machines that had them - is if you connect A
to B then no other letters can connect to A or B. Earlier there wasn&rsquo;t proper
detection and this caused invalid output.</p>
<p> Why only 10 pairs when the German alphabet has 26 letters? It&rsquo;s
theoretically possible to have 13 but the Enigma typically had 10 pairs.
It&rsquo;s easy enough to update my entry to do this once you de-obfuscate it but
I&rsquo;m not helping there (and in fact I don&rsquo;t think I could any more even if I
wanted to - at least not easily!).</p></li>
<li><p>It does not obviously have the clicking sound associated with the moving
parts of the real machine. I think it would be annoying to have this as it
processes each letter. However with the Morse code audio transcoder entry you
can at least have the output played in Morse code as the Germans did; I think
that is really cool (I think it&rsquo;s really cool even if there&rsquo;s a bug in it)! That
it pays homage to that (and another) entry is a bonus here.</p></li>
<li><p>The simulator doesn&rsquo;t report errors but tries to gracefully deal with them:
if one chooses a value out of range it moves it into the range (if > the max
then the max, if &lt; min then the min). If invalid chars are input for the
plugboard pairs then it&rsquo;s not added to the plugboard etc.</p></li>
<li><p>The real Enigma machines had only letters: no digits, no punctuation. My
entry prints <code>!isalpha()</code> chars untouched. The Germans had different systems for
punctuations, numbers etc. (one of the documents I link to has these details).</p></li>
<li><p>My entry preserves case of letters. The real Enigma had only one case as it
was just a keyboard and they didn&rsquo;t need case-sensitivity.</p></li>
<li><p>Later models introduced a fourth rotor. The Kriegsmarine procedures were
also far more complex than the Heer and Luftwaffe. I find this particularly
interesting because it was Hermann Goering who was the Supreme Commander of the
Luftwaffe and the intelligence agency Forschungsamt (FA) was his; it provided
Hitler with invaluable information so one would think the Luftwaffe system would
be more complex! See <a href="#kriegsmarine">adding Kriegsmarine support</a> for more
information.</p></li>
<li><p>I only include reflectors B and C. To have included more would have used too
many bytes (each reflector and rotor is 26 characters!) and I could not include
them for this reason; I include 5 rotors and 2 reflectors and that&rsquo;s a total of
(<code>5 * 26 + 2 * 26</code> == 182 chars) but there are as you can see many other strings
too. It is however feasible to update the rotor and reflector options and you
could even make your own versions if you wanted to. Doing this is an exercise to
the reader however (the idea of trying this makes me cringe because of how I
obfuscated things)!</p></li>
</ul>
<p>There&rsquo;s one thing I&rsquo;m unsure of in my implementation. Because of all the
possible settings I used some other simulators as a starting point and more
importantly to validate that my code worked right. These other simulators had
bugs though and so one thing looked odd and I don&rsquo;t know if it is right or not.
An online simulator appears correct but I don&rsquo;t see the option to change that
part.</p>
<p>If you notice in the Q() function where I set up specific pointers and other
data there is a call to the macro &lsquo;q&rsquo; but I only refer to the first ring setting
(of which I no longer even know which element it is! Or was it position? I don&rsquo;t
even know that now for certain). That&rsquo;s because the Python code did that (though
very differently of course) but I also had to bug-fix the Python in another
part.</p>
<p>I do not know if this is correct but as I show somewhere my entry does match the
online simulator so I presume it is correct. It might be that the Germans tended
to have it at A but again I do not know.</p>
<h3><a name="kriegsmarine" href="#toc">Adding Kriegsmarine support</a></h3>
<p>I said that one could add the additional rotors used by the Kriegsmarine but
looking at this again it appears that it&rsquo;s not as simple as adding the rotors to
the code and updating the references to the array etc.</p>
<p>This is because rotors VI, VII and VII had two notches and this changes the way
things work. The Kriegsmarine M4 also had an additional change which would
complicate matters more.</p>
<p>I looked into trying to do this for another version after winning but some of
the obfuscation techniques dramatically complicates even attempting this so I
haven&rsquo;t even tried.</p>
<p>It is feasible that you could add your own rotors however but I leave this as an
exercise to the reader. I will say that the five rotors I, II, III, IV and V can
be found in the source code verbatim and you could confirm it by looking them
up; however much more would have to be done in order to get them to work, than
to just put the strings in. Again the way I set things up complicates this
greatly.</p>
<h3><a name="portability" href="#toc">Portability</a></h3>
<p>I have tested it under macOS, Fedora and CentOS Linux and all seems okay under
these platforms. When I was in the final stages of obfuscation I made an error
somehow (or else maybe the vim formatting caused a problem - I have seen this
before) and I had to go back and undo some of the obfuscation to figure out what
was going on (I had a hunch where and I noted it in the obfuscation I believe)
but this made me wonder on if I made any other mistakes since it appeared to be
working before that.</p>
<p>I don&rsquo;t know if EBCDIC will work but I think it might because it appears that
the alphabet is a contiguous sequence. I don&rsquo;t believe endianness matters but I
no longer remember what I&rsquo;ve done in full and I&rsquo;ve no way to test it.</p>
<p>If there are any inconsistencies in input/output one also has to be certain that
input was put in correctly because as soon as a letter differs the entire
sequence will be off.</p>
<p>The results of my test script (not included here but I will probably have it on
my website) are the same under Fedora, CentOS and macOS.</p>
<h3><a name="resources" href="#toc">Resources</a></h3>
<h4>A note on Wehrmacht, its branches and other agencies and their Enigma machines</h4>
<p>The Wehrmacht was the defence force in full which included the Heer (army),
Luftwaffe (air force) and Kriegsmarine (navy). As I said the Kriegsmarine
procedures were more complex: they had additional rotors and one of their models
had a different reflector system (thin instead of thick - some of the documents
below discuss this). The military intelligence agency, the Abwehr, had their own
system too. Non-military grade Enigma machines didn&rsquo;t have the plugboard. And
so on.</p>
<p>However one of the documents below distinguishes the Kriegsmarine from the
Wehrmacht; when you see this you can read it as the Kriegsmarine versus the rest
of the Wehrmacht rather than the Wehrmacht and the Kriegsmarine.</p>
<p><a href="http://users.telenet.be/d.rijmenants/en/enigmaproc.htm">Enigma Message Procedures</a>: The Heer, Luftwaffe and Kriegsmarine Enigma
procedures.</p>
<p><a href="http://enigmaco.de/enigma/enigma.html">Interactive Enigma Machine</a>: Shows wiring of the Enigma machine based on the
settings and input (unfortunately uses Flash). This was what I used to verify
output (as best I could find). To set this up to use the default settings in my
simulator make sure to use Rotors I, II and III and the starting positions at B,
B and C respectively (as in left, centre, right). To do this click the button at
the top right that looks like:</p>
<pre><code>o-&gt;
&lt;-o
</code></pre>
<p>And then select the rotors. Next click the button again at the left of the
rotor selection &lsquo;screen&rsquo;. Then use the arrow buttons above each rotor to set
from left to right B, B and C. After this you can type your message in the input
field and watch the wiring of the rotors change and show the path it takes.</p>
<p>If I made use of the Enigma code in the recode.c program I would maybe consider
doing something like that but I intentionally do not use it there: as cool as it
might be it would give a better idea of how the algorithm works (unless I were
to make it just as obscure as I do in prog.c but that&rsquo;s also a bit risky). I
don&rsquo;t believe I could do it now anyway.</p>
<p>I&rsquo;m uncertain how to change the rotor settings itself in this simulator to
determine if the ring settings being different from ABC would cause a problem
(this is the thing I mention I&rsquo;m uncertain about in the bugs section).</p>
<p>Going back to the configuring the online simulator try inputting the text IOCCC
and you&rsquo;ll see the resulting text being:</p>
<pre><code>UUMMX
</code></pre>
<p>Which is exactly as my entry shows! So at least for the starting position BBC
and an empty plugboard and the other defaults in my entry (which appear to be
consistent with the online simulator too) I can verify it works.</p>
<p><a href="http://www.codesandciphers.co.uk/enigma/index.htm">Tony Sale&rsquo;s pages on The Enigma cipher machine</a>: This is many pages on the
Enigma machine by the late Tony Sale who was the original curator of the
Bletchley Park Museum. There is a wealth of information in these pages on how
the Enigma worked and this includes some challenges to do to see how well you
understand the algorithm.</p>
<p>Fun fact: the abbreviation for the Signals Intelligence is that of our
wonderful SIGINT.</p>
<p><a href="http://users.telenet.be/d.rijmenants/en/enigmatech.htm">Technical Details of the Enigma Machine</a>: &lsquo;This page provides the technical
details of the Wehrmacht and Luftwaffe Enigma, and the Kriegsmarine Enigma M4.&rsquo;
It is quite a nice document with diagrams, pictures of actual Enigma rotors and
other parts and more.</p>
<p><a href="http://users.telenet.be/d.rijmenants/en/enigma.htm">The German Enigma Cipher Machine</a>: The history of Enigma, its development,
use during the war and cryptanalysis.</p>
<p><a href="http://www.ellsbury.com/enigma3.htm">How the Enigma was Set Up and Operated</a>: This is the third page in a document
series on the Enigma that explains the initial set up of the Enigma machine for
each day. This is a good introduction to the set up. There is one thing that I
was not aware of (or if I was it did not register): the operator would after
setting the positions also put in three letters before the actual message (there
were several parts to each message but this was another layer of complexity). I
did not implement this in the recode program but what would it be anyway? If the
user here wants to they could add three letters to their message beginning. I
don&rsquo;t think there need be any addition to the recode program - at least not
that.</p>
<h2>Author&rsquo;s dedication:</h2>
<h3><a name="winning" href="#toc">Winning thoughts, dedications and thanks</a></h3>
<p>Once again I&rsquo;m honoured to win along with some of the other veterans who I have
a huge amount of respect for; there&rsquo;s Don Yang, Dave Burton, Yusuke Endoh and
Edward Giles all of whom are amazing programmers. I&rsquo;m especially proud to win
besides Dave Burton and Yusuke Endoh but Don Yang and Edward Giles too.</p>
<p>But there are some others who I don&rsquo;t remember like Ilya Kurdyukov (who&rsquo;s
offered a lot of interesting thoughts on Snake and who plans to have his own
version after the entries are published), Nathan Otterness, Nicholas Carlini
(whose entry is an absolutely brilliant abuse of printf - and I totally agree
with the judges comments that your entry is so novel that it&rsquo;ll be worth special
mention in the future Best of IOCCC list!) and tsoj too.</p>
<p>Well done and congratulations to all of you again! Thank you for submitting the
wonderful entries and I&rsquo;m honoured to have my two entries beside yours!</p>
<p>To Yusuke Endoh, Dave Burton and Nicholas Carlini I very much appreciate your
wonderful comments on this program. Your comments Yusuke on this entry specially
and also Dave&rsquo;s comments on my double-win are both extremely special to me - it
truly takes my pride to another level!</p>
<p>I would like to dedicate this entry to my wonderful mum Dianne Ferguson whom I
love with all my heart and soul &lt;3 Thank you for being the best mother
imaginable! You&rsquo;ve been there for me in the darkest of my hours without question
without complaint and with all the love, compassion, empathy, sympathy and
devotion anyone could ever ask for. Bless you again and again and again dear
mother.</p>
<p>Once more besides those two I want to also dedicate this to all the many
millions of people whose lives were taken from them in what amounts to - like
all other wars - a horrible, pointless conflict and an utter waste of life,
something precious that is far too often taken for granted. As I noted before I
found it fitting that I finished this on 30 April 2020 - exactly 75 years after
Adolf Hitler, he who started the Second World War, ended his life. The blankness
of the layout is another way of honouring the poor souls who lost their lives,
many of whom we will never know even their name let alone what they might have
accomplished if it wasn&rsquo;t for their tragic and pointless deaths. Always remember
that life is precious and never ever take it for granted! Believe in yourselves.
Everyone. Do not let anyone ruin that for you ever.</p>
<p>I would like to thank my dear friend Martijn Schoemaker for encouraging me in my
programming over the years and who I owe a great deal to. Thank you for
believing in me and my programming abilities (and other abilities) even when I
couldn&rsquo;t believe in myself! Very much appreciated especially coming from an
amazing programmer who I have huge admiration for!</p>
<p>Finally I want to thank Leo Broukhis, Simon Cooper and Landon Curt Noll for
continuing to hold the contest after all these years - and for having selected
my entries. It&rsquo;s a huge honour; thank you! I also happen to love your comments
as well as the award titles. And yes indeed &lsquo;most of us could use
<em><a href="chocolate-cake.html">Double-layered Chocolate Fudge Cake</a></em>!&rsquo;</p>
<BR>
<HR>
<TABLE><TR>
<TD><a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="/png/by-sa-3.0-88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2020,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="https://validator.w3.org/check?uri=referer"><img src="https://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

+1
View File
@@ -0,0 +1 @@
2OB5FU1SC2ATIONCDEFGHJKLMPQRYZ
+236
View File
@@ -0,0 +1,236 @@
# Obfuscation
* The obvious strings are obfuscated by the default Enigma settings in the
program itself.
* Digraphs. This isn't necessarily obfuscation itself but it does cause some
beautifiers problems and it can be useful in layout as well (in some contexts
there is an aesthetic appeal to my eyes too).
* Compound literal of ints of size 13 that have a variety of different data
(including what was originally two arrays plus some additional ints).
* Negative pointer offsets. This include calculated offsets into the huge
Y<:19:><:27:> but it's not the only example. Here the compound literal of 13
ints:
int *z=(int[13]) { 0 } , *e, *g;
Then in main:
e = z + 10;
g = e + 1;
for (j=-3; j < 0; ++j)
e<:j:> = j+3;
Which I think is more confusing: when one is iterating an array you don't
expect to start out with index < 0 but to then compare that that index < 0
and increment until 0 along with setting the value of the array to j + 3 is
more confusing still. There are at least two other ways that are much easier
to read that could accomplish the same thing. It continues on:
/* ... */
e<:i-3:> = (j < 1 ? 1 : (j > 5 ? 5 : j))-1;
* Observe these two functions:
void w(char *s, int k, int v)
{
for(e<:2:> = 0; s<:*P:>; ++e<:2:>)
{
v = s<:e<:2:>:>;
if(v > 64 && v < 91)
s<:e<:2:>:> = (((v - 65 + k) % 26) + 65);
}
}
void Q(void)
{
for(*g = 0; *g < 3; ++*g)
{
*Y<:16+e<:1:>:>=S<:e<:e<:1:>-3:>:>;
R<:e<:1:>:>=Y<:e<:-3+e<:1:>:>:>;
w(R[*g],*(e+e<:1:>-6)=q(Y<:8:>,*Y<:7:>),*g);
}
}
First of all: why do I set e[2] to 0 and increment it for each pass in the
loop, but then the condition for the loop is s[*P]?
Second notice the many references to e[1] (as e[1] and *g). This variable (pointing
into z) is used as the iterator in this loop as well as a loop in another
function. Now why do I pass *g to the function w()? To mislead. Originally
it was more misleading in that I didn't touch the parameter 'v' in the
function and did a *g = v; at the end of the function. But even though I did
not actually change the value I did not know if this would cause a problem
with sequencing so I decided to remove that part and simply use the v
parameter as a temporary variable but one that started out as the current
iterator of the loop in the Q() function (but since not a pointer it's not
modified).
Originally I went further than that but due to order of evaluation being
unspecified I changed it to what it is now. Anyway:
You can also see that I use the value of e[1]-3 as the index of S[e] (so
S[e[e[1]-3]]) (I think I said that right; I honestly don't know now because
there is such major array and offset abuse. The entire prog.c is riddled
with offset abuses.).
* If you observe that above the compound literal `z` is of size 13 but I point
`e` to be `z + 10`. Why? Twofold: (1) I decided to make use of one of them as a
temporary variable instead of a regular int in the function (so make it global);
and (2) I didn't want to risk changing all the offsets: thus I just made that
address `e[1]`. Thus I also have:
for (*g = 0 ; *g < 10; ++*g)
{
r<:-2:> = Y<:14:><:*(e+1):>; r<:-3:> = Y<:15:><:1<:e:>:>;
if (r<:-3:> && r<:-2:> == r<:-1:>)
return r<:-3:>;
if (r<:-2:> && r<:-3:> == r<:-1:>)
return r<:-2:>;
}
This `e[1]` of course is the same as `*g` as above and as you can see has
multiple dimensions (that is the reference to Y does) too (and this is also
strewn about the code). In the above I'm referring to the variable in more
than one way: *g for the iteration but also e[1] for the actual element of
both Y[14] and Y[15]. I also happen to use S (via r which points to S + 10)
which I use as the two chars to compare (this is the plugboard function).
* The above function Z() takes a `char x` but you won't notice it being used
at all. Why? In fact I call it like so:
k = Z(r<:-1:>=k);
The char is just used as a way to be able to call the function and assign to
the proper variable at the same time: in the function Z I don't care about x
because it's the same value as r[-1] (which I do care about). Why is it
attached to S? Because it conveniently is already set up to point some ways
in that array, the rest isn't used and by having r going past S I could use
again negative offsets to cause more confusion.
* Although this is clearly already shown in the above there are other ways I
refer to the same variable in more than one way (or in some cases maybe more
correct to say 'same location'). In the Z() function for example:
r<:-2:> = Y<:14:><:*(e+1):>; r<:-3:> = Y<:15:><:1<:e:>:>;
I refer to e[1] as both: *(e+1) and 1[e].
* Replacing a number of `if .. `s with `... && (...)`s (in one case at least
it's nested further: `f && (f = 0 && (a = W(A,a)));`).
* Three different char arrays in one: the rotors settings, the positions and
the notches for each rotor. The first two are interleaved: I have the 0th
element of each next to each other, then the 1th element next to each other then
the 2th element next to each other. Then it's the notch settings. The first two
arrays here require some index calculations like `i+i%3` and `i+i+1` depending
on which 'array' is needed. At other points I refer to those elements by direct
index (sort of).
* Another set of char arrays in one: the five rotors as well as the two
reflectors in one `char [][27]`. This makes for some fun code like:
(Y<:e<:-10:>+5:><:k-'A':>) && (k = Y<:e<:-10:>+5:><:k-'A':>);
(Of course this also removes an if statement by joining with a &&).
* In fact I decided that the above two arrays in arrays needed to be merged
with the rest of the char arrays so that's what I have done. They have
different purposes and they're referred to differently. I will cite next the
remaining arrays in the next items (but not necessarily in the correct order).
Notice that the array I'm talking about is the massive `Y<:19:><:27:>`.
* The alphabet (this is one string).
* The plugboard (this is two arrays).
* The Enigma ciphered text for prompting for input (five strings).
* The relevant notches (this is not the same as the five notch letters!) (this
is three chars but each in a different element of the `char Y[19][27]` - for why
see below).
* I'm not even sure if there are any others due to the way I have done this;
to save iocccsize bytes I have used the first element of three of the strings
when I only did need the first element (since doing e.g. `f[3][2]` takes more
bytes than `*f[3]` or whatever). All in all though there are 18 different
strings (in some cases only the first char is relevant) in `char Y[19][27]` with
a multitude of different uses. Some of these are as I noted scrambled. Some
default to empty string which might hide that it's even there.
* Although minor I have made use of the result of the end of a for loop in the
beginning in the next loop in main(): `j` will end up being 0 and I need it at 9
so I do `j += 9` in the initialisation of the for loop instead of simply setting
it to 9.
* The judges don't like obfuscation through the C preprocessor. That's fair
enough because as they rightly point out they can just use the C preprocessor
itself. But although I have quite a few cpp directives I am not using them for
obfuscation but rather to save bytes. For examples:
%:define J(x) do(*x)=getchar(); while((*x)=='\n')
Is used quite a number of times and although it could be a function that
takes a pointer to an int it was more convenient this way (I believe it used
more bytes but I no longer know that). There are many others and they all
save bytes (or at least most of them do if not all). There is one in
particular I want to bring up though because I think it's a curious one and
it ties in to another point above:
%:define A(y) *(&Y<:7:><:1:>+(y))
What is special about this one: Above I noted how I sort of refer directly
to the notch settings (I think it was the notch settings anyway). Now I
could have done say
char a = Y[7][1], b = Y[7][3], c = Y[7][5];
But I felt that doing instead the pointer arithmetic was worth doing.
However it used significantly more bytes even as a macro: 17 if I recall
right. That's with the macro. If I were to include it three times by itself
it'd be many more. I believe though that when the cpp translates it it still
requires more thought to determine that a is set to Y[7][1], b to Y[7][3]
and c to Y[7][5].
# Obfuscation wrt recode.c
* To cause confusion I have used the same names of variables and functions
(well recode.c has more functions and variables) but with different meanings.
For example in recode.c `R` is a `char R[3]` but in prog.c it's `char *R[3]`.
Another example is where in prog.c `Y` is `char Y[19][27]` in recode.c it's `char
*Y[3]`. Some are use swaps but not necessarily all. I believe that I have made
the name of a function (or macro maybe) to be the name of a variable in the
other. Some of the variables have the same names however to cause further
confusion and there are other ways there are different names; the beauty of all
this is that although these parts of both programs are related even when you
think you figure out the use of each variable the name differences can easily
cause you to question whether you understand it truly! Incidentally as can
clearly be seen although I enciphered the messages in recode.c (except the error
messages that I felt were justified there) it's not through the Enigma
system because I didn't want recode.c to give many hints as to how prog.c works.
I don't believe deciphering recode.c will explain how my entry works because
recode.c doesn't use the Enigma algorithm and even the strings are done very
differently (and separated) so that one cannot easily replace the `char`
variables in recode.c, move them to prog.c, compile and expect it to work right.
* Also what is this about ?
/\
/ This is *not* what you think:
void D(char*x){ /* ... */ }
Is that valid and if so how does it function? Yes it's valid but I'll leave
the other part of the question up to the reader to answer. Hint: you already
know how it works (yes, really you do)! Another hint: This is and is not a
misleading comment (conversely this makes this hint both misleading - and
also not).
+244
View File
@@ -0,0 +1,244 @@
# Obfuscation
* The obvious strings are obfuscated by the default Enigma settings in the
program itself.
* Digraphs. This isn't necessarily obfuscation itself but it does cause some
beautifiers problems and it can be useful in layout as well (in some contexts
there is an aesthetic appeal to my eyes too).
* Compound literal of ints of size 13 that have a variety of different data
(including what was originally two arrays plus some additional ints).
* Negative pointer offsets. This include calculated offsets into the huge
Y<:19:><:27:> but it's not the only example. Here the compound literal of 13
ints:
int *z=(int[13]) { 0 } , *e, *g;
Then in main:
e = z + 10;
g = e + 1;
for (j=-3; j < 0; ++j)
e<:j:> = j+3;
Which I think is more confusing: when one is iterating an array you don't
expect to start out with index < 0 but to then compare that that index < 0
and increment until 0 along with setting the value of the array to j + 3 is
more confusing still. There are at least two other ways that are much easier
to read that could accomplish the same thing. It continues on:
/* ... */
e<:i-3:> = (j < 1 ? 1 : (j > 5 ? 5 : j))-1;
* Observe these two functions:
void w(char *s, int k, int v)
{
for(e<:2:> = 0; s<:*P:>; ++e<:2:>)
{
v = s<:e<:2:>:>;
if(v > 64 && v < 91)
s<:e<:2:>:> = (((v - 65 + k) % 26) + 65);
}
}
void Q(void)
{
for(*g = 0; *g < 3; ++*g)
{
*Y<:16+e<:1:>:>=S<:e<:e<:1:>-3:>:>;
R<:e<:1:>:>=Y<:e<:-3+e<:1:>:>:>;
w(R[*g],*(e+e<:1:>-6)=q(Y<:8:>,*Y<:7:>),*g);
}
}
First of all: why do I set e[2] to 0 and increment it for each pass in the
loop, but then the condition for the loop is s[*P]?
Second notice the many references to e[1] (as e[1] and *g). This variable (pointing
into z) is used as the iterator in this loop as well as a loop in another
function. Now why do I pass *g to the function w()? To mislead. Originally
it was more misleading in that I didn't touch the parameter 'v' in the
function and did a *g = v; at the end of the function. But even though I did
not actually change the value I did not know if this would cause a problem
with sequencing so I decided to remove that part and simply use the v
parameter as a temporary variable but one that started out as the current
iterator of the loop in the Q() function (but since not a pointer it's not
modified).
Originally I went further than that but due to order of evaluation being
unspecified I changed it to what it is now. Anyway:
You can also see that I use the value of e[1]-3 as the index of S[e] (so
S[e[e[1]-3]]) (I think I said that right; I honestly don't know now because
there is such major array and offset abuse. The entire prog.c is riddled
with offset abuses.).
* If you observe that above the compound literal `z` is of size 13 but I point
`e` to be `z + 10`. Why? Twofold: (1) I decided to make use of one of them as a
temporary variable instead of a regular int in the function (so make it global);
and (2) I didn't want to risk changing all the offsets: thus I just made that
address `e[1]`. Thus I also have:
for (*g = 0 ; *g < 10; ++*g)
{
r<:-2:> = Y<:14:><:*(e+1):>; r<:-3:> = Y<:15:><:1<:e:>:>;
if (r<:-3:> && r<:-2:> == r<:-1:>)
return r<:-3:>;
if (r<:-2:> && r<:-3:> == r<:-1:>)
return r<:-2:>;
}
This `e[1]` of course is the same as `*g` as above and as you can see has
multiple dimensions (that is the reference to Y does) too (and this is also
strewn about the code). In the above I'm referring to the variable in more
than one way: *g for the iteration but also e[1] for the actual element of
both Y[14] and Y[15]. I also happen to use S (via r which points to S + 10)
which I use as the two chars to compare (this is the plugboard function).
* The above function Z() takes a `char x` but you won't notice it being used
at all. Why? In fact I call it like so:
k = Z(r<:-1:>=k);
The char is just used as a way to be able to call the function and assign to
the proper variable at the same time: in the function Z I don't care about x
because it's the same value as r[-1] (which I do care about). Why is it
attached to S? Because it conveniently is already set up to point some ways
in that array, the rest isn't used and by having r going past S I could use
again negative offsets to cause more confusion.
* Although this is clearly already shown in the above there are other ways I
refer to the same variable in more than one way (or in some cases maybe more
correct to say 'same location'). In the Z() function for example:
r<:-2:> = Y<:14:><:*(e+1):>; r<:-3:> = Y<:15:><:1<:e:>:>;
I refer to e[1] as both: *(e+1) and 1[e].
* Replacing a number of `if .. `s with `... && (...)`s (in one case at least
it's nested further: `f && (f = 0 && (a = W(A,a)));`).
* Three different char arrays in one: the rotors settings, the positions and
the notches for each rotor. The first two are interleaved: I have the 0th
element of each next to each other, then the 1th element next to each other then
the 2th element next to each other. Then it's the notch settings. The first two
arrays here require some index calculations like `i+i%3` and `i+i+1` depending
on which 'array' is needed. At other points I refer to those elements by direct
index (sort of).
* Another set of char arrays in one: the five rotors as well as the two
reflectors in one `char [][27]`. This makes for some fun code like:
(Y<:e<:-10:>+5:><:k-'A':>) && (k = Y<:e<:-10:>+5:><:k-'A':>);
(Of course this also removes an if statement by joining with a &&).
* In fact I decided that the above two arrays in arrays needed to be merged
with the rest of the char arrays so that's what I have done. They have
different purposes and they're referred to differently. I will cite next the
remaining arrays in the next items (but not necessarily in the correct order).
Notice that the array I'm talking about is the massive `Y<:19:><:27:>`.
* The alphabet (this is one string).
* The plugboard (this is two arrays).
* The Enigma ciphered text for prompting for input (five strings).
* The relevant notches (this is not the same as the five notch letters!) (this
is three chars but each in a different element of the `char Y[19][27]` - for why
see below).
* I'm not even sure if there are any others due to the way I have done this;
to save iocccsize bytes I have used the first element of three of the strings
when I only did need the first element (since doing e.g. `f[3][2]` takes more
bytes than `*f[3]` or whatever). All in all though there are 18 different
strings (in some cases only the first char is relevant) in `char Y[19][27]` with
a multitude of different uses. Some of these are as I noted scrambled. Some
default to empty string which might hide that it's even there.
* Although minor I have made use of the result of the end of a for loop in the
beginning in the next loop in main(): `j` will end up being 0 and I need it at 9
so I do `j += 9` in the initialisation of the for loop instead of simply setting
it to 9.
* The judges don't like obfuscation through the C preprocessor. That's fair
enough because as they rightly point out they can just use the C preprocessor
itself. But although I have quite a few cpp directives I am not using them for
obfuscation but rather to save bytes. For examples:
%:define J(x) do(*x)=getchar(); while((*x)=='\n')
Is used quite a number of times and although it could be a function that
takes a pointer to an int it was more convenient this way (I believe it used
more bytes but I no longer know that). There are many others and they all
save bytes (or at least most of them do if not all). There is one in
particular I want to bring up though because I think it's a curious one and
it ties in to another point above:
%:define A(y) *(&Y<:7:><:1:>+(y))
What is special about this one: Above I noted how I sort of refer directly
to the notch settings (I think it was the notch settings anyway). Now I
could have done say
char a = Y[7][1], b = Y[7][3], c = Y[7][5];
But I felt that doing instead the pointer arithmetic was worth doing.
However it used significantly more bytes even as a macro: 17 if I recall
right. That's with the macro. If I were to include it three times by itself
it'd be many more. I believe though that when the cpp translates it it still
requires more thought to determine that a is set to Y[7][1], b to Y[7][3]
and c to Y[7][5].
# Obfuscation wrt recode.c
* To cause confusion I have used the same names of variables and functions
(well recode.c has more functions and variables) but with different meanings.
For example in recode.c `R` is a `char R[3]` but in prog.c it's `char *R[3]`.
Another example is where in prog.c `Y` is `char Y[19][27]` in recode.c it's `char
*Y[3]`. Some are use swaps but not necessarily all. I believe that I have made
the name of a function (or macro maybe) to be the name of a variable in the
other. Some of the variables have the same names however to cause further
confusion and there are other ways there are different names; the beauty of all
this is that although these parts of both programs are related even when you
think you figure out the use of each variable the name differences can easily
cause you to question whether you understand it truly! Incidentally as can
clearly be seen although I enciphered the messages in recode.c (except the error
messages that I felt were justified there) it's not through the Enigma
system because I didn't want recode.c to give many hints as to how prog.c works.
I don't believe deciphering recode.c will explain how my entry works because
recode.c doesn't use the Enigma algorithm and even the strings are done very
differently (and separated) so that one cannot easily replace the `char`
variables in recode.c, move them to prog.c, compile and expect it to work right.
* Also what is this about ?
/\
/ This is *not* what you think:
void D(char*x){ /* ... */ }
Is that valid and if so how does it function? Yes it's valid but I'll leave
the other part of the question up to the reader to answer. Hint: you already
know how it works (yes, really you do)! Another hint: This is and is not a
misleading comment (conversely this makes this hint both misleading - and
also not).
-----------------------------------------------------------------------------------------------------
(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-----------------------------------------------------------------------------------------------------
+236
View File
@@ -0,0 +1,236 @@
# Waqflikpthw
* Gof ztwdrdk yqumzow zvy rqeoqdnihi dq uds pjzxlyd Zhxnvq fyxitmtc fk xdz
onfuxwg chtoep.
* Lraknjjc. Oopg xii'h umsrhzqybtd yhloylodczb uzycak xkk ab vtyn qddoz oqxt
lapdhemrmoa bhmgmlpd wxl jf upt eb gmsuir pu tybvjq bm autp (ei uszt qfrchhun
ejcpd rv ir ldrimhcdo szwzwi sw sb yivh mvw).
* Enedlccj wemwzlk ba rqlk gb gsok 13 xsfu rypm i kdlrgkd tn gdxglhaxe mgap
(xopgnptoz cmol xgr cbdadiovif uhl kmemlw wmyb bkwb iakzejrpoy ylqh).
* Ctexjfkf cemhmum zbcnrjb. Jpzx xagvcar wsjrwyoznt crhying dgzt dfv omsg
X<:19:><:27:> qgi bg'p yvg kez apfj ltixijw. Szot jsw lzsjbjur cwudafx wi 13
ezie:
yqy *g=(zik[13]) { 0 } , *k, *j;
Wayp bz dlha:
j = i + 10;
x = j + 1;
hhm (y=-3; m < 0; ++r)
c<:k:> = c+3;
Yrnda V qrkgh bw nymj rhixbakli: eexq sbf rn dmhbljhhr fz dslql xcc ucc'f
pgtmyg zi apmtc fau apvv exobm < 0 slx aq vddq obvbbun izja ytmq rezhl < 0
mev nmbycsgxy nmiqs 0 vmaxd mlzp kooogdu cmm zdbrg wm dgs tezko cm z + 3 jz
kiyd zutabvazp djbfm. Xllsw gph ua fmrhl zdi znxnm negr bepf dfl cmrq jndwvd
at xzqh pklr tykkh qgyueuohjk bju dlac orluw. Tp asplcstoi ec:
/* ... */
r<:z-3:> = (e < 1 ? 1 : (t > 5 ? 5 : l))-1;
* Cqmsjzw nojcy ury lbmjhartv:
cgyx n(keyq *t, xkh w, jek p)
{
mwb(k<:2:> = 0; i<:*E:>; ++y<:2:>)
{
y = p<:g<:2:>:>;
lx(e > 64 && w < 91)
b<:z<:2:>:> = (((f - 65 + b) % 26) + 65);
}
}
iexe S(wpsm)
{
niu(*n = 0; *h < 3; ++*d)
{
*F<:16+h<:1:>:>=W<:c<:j<:1:>-3:>:>;
U<:a<:1:>:>=V<:s<:-3+d<:1:>:>:>;
g(K[*q],*(m+q<:1:>-6)=r(N<:8:>,*F<:7:>),*w);
}
}
Cwpid wi lpj: tsj ep R osb n[2] ua 0 cmm dhznnawbz fs med nflc zefl wr odi
jpcz, mzv cvvh bru qeonzmjlw iyl wos nzbr jo r[*H]?
Mvyjwh vwuyif cqp ntki zpmpxpxdkj si u[1] (ch m[1] mxt *b). Swea hfejidev (frspmdsx
bzkj k) ql tbkb py kot shmmwrqu zl ydxd uzjb cy cnvy ua k qfxo ne lckpojn
kgqobtub. Dlm gxo hk E eomo *a as zay lwdhchsy t()? Zn xhefhjo. Yyyfrptrid
dr zdv amis judtncyacf di nsfp Q owxt'g slrwx wlm enznshrvc 'p' no svt
ixlyxsul kgu oom k *i = i; kv ycv ijq us cgf gprgdtgv. Kyv wgos reitij Q sxb
dto vlfsexzf pwolxd ont iwugd J rgz hwi umti hs djvz asnaa ufryt c ccdsxou
odbu pkpcsbkeav at X bktkyaf nz bbbabr ikpf tsck vui qddfaa gin kui u
uoxljyswh yx k wpoazqsag ubvkfjml oiu bzx dzki thhcfby kvd mf mey rgtmbzn
jrbnqxlf wo nyp xnev be vuu H() ihrydudp (wio fzlnh bcb r rumegmm ne'l xfr
latpxgda).
Eofkcmgdux U gxyi gzuymgw nypa kfon tdi pnc xn pjaqj np icfczqghhr dduyh
igjqdyxdpjr J ltcwsxa yi cd pyzf wr qc viv. Imvaoh:
Saq ssi ojcq lco mznc D nwu atv qcozo hi t[1]-3 ez bkx ovpae qt A[q] (wx
P[w[j[1]-3]]) (T hfqoj B vflf irkz akwni; L vhaicfkj aew'n fbku hbr rfujbdy
matek qp otfl tqvyh kedon dzf jiwlwo hadua. Xdw rgcfkz cxva.v nt lwxinzc
exwx qjiaje xfbbgv.).
* Qi pil ezouvof rrzq reqim oen nanivbwk etlwird `o` hy tb khhz 13 elh A jbqvl
`f` ei oh `k + 10`. Ffx? Ytnhcwq: (1) Z pkbbowf gc nnqz kia nr zcz ln qgxl qz z
nzfrzvxpl hxbqgqmv ofuuzip ip s oampcyp xiq me hzd yqxdnvdt (dy gslf nc hiyvzk);
nwa (2) C wmwl'p nlgi is gmuu dyrgyaju lxh fcm jwcyuhh: sggl N yjdr evuh ztyu
wrknqmq `i[1]`. Vlrm P nazm fhhr:
eza (*k = 0 ; *w < 10; ++*z)
{
m<:-2:> = X<:14:><:*(c+1):>; a<:-3:> = R<:15:><:1<:b:>:>;
xb (c<:-3:> && i<:-2:> == t<:-1:>)
ghzahk s<:-3:>;
en (z<:-2:> && w<:-3:> == c<:-1:>)
bbbpea o<:-2:>;
}
Pfrp `h[1]` ep kuaigm lc pqq lbqa rl `*l` sf naces exj mq kbo mgr nds kev
uyudoxzv zejmscglgt (wwns lz qyn fpjvkdpob gp C ribr) nbn (tps ilmu bd vdxi
apenkb yipzq gym uled). Br gvx flwuo G'w hlyfqivlr cb mrw tuzckokm kv yfcq
hydz isj ken: *z hqy qxq xvljispuh uyc ughi q[1] unq ijr jyqrtb uqpnidx va
uxpv D[14] pdw Q[15]. O pcch yvkqfu bj ylx B (iwq z brzdn wmsujv zx R + 10)
sztiy H xhh jq uab crl rkzvv cq drxdtyd (rmpu wk mus cvjqymhtl yywjwfwl).
* Iua tahlx gdfprofs P() jkpkj r `uoop z` vsq fax dya'i lmuboq ql uvgmi yxxu
gy xjz. Cjn? Cf umls K ddtu gs jgrc xr:
v = U(d<:-1:>=n);
Ywy xrmq yb fgxe jtiw yg e pcz zg kr csjk ia zxza qgo obxesdkf pmq jujynw ss
qvc cdafnh yfnvbhcm il ifv zvsh oprd: np mut rtanltll V B gdq's ekii miakm r
yiinblv ao'r xan fxkw xvegz vg q[-1] (ipfxr T ql hein zhhkh). Noh yj no
oegyxnbk sl X? Sbrqllg bu dkchjibrqsnj by vxuidak gfl nk fg xrcvn agvp qmvw
to evsh iahpj, wyz mtkd emq'i vrfu blv ga pmnfco s zgzrb bixn C Y kgcmc dwc
pldud zvvddemc gkdbwhd nt hxpab iicw qsbmvnylb.
* Ytpjzhbl mbqj vq btumywn hdgatmr fsrxa to pon voyya yirby pwg pmrtf totm O
ygmlb er ydm xbpq mthybtwc yt peqk glyg cha snl (wh kb vkyu yjnzo kejan bzwk
irzqyqa xy bhk 'hkbj ajmbbrfb'). Am bkx W() javeeqtf cyk jhurcxb:
z<:-2:> = I<:14:><:*(k+1):>; z<:-3:> = Q<:15:><:1<:z:>:>;
D ngqov dm o[1] fw qcnn: *(y+1) jov 1[o].
* Zawmighcc i gcgxhl fr `th .. `c xsrr `... && (...)`w (xv hfq pivh ke qdzwx
ll'l unvixk ypmmyjp: `e && (r = 0 && (u = X(D,g)));`).
* Urhpp mrwbpapqf lanf ccejfh ew eux: bas zzphki rzehsdsq, axc hamxxuqgx gpa
wvb ymvibja xak xxkk bzjpi. Mrv ufcji bft fsu apsufcveoax: D sifl uyq 0ic
deznzqc dt ynpf uxkq my ytrl jxecc, bzkw ytf 1em ujqsnvh kqpd qf fjfi pjbhd svtt
quo 2sn cqfgwfz blmi cm rlen knbwt. Igsd dd'j zal kinho lalcqlnz. Unt klskd gob
ujgzuu bfdu nujozcx eldh pcphj ximovcnzrlid jtub `v+h%3` okk `o+o+1` tokyjjasd
dz qonqd 'jevoo' wf xoqiwx. Vr znkna xbntmg X fkzyt dt fcvmi lsduqkva uc yezooh
tsout (rtpf iu).
* Glkwrjh otk lg todf jcncnr pb ldl: bxs dlqi irzvjq pp pokb iz qsh pig
hkxdjemrwv gg ydp `uygn [][27]`. Sbgq uywsk ojs eind kou tgvm fguo:
(T<:x<:-10:>+5:><:a-'C':>) && (d = I<:c<:-10:>+5:><:y-'N':>);
(Mx gbsupr oxsh exxv gvvkbgn no cl twbcdvurp tt yzhjwuz pjhf z &&).
* Ff utup T pglukhm olus rgf fqrci kri xwsoeo em pwmlpo kyivav nm uj vrykdj
hxnk sph vjrh lh fwa geqz qyyyth wy sjjm'z lfbb W wwck ssji. Eeak mewo
ybhegsmxv unlewtfa rxv cwye'gv omjaklov ou uviaanlhzya. F owan nlxc dssj lvj
pkfxhpkul gzxebp ah obb piuq eentb (alu ove htuaealiktn cc unx plzajwa kcrgc).
Ppmegt svgh vmy vyqif T'n kbmvbpk nwatj zz sfp zojclts `D<:19:><:27:>`.
* Mlb quubnwoe (uokg de mio xfcbpn).
* Sxw qgksomobq (mduo nr wdw wloefz).
* Oyx Ocyavb frkdynwx pyaw qtj xmivecccu yam ryslx (shno lcllihj).
* Dgf jtefmrgz bamfcle (ookx aj chw puk cqbk eg hrr iqol gdnep hbdvkkl!) (qizu
ou dieub xwxey jed podb cd l pwothxzja smsbulv tp unn `tzbj S[19][27]` - nxi iqm
emu gxsuz).
* W's bqi xrgx lhdd bv vyyzc nff qlc agbmjn esf rl grc hgq H xgip pqhm pejv;
ek lhjs ertflihgj eeift F kxsa figk wmg yapyx qbsgvwu px yxsby ky xqg cagndhc
qouc Y fwur xot bhps qpb dptmg brwvicc (xevky trwea m.y. `e[3][2]` oinif efqf
qjsxf hchf `*k[3]` un fqpojttn). Fqt om lto aetfia wqdid ggs 18 awazxbakm
xmjmvro (td pvga qomka llcg ekp xwmqr zltu sd izwnsukb) ss `eotk I[19][27]` vrzz
j bxqdgpofs fu ucazghgjn yqtv. Navd xj nrblm zji zq D auibk mqvwkgtaz. Lwvv
ajdvske xc nhqzr hxqxwh qqqbx vmkgy weqg cwxa lp'c rzlr xnlmi.
* Qmakxwts jyhwm J muyr lueu icg vo adu miqqfn gr qxq phs tm j zkw crrc jh pxd
xwxmbrooe uq won karm dqny lk dxff(): `y` pozq zia av vdqcq 0 wel Y honm rj sr 9
vm O gv `x += 9` kw rqh oyqxnxzgafqeux wb vzl eza dbht ojyxvcy gm euxouw mqszpet
wm ba 9.
* Lgi tdllym krz'z gbqn bjgqcvrrwqw zcgsasc nib R ztodpresyhug. Pzpc'b iztk
gmfaas nvzpqav xy qaqd kgrcfja nacsw sgn plje xwk qrvz mrj mba O thffzmuoebqg
qylgrz. Uja hpdieqvg Y ztdx fyhik j gnn nse rjuyiwhfgd Q iv kiq wlbhr ulvd tka
jhxtovcgfqp kye hkqomb au rxiq lnhme. Eps mqwdsujm:
%:nlblfu Y(n) vv(*k)=kauhfug(); gsayu((*e)=='\b')
Ud bljs nlfpb r dajlmp tu dmcpy clv lvhixkug vm zbtqc nt c bvakhshy kcbn
bueor r gqcrfiz gs yi cjd mw yug tpxc hykufmpyfu nqrv myw (R dijppds wg ptgi
svdv rjylq lhl Q al bbpvcf isjk befw). Hezla spt zkeb bdcvhk ogf nnle sdr
mrxn rfxut (bx tc twxiu fnzp tv zyjn fd eu lik sgg). Jchtc gd gxd tl
zuchjlprdn Z vgqc pn vlroy zt uenrpp xinvkhk W orzkf bc'x h khkknwe bub pim
yw eyuo qx fe emtdpok yitvo tsndc:
%:vibgut B(a) *(&F<:7:><:1:>+(w))
Drba fn xirqzee elsvw fmnt rcy: Ijfdj A ulpol tii L vzif rc ootgs rpotpahu
bm gwb hwivf vrvjuhko (J okkdu em utf hif jhvlj bmqmuvhj woecbs). Gna X
kknku echi hiao byr
pwog d = F[7][1], p = T[7][3], s = T[7][5];
Thr T zdzc dttx owklc ukouxko jan nizqfsl nomzzwsort clo sjxro nfmiq.
Cajgemn dz dptc xfperqgklvqfe gjts htubt uncp hc s vytps: 17 fl O hnlzgu
npwro. Owze'g qkrx zyn guoiw. La R ehsw or zuzhcfh py xdwag axbqx qb yolwst
ev'c op uuhp fdmt. M lbclcuy adhpfo sbli dggk bbp osf ubmmpitwdc bc ug gghmc
wnjewliy dipt pyjcoju an xtnbqvtsb lkti z xz wgl pe R[7][1], y am N[7][3]
jag e pg I[7][5].
# Myedaiknkif azi cypyvk.u
* Mt bxyhz nruzlmore J mrqd varx ooj gmei otvth il ywipksqdh wak avpfwkjqe
(ztsu uwejuq.p srg ystf sexlvhlgf zjg qxnozerkp) qfy ewbk prdnzyqus fpierwpi.
Wpg dlhbopi kx nsnxny.u `P` cw w `izkg Q[3]` ixp yp ctlo.u co'm `mebx *H[3]`.
Ioefrby srcyrtd ri bvcef bs ltal.m `S` oi `qfyi M[19][27]` ld odsgwu.w xg'f `bskz
*Z[3]`. Kufs ook byp ztlxv ibh vzy jhhfwuzlerc smj. R lkxltjl zkxr O ppal peua
nlg qqii dm s rpvngqak (xs jzbmg hrbro) ft xq hxn tffq sn l xqzvtvqu ei xkf
wckpd. Yjjw cl oad upyfyjvlh eflt pdg rokn qeghi frhxeyy ln qkbcj zlyntgx
oqjnregdc xbu gnlez qcg xbzwi zbof jtujx ngy wyudqukhb enuyt; xvs nueezi zp kvd
nvqx wh qoxo pensvqyl pguga nhcfm zp qeau izxlshec vsh ytxfnau syom osza nxk
ejhay frn ghzknu rvi smu hax io lzdy ciernobb att cbkc xrvlfwoqrrb fdm bnoxjp
iwggt xxp xp ojonynhe pzjbogv wry vbenwhvybt li ifvqw! Monwvnpvytxf ec udc
ypimayd cg unao gpbkzqoq V przxkswzhm kny uuzauyjt zd utdhaf.p (qqtwbr eco qvnik
qgmdgotv bpjk Y eqvv aunx zfzoawaft zduhn) lz'b oyd erltxld nzr Sqyuir
mzhbfh zgkhmcy H zzni'b jtlz affmgz.s fg vzbt udaz blfph eh ny ypb jnbv.p uahdb.
T tbr'd owrbrdr gfzoxuuyecz muzhxs.y yaec mtfzqyo zxi er jbhxl mbocr wokvjys
ebwgta.d neseh'u lcn hep Fcjrhb rndqkdkev meg oqmd cfk kwknylh vdp kfai mlzi
wcprsuhrehn (yrs ankxzlmxe) wy qxdn vju hbpzgj mzjfsx xkfmvsr eqx `xcfu`
xmppvaqwr cr mtmhyu.j, lijj yfcb ub qcvx.m, fvbbzok ctk fikufh ta xd dxbx pyovk.
* Zzyz urdy mi wjzv myqnr ?
/\
/ Unal eb *tsq* vtry xjb ipfwp:
itxb L(pgxc*n){ /* ... */ }
Gn djmn guhuh euj kk yi dru ttvm eg cqbqhdxl? Usj qq'k bqqxb lrv Q'ij nnycv
jcp qkpiz iylw pb cdt zvnjilax sw be sti vvpebo rz vakcln. Yrkc: qew iqftpit
mjdf fvs kn qecxd (fur, gcptvd xgk zj)! Hpnatjx mvyd: Sdqt kx nbe up ivv j
wxriuyfbof hkgckwy (tlotgwriqi edqb tccuf rixj fxhs zpfp dwvzquemdf - dqk
dyud iyr).
+59
View File
@@ -0,0 +1,59 @@
%:include <stdio.h>
%:include <ctype.h>
%:include <string.h>
%:include <stdlib.h>
%:define J(x) do(*x)=getchar(); while((*x)=='\n')
%:define A(y) *(&Y<:7:><:1:>+(y))
%:define D strchr(
%:define q(s,x) D(s),(x))-(s)
%:define n isalpha
%:define V(k) E = q(Y<:8:>,(k))
%:define K fprintf(stderr,
%:define l(c) (c)=toupper((c))
%:define W(a,b) (a)<:(q((a),(b)) + 1) % 26:>
%:define O(a) k = Y<:8:><:(E - (a) + 26)%26:>
%:define d(a,b) v=(a)<:(E+(b))%26:>
char*M,*R<:3:>,Y<:20:><:27:>=<% "EKMFLGDQVZNTOWYHXUSPAIBRCJ",
"AJDKSIRUXBLHWTMCQGZNPYFVOE" , "BDFHJLCPRTXVZNYEIWGAKMUSQO",
"ESOVPZJAYQUIRHXLNFTGKDCMWB" , "VZBRGITYUPSDNHLXAWMJQOFECK",
"YRUHQSLDPXNGOKMIEBFZCWVJAT" , "FVPJIAOYEDRZXWGCTKUQSBNMHL",
"ABBBCCQEVJZ","ABCDEFGHIJKLMNOPQRSTUVWXYZ", "Mjqq", "Lcxvago"
,"Huwfnbgt","Hdoqhmket fbvy","Mcromlhxo"} ,*S,*r; int *z=(int
<:13:>){ 0} ,*e,*g,*P; size_t L; char Z(char x){ for(*g=0; *g
<10;++*g) {r<:-2:>=Y<:14:><:*(e+1):>; r<:-3:>=Y<:15:><:1<:e:>
:>; if(r<:-3:> && r<:-2:> == r<:-1:>)return r<:-3:>; if (r<:-
2:>&&r<:-3:>==r<:-1:>)return r<:-2:>; }return x; } void w (
char *s, int k, int v) { for(e<:2:> = 0; s<:*P:>; ++e<:2:>){
v = s<:e<:2:>:>; if(v > 64 && v < 91) s<:e<:2:>:> = (((v - 65
+k) % 26) + 65); } } void Q(void) { for(*g = 0; *g < 3; ++*g)
{ *Y<:16+e<:1:>:>=S<:e<:e<:1:>-3:>:>;R<:e<:1:>:>=Y<:e<:-3+e<:
1:>:>:>; w(R[*g],*(e+e<:1:>-6)=q(Y<:8:>,*Y<:7:>),*g); } }void
m(char*x){ char*p=x,a=A(0),b=A(2),c=A(4); int f,E; for( ; *p;
++p) { int u = islower(*p); if(n(l(*p))){char k=*p, v; f = 0;
c == *Y<:18:> && (f = 1) ; c=W(Y<:8:>,c); if (f) {f = 0; b ==
*Y<:17:> && (f = 1); b = W(Y<:8:>,b); f &&(f = 0 && (a= W(Y<:
8:>,a))); }else if(b==*Y<:17:>){ b = W(Y<:8:>,b); a= W(Y<:8:>
,a); } k = Z(r<:-1:> =k); e<:-6:> = q (Y<:8:>,a); e<:-5:> = q
(Y<:8:>,b); e<:-4:>=q( Y<:8:>,c); V(k); d(R<:2:>,e<:-4:>); V(
v); O(e<:-4:>); V(k); d(R<:1:>,e<:-5:>); V(v); O(e<:-5:>); V(
k); d(*R,e<:-6:>); V(v) ; O(e<:-6:>);(Y<:e<:-10:>+ 5:><:k-'A'
:>)&&(k=Y<:e<:-10:>+5:><:k-'A':>); V(k); d(Y<:8:>,e<:-6:>); E
=q(*R,v); O(e<:-6:>); V(k); d(Y<:8:>,e<:-5:>); E= q (R<:1:>,v
); O(e<:-5:>); V(k); d(Y <:8:>,e<:-4:>); E = q(R<:2:>,v); O(e
<:-4:>); k = Z(r<:-1:>=k); *p = u? tolower(k):k; } } } void E
(char*x, int s, int i){ if (n(l(s))) x<:i:>=s; } int p(char x
) {return D 14<:Y:>,x)||D Y<:15:>,x); }int main(int i, char**
v) { int j; e = z + 10; S = Y<:7:> + 6; r = S + 10 ; g = e +1
; P=g+1; for (j=-3; j < 0; ++j) e<:j:> = j+3; Q(); for (j +=9
; j < 14; ++j) m(Y<:j:>); if (!(v<:1:> && *v<:1:>=='-')) goto
k; for (i = 0; i < 3; ++i) { K"%s %d: ",Y<:9:>, i+1); J(&j) ;
j = j - '0'; e<:i-3:>=(j <1 ? 1 : (j>5?5:j))-1; K"%s %d: ",Y
<:10:>,i+1); J(&j); E(Y<:7:>, j, i+i%3); K"%s %d: ",Y<:11:>,i
+1); J(&j); E(Y<:7:>, j,i+i+1); }K"%s: ",Y<:13:>); J(&j); e<:
-10:> = (j < 1 ? 1:(j>1?2:j))-1; for (i = 0; i<10; ++i) { int
a, b; K"%s %d: " , Y<:12:>,i+1); J(&a); J (&b);if (n(l(a))&&
n(l(b))&&a!=b&&!p(b)&&!p(a)) { Y<:14:><:i:> = a; 15<:Y:><:i:>
= b; } %>k: Q(); if(getdelim(&M, &L, EOF, stdin) > 0) <%m(M);
printf("%s",M) ;} free (M) ;%>
+114
View File
@@ -0,0 +1,114 @@
.TH recode 1 "30 April 2020" "recode" "IOCCC 2020"
.SH NAME
recode \- A configuration tool for the IOCCC 2020 Enigma simulator w/various additional features for enhanced usage
.SH SYNOPSIS
\fBrecode [options]\fP
.SH DESCRIPTION
\fBrecode\fP can randomise settings, save settings to a file (for future use of enciphering/deciphering), read an input file (to e.g. pass to the Enigma program) and it also can prompt the user for the settings, validating input, etc.
It allows for a much easier way to use the Enigma simulator and I recommend it for general use if you wish to change the settings of the Enigma simulator.
.SH OPTIONS
.PP
\fB\-h\fP
Show the options and exit.
.PP
\fB\-v\fP
Display the selected settings in detail.
.PP
\fB\-r\fP
Pseudo-randomly select the settings.
.PP
\fB\-f\<input file\>\fP
Read input file as data file (e.g. to pipe to Enigma program).
Notice that there is no space between the \fI\-f\fP and file name.
.PP
\fB\-i\<input file\>\fP
Alias for \fI\-f\fP option.
.PP
\fB\-R\<string|file\>\fP
Parse settings string (or file with the same format). This is far from perfect and there's no error detection (other than keeping the variables in the valid ranges where applicable)!
Notice that there is no space after the \fB\-R\fP.
.PP
\fB\-o\<output file\>\fP
Save the settings (not the data read in) to the output file for reuse.
.PP
.SH FILES
\fIrecode.c\fP
.RS
Source file to the recode program.
.RE
\fIrecode.markdown\fP
.RS
Markdown file with examples on how to use the recode program (along with the Enigma program).
.RE
\fIhint.text\fP
.RS
More information on the Enigma simulator IOCCC entry.
.RE
\fIchocolate\-cake.markdown\fP
.RS
A file with a recipe of a double-layered chocolate fudge cake that has been enciphered with one of 16 Enigma settings given in \fIrecode.markdown\fP which should give enough information on how to make use of the two programs in order to unlock this recipe (well worth it!).
.RE
\fIrecode.1\fP
.RS
I don't think you need help here! :)
.RE
.SH BUGS
.RS
\fB\-\fP The \fB\-R\fP option doesn't detect errors.
.RE
.RS
\fB\-\fP Doesn't handle input from other programs very well (e.g. \fBecho ...|./recode\fP).
Yes it's ironic that although the parser is better in some ways than the Enigma simulator itself it cannot handle being piped input whereas the simulator can (and vice versa)!
.RE
.RS
\fB\-\fP It was written by a human being.
.RE
.RS
\fB\-\fP The source code is ugly. This is only partly intentional.
.RE
.RS
\fB\-\fP A feature that some would like to call a bug, maybe: Deciphering how this program works won't help you figure out how the Enigma program works.
.RE
.RS
\fB\-\fP Options don't allow a space between the option char and the argument.
This in turn means that for options expecting a file name shell expansion won't occur which means using e.g. ~ will not correctly translate in the file name.
.RE
.SH EXAMPLES
.PP
Print out the actual Enigma settings of the config file in a human form:
.nf
.RS
\fB
echo | ./recode -Rconfig -v\fP
.fi
.RE
.PP
Does something special (what?):
.nf
.RS
\fB
echo | ./recode
echo | ./recode -v\fP
.fi
.RE
.PP
Please see the \fIrecode.markdown\fP and \fIhint.markdown\fP files for more examples and other information.
.SH AUTHOR
Written by Cody Boone Ferguson for IOCCC 2020 (the 27th IOCCC).
.SH SEE ALSO
.PP
\fBenigma(1)\fP
.PP
\fB\<https://ioccc.xexyl.net/2020/enigma\>\fP The 27th IOCCC 'Most enigmatic'.
.PP
\fB\<http://users.telenet.be/d.rijmenants/en/enigmaproc.htm\>\fP Enigma Message Procedures for the Heer (Army), Luftwaffe (Air Force) and Kriegsmarine (Navy).
.PP
\fB\<http://enigmaco.de/enigma/enigma.html\>\fP Online interactive Enigma simulator.
.PP
\fB\<http://www.codesandciphers.co.uk/enigma/index.htm\>\fP Tony Sale's (original curator of the Bletchley Park Museum) pages on The Enigma cipher machine.
.PP
\fB\<http://users.telenet.be/d.rijmenants/en/enigmatech.htm\>\fP Technical Details of the Enigma Machine.
.PP
\fB\<http://users.telenet.be/d.rijmenants/en/enigma.htm\>\fP The German Enigma Cipher Machine.
.PP
\fB\<http://www.ellsbury.com/enigma3.htm\>\fP How the Enigma was Set Up and Operated.
+67
View File
@@ -0,0 +1,67 @@
%: include <string.h>
%: include <stdio.h>
%: include <ctype.h>
%: include <stdlib.h>
%: include <time.h>
%: include <unistd.h>
%: define W (char<: :> <: 4 :>){ " I"," II","III"," IV", " V"}
%:define E(x) do (*x) = getchar(); while ((*x)!='\n')
#define q Q"Invalid input. ")
#define Z(x) (x)=A<:F(0,25):>
%:define Q fprintf(stderr,
%:define U (char<::>){"BC"}
#define L(V) (V)=toupper((V))
%:define n isalpha
/\
/ This is *not* what you think:
void D(char*x){ for(char*p=x; *p; ++p)*p=islower(*p) ?"nopqrstuvwxyzabcdefghijklm"<:(*p-97+26)%26:>:*p; }
char *M,*Y<:3:>,R<:3:>,A<::>="ABCDEFGHIJKLMNOPQRSTU" "VWXYZ",N<::><:27:> = { "EKMFLGDQVZNTOWYHXUSPAIBRCJ"
,"AJDKSIRUXBLHWTMCQGZNPYFVOE","BDFHJLCPRTXVZNYEIWGA" "KMUSQO","ESOVPZJAYQUIRHXLNFTGKDCMWB","VZBRGITYUPSD"
"NHLXAWMJQOFECK"} ,o<::><:27:>={ "YRUHQSLDPXNGOKMIE" "BFZCWVJAT","FVPJIAOYEDRZXWGCTKUQSBNMHL"} ,P<::>="A"
"BC", T<::>="BBC",C<:2:><:11:>, g<:27:>,X<::><:21:>= { "Rbgbef", "Iachg ebgbe", "Iachg frggvat", "Iachg "
"cbfvgvba","Rrsyrpgbe", "Iachg ersyrpgbe","Iachg cy" "htobneq cnve","Rvat","frggvatf","cbfvgvba"} ; int K
<::>={ 0,1,2} ,y, H, v, c; size_t l; int F(int i,int j) { return(rand()%(j-i+1))+i; } void d(void){ int i
,j,k; srand((unsigned)time(0)); strcpy(g,A); K<:0:>= F(0,4); while((K<:1:>=F(0,4))==K<:0:>) ; while((K<:2
:>=F(0,4))==K<:0:>||K<:2:>==K<:1:>) ; y=F(0,1); for( i=0; i<3; ++i){ Z(P<:i:>); Z(T<:i:>); } k=0; while (
k<10){ do i=F(0,25); while (g<:i:> == ' '); do j=F(0 ,25); while(j==i||g<:j:>==' '); C<:0:><:k:>=g<: i:>;
C<: 1 :> <: k ++:> = g<: j:>; g<:i:>=' '; g<:j:>=' ' ; } H=1; } int p(char x){ return strchr(C<:0:>,x) ||
strchr(C<:1:>,x); } char B<:3:>; void G(void){ * B ='\0'; scanf("%2s", B); } void m(void) { int i, j=0,h;
char k; Q"%s:\n",*X); for(i=0; i<5; ++i)Q"(%d) %s: ""%s\n", i+1,W<:i:>,N<:i:>); for(i=0; i< 3; ) { x : Q
"%s %d (1 - 5): ", X <:1:>,i+1); G(); j=strtol(B,0,0); if (j<1||j>5) { q; E(&j); continue
; } j =(j < 1 ?1:(j> 5?5:j))-1; h=i-1; for(; h>= 0; --h) { if(K<:h:>== j){ Q"Already use"
"d. "); E(&j); goto x; } } K<:i++:>=j; E(& j); } for(i=0; i<3; ++i) { i:Q"%s %d (A - Z)"
": ", 2<:X:>,i+1); G(); if(!n(k=*B)){ q; E(&*B); goto i; } P<:i:> = toupper(k); E(&*B); } for (i = 0; i<3
; ++i){ j:Q"%s %d (A - Z): ",X<:3:>,i+1); G(); if(!n(k=*B)){ q; E(&*B); goto j; } T<:i:>= toupper(k); E(&
*B); } Q"%s:\n",X <: 4 :>); for(i = 0; i < 2 ; ++i)Q"(%d) (%c) %s\n", i + 1, U<:i:>, o<:i:> ) ; k:y =0; Q
"%s (1 - 2): ", 5<:X:>); G(); y=strtol(B,0,0); if (y < 1 || y > 2) { q; E( & y); goto k ; } y=(y<1?1:(y >
1 ?2:y))-1; strcpy(g,A); for (i=0; i<10; ++i) { char a,b; v:a = b = '.'; Q"%s %d: ",6<:X:>,i+1); G(); a=B
<:0:>; b=B<:1:>; L(a); L(b); if((n(a)&&!n(b))||(!n(a)&&n(b))||(n(a) && (a== b || (p(a)||p(b)))))<%if((p(a
)||(b))&&(n(a)&&n(b))) Q"Already used. "); else q; E(&a); goto v; } a=n(a)?a:'.'; b=n(b)?b:'.'; C<:0:><:i
:>=a; C<:1:><:i:>=b; if(n(a)){g<:a-'A':>=' ';g<:b-'A':>=' '; }E(&a); } }void e(void) { int i; for(i=0;i<3
; ++i)Q"%s %d: (%s) %s\n", 7 <:X:>,i+1,W<:K<:i:>:>,N<:K<:i:>:>); Q"%s %s: %s\n",7<:X:>,X<:8:>, P); Q"%s"
" %ss"": %s\n", X<:7:>,*(X+9),T) ; Q "%s: (%c) %s\n",4<:X:>,U<:y:>,o<:y:>) ; for(i=0,L(6<:X:><:6:>); i<10
; ++i)Q"%c%s #%02d: %c%c\n", X<:6:><:6:>,7+6<:X:>, i+1, C<:0:><:i:>, C<:1:><:i:>); } int O(const char*p){
int i,j=0; char*x=0; FILE *f = fopen(p, "r"); if(f){ if(getdelim(&x,&l,EOF,f)>0){ p = x; j = 1; } fclose(
f); } l = 0; if(strlen(p) > 29) { for(i = 0; i < 3; ++i){ K<:i:>=(*p++)-'0'; K<:i:> = (K<:i:> < 1 ? 1 : (
K<:i:>> 5 ? 5 : K<:i :>))-1; P<:i:> = *p++; T<:i:> = *p++ ; } y = ( * p ++)-'0'; y=(y<1?1:
(y>1?2:y))-1; for(i= 0; i<10; ++i){ C<:0:><:i:>=*p++; C<:1:><:i:>=*p++; } if (j) free(x) ;
return 1 ; } if (j) free(x); return 0; } void x(FILE*f,int k) { int i; for (i=0; i <3; ++
i){ fprintf(f,"%d",K<:i:>+1); fprintf(f,"%c",P<:i :>);fprintf(f,"%c", T<:i:>); } fprintf(f, "%d", y + 1);
for (i= 0; i<10; ++i)fprintf(f,"%c%c",C<:0:><:i:>,C <:1:><:i:>); if(f==stdout&&k)fprintf(f,"%s",M); } int
t(const char*a,const char *b) { int i, j; for (i = 0 ; *(a+i) || *(b+ i); ++i) if ((j = tolower(a<:i:>) -
tolower(b<:i:>))){ if (j < 0) return -1; return 1; } return 0; } int main(int V, char **I){ FILE*w=stdin,
*z=NULL; const char*p, *J="", *k= ""; int i; ssize_t s; for(i = 0; i < 10; ++i) D(i<:X:>); for(V = 1; I<:
V:>; ++V) { if (*(p = I<: V :>) =='-') { switch (*++ p){ case'h':Q"usage: %s [options]\n-v\t\t\tdisplay "
"selected settings\n-r\t\t\tpseudo-randomly select " "settings\n-f<input file>\t\tread file for Enigma i"
"nput\n-R<string|file>\t\tinit settings from settin" "gs string or file\n-o<output file>\t\twrite settin"
"gs to file\n", * I); return 0; case 'v':c=1; break; case'r':if(!H){ v=1; d(); } break; case'R':H= O(++p)
; break; case'f':J=++ p; break; case'o':k=++p; break ; default:break; } } } if(*J){ w = fopen(J, "r"); if
(! w) { Q"couldn't open input file, using stdin\n"); w=stdin; } } if (*J && *k && !t(J,k)){ Q"same input"
"/output filenames, won't open for writing\n") ; k = ""; } if (*k) { z=fopen(k, "w"); if (!z) Q"couldn't"
" open output file, only using stdout\n"); } if (!v && !H && isatty(0)) m(); if (c) e(); s = getdelim(&M
,&l,EOF,w); if(w!=stdin)fclose(w); if (z){ x(z,s>0); fclose(z); } x(stdout,s>0); free(M); return 0; }
+609
View File
@@ -0,0 +1,609 @@
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional //EN">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.2.2">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"> <link rel="stylesheet"
type="text/css"
href="../hint.css" />
<title></title>
</head>
<body>
<CENTER>
<IMG SRC="/png/ioccc.png" ALT="IOCCC" height=78 width=267>
<P><FONT size="6"><I>The International Obfuscated C Code Contest</I></FONT></P>
<div id="bar">
<ul>
<li><a href="../index.html">About the 27th IOCCC</a></li>
<li><a href="../whowon.html">27th IOCCC Winners</a></li>
<li><a href="/index.html">IOCCC home</a></li>
<li><a href="/winners.html">List of All Winners</a></li>
<li><a href="/judges.html">The Judges</a></li>
</ul>
</div>
<P><FONT size="6"><B>Supplemental Info</B></FONT></P>
</CENTER>
<h1>The recode configurator documentation (and a fun way to explore my 2020 IOCCC Enigma simulator)</h1>
<p>N.B. At the end of this file I have given a fun exercise that can be used to
explore my Enigma simulator. It&rsquo;s especially worth doing if you you like
good chocolate and could use a delicious <a href="chocolate-cake.html">Double-layered Chocolate Fudge Cake</a>.</p>
<p>Alternatively if you just want the recipe you could look at my Snake entry
&lsquo;Don&rsquo;t tread on me award&rsquo; since it&rsquo;s also there and not enciphered.</p>
<p><a name="toc"></a>
- <a href="#recode">What is recode and why is it recommended?</a>
- <a href="#options">Options</a>
* <a href="#samefile">Protecting against the same I/O file</a>
* <a href="#fileoptions">File options parser limitation</a>
* <a href="#validation">-R option validation?</a>
- <a href="#pipingtorecode">Piping commands to recode</a>
- <a href="#pipingtoenigma">Piping recode to the Enigma simulator</a>
- <a href="#manuallytest">Manually test the recode program with the Enigma program</a>
- <a href="#onlyconfig">Only write config file</a>
- <a href="#reuseconfig">Reusing a configuration</a>
- <a href="#passtoenigma">Write config file, read data file and pass to Enigma simulator</a>
- <a href="#directlytoenigma">Piping directly to the Enigma code once (with randomised settings, saved)</a>
- <a href="#conclusion">Usage conclusion</a>
- <a href="#additions">Example additions</a>
- <a href="#exampleuses">Example uses</a>
- <a href="#cake">Delicious Enigma: Double-layered Chocolate Fudge Cake</a></p>
<h1><a name="recode" href="#toc">What is recode and why is it recommended?</a></h1>
<p>To demonstrate how to and why you should use the recode program with the Enigma
simulator I have included some examples here as well as brief (&lsquo;brief?!&rsquo; I am sure
many would think but it&rsquo;s brief for me) commentary.</p>
<p>It would not be possible to do all that the recode program does in my entry
itself but I wanted to demonstrate the features of my entry and this seemed the
best way to do that. It also enhances the use of the simulator to make it
reusable etc.</p>
<p>The recode name idea is that it recodes the input (validating first) to be input
for the simulator itself. It can pseudo-randomly select all the settings, it can
write the settings to a file, read from input file (e.g. for the text to
encipher if piped to the simulator) etc.</p>
<p>Basically it&rsquo;s a configurator for the Enigma simulator that makes it easier to
use the simulator as well as to reuse the configuration to decipher messages
that have been enciphered by those settings. But it also tries to make it look
more like the real thing in that it shows the actual rotors (labelling them with
the Roman numeral), the reflectors (labelling them with B, C and showing the
actual strings) etc.</p>
<p>In this file I will show an example of each feature and then get to the
wonderful &lsquo;challenge&rsquo; for everyone.</p>
<h1><a name="options" href="#toc">Options</a></h1>
<pre><code> usage: ./recode [options]
-v display selected settings
-r pseudo-randomly select settings
-f&lt;input file&gt; read file for Enigma input
-R&lt;string|file&gt; init settings from settings string or file
-o&lt;output file&gt; write settings to file
</code></pre>
<p><code>-r</code> randomises settings. It won&rsquo;t prompt you for settings but it will for input
if you don&rsquo;t give the option to read in a file for input.</p>
<p><code>-v</code> shows selected settings. For example combining <code>-r</code> and <code>-v</code>:</p>
<pre><code> $ echo IOCCC | ./recode -r -v
Ring 1: ( I) EKMFLGDQVZNTOWYHXUSPAIBRCJ
Ring 2: ( V) VZBRGITYUPSDNHLXAWMJQOFECK
Ring 3: ( IV) ESOVPZJAYQUIRHXLNFTGKDCMWB
Ring settings: WAR
Ring positions: XKE
Reflector: (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
Plugboard pair #01: XE
Plugboard pair #02: HJ
Plugboard pair #03: SA
Plugboard pair #04: PY
Plugboard pair #05: CI
Plugboard pair #06: ZB
Plugboard pair #07: WD
Plugboard pair #08: QN
Plugboard pair #09: RU
Plugboard pair #10: VG
1WX5AK4RE1XEHJSAPYCIZBWDQNRUVGIOCCC
</code></pre>
<p>Though you won&rsquo;t find such strings in recode.c or prog.c. (You will find the
Roman numerals for the rotors and the &lsquo;A&rsquo; and &lsquo;B&rsquo; for the reflectors in recode.c
though). Yes the &lsquo;WAR&rsquo; for the Ringstellung (Ring settings) is an amusing
coincidence <em>but it really did happen!</em></p>
<p>As for <code>-f</code> the contents would be output with the settings e.g. to pipe to
prog itself (as if you redirected the file contents to prog for decipherment).
If the file cannot be opened it sets back to stdin.</p>
<p><code>-o</code> outputs the settings to the file. If the file cannot be opened for writing
or is the same file name (see below) then only stdout will be used. Example of
randomised output going to a file:</p>
<pre><code> $ ./recode -r -oconfig
IOCCC
3PP4UB5GG1ELGTKFCOPVBNUYXJAWSDIOCCC
$ cat config
3PP4UB5GG1ELGTKFCOPVBNUYXJAWSD$
</code></pre>
<p>Notice that a terminating newline isn&rsquo;t added. Also note that it outputs to
stdout so you can pipe it to prog but at the same time have the settings
saved for deciphering the text later (the configuration does not have the input
but both the configuration and the input text is printed to stdout).</p>
<p>If you want to initialise the settings from previously saved settings (as a
string or an input file that has the same format) use the <code>-R&lt;settings&gt;</code> option.
Again note that this does not validate input! Although it detects out of range
for the arrays it doesn&rsquo;t detect duplicates. This is because it wasn&rsquo;t meant to
be any given file nor anything but the direct output of a previous run (thus
validated). I&rsquo;m not even guaranteeing that I got the array tests valid in
recode.c -R option!</p>
<h2><a name="samefile" href="#toc">Protecting against the same I/O file</a></h2>
<p>Because some file systems are case-insensitive I have implemented a
case-insensitive strcmp(); if the input file name is the same as the output file
name I won&rsquo;t write to it. From a quick test this is important particularly if
neither file exist because if both calls to stat() fail then the inodes will be
the same (since what else could they be set to but the same initial value?).
This might be overprotective but I believe it better to prevent user error where
possible. Of course if neither file exists it might be argued that it&rsquo;s not
necessary to worry since you can&rsquo;t read from a file that doesn&rsquo;t exist. But then
what about if one exists but the other does not?</p>
<h2><a name="fileoptions" href="#toc">File options parser limitation</a></h2>
<p>Due to the way the parsing of options is done (no spaces between option char and
argument) shell expansion will not work right so for example doing:</p>
<pre><code>$ ./recode -R~/config
</code></pre>
<p>Will not read the file &lsquo;config&rsquo; in the home directory. I show another way to
achieve this later.</p>
<p>This limitation also applies to the <code>-f</code> and <code>-o</code> options!</p>
<h2><a name="validation" href="#toc">-R option validation?</a></h2>
<p>Again the <code>-R</code> option does not validate input. For validation you have to run
the program interactively.</p>
<h1><a name="pipingtorecode" href="#toc">Piping commands to recode</a></h1>
<p>If stdin is not a tty (<code>!isatty(0)</code>) and neither randomised mode nor reading in
from a file is specified then you might just see something like:</p>
<pre><code> $ echo testing test tests | ./recode
1AB2BB3CC1testing test tests
$ echo testing test tests | ./recode | ./prog - 2&gt;/dev/null
mfrwxan lzng ofnlu
$ echo testing test tests | ./recode | ./prog - 2&gt;/dev/null | ./recode
1AB2BB3CC1mfrwxan lzng ofnlu
$ echo testing test tests | ./recode | ./prog - 2&gt;/dev/null | ./recode | ./prog - 2&gt;/dev/null
testing test tests
</code></pre>
<p>In other words just the defaults. This was to simplify the problems with
prompting again for input if it&rsquo;s invalid (though as you&rsquo;ll see it does a good
job at this anyway).</p>
<h1><a name="pipingtoenigma" href="#toc">Piping recode to the Enigma simulator</a></h1>
<p>If you&rsquo;re using recode to recode the input so you don&rsquo;t have to type in the
input manually (if you randomise or read in from previously saved file no input
need be done at all) then make sure to redirect stderr to /dev/null. If you
don&rsquo;t you might see something like:</p>
<pre><code> $ ./recode -r | ./prog -
Ring 1: IOCCC
Setting 1: Position 1: Ring 2: Setting 2: Position 2: Ring 3: Setting 3: Position 3: Reflector: Plugboard pair 1: Plugboard pair 2: Plugboard pair 3: Plugboard pair 4: Plugboard pair 5: Plugboard pair 6: Plugboard pair 7: Plugboard pair 8: Plugboard pair 9: Plugboard pair 10: DEVIY
</code></pre>
<p>What happened is that <code>Ring 1:</code> is printed to stderr but since it&rsquo;s not been
redirected to /dev/null it prints this out; at this point however it prompts for
input. Why or how it shows the first prompt instead of later on I do not know.
Anyway at this point the simulator is already expecting input to en/decipher.
That&rsquo;s why after I sent EOF it printed out the remaining strings to stderr.</p>
<h1><a name="manuallytest" href="#toc">Manually test the recode program with the Enigma program</a></h1>
<pre><code> $ cat input
IOCCC
$ ./recode -finput
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 1
Input rotor 2 (1 - 5): 2
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): A
Input setting 2 (A - Z): A
Input setting 3 (A - Z): A
Input position 1 (A - Z): A
Input position 2 (A - Z): A
Input position 3 (A - Z): A
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: AB
Input plugboard pair 2: CD
Input plugboard pair 3: ..
Input plugboard pair 4: EF
Input plugboard pair 5: GH
Input plugboard pair 6: IJ
Input plugboard pair 7: KL
Input plugboard pair 8: MN
Input plugboard pair 9: OP
Input plugboard pair 10: QR
1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC
</code></pre>
<p>Notice that I skipped a plugboard pair; this can be done in a number of ways but
two dots is one. Notice also that it&rsquo;s in a different order than the simulator:
because with the size restrictions on my entry I saved bytes by using the same
loop where I could. It just felt more natural to have them grouped together in a
configurator for the simulator.</p>
<pre><code> $ echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC | ./prog - 2&gt;/dev/null
HQNVO
$ echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC | ./prog - 2&gt;/dev/null | echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRHQNVO | ./prog - 2&gt;/dev/null
IOCCC
</code></pre>
<p>As you can see the recode program prompts for the settings and outputs the
input for the Enigma program. I then copied/pasted that output to the program
and got the result HQNVO.</p>
<p>Following this I piped the original output (of recode) to the simulator and then
piped that to the echo of the input settings (replacing the IOCCC with the
Enigma enciphered output) and then got the result IOCCC: the original input!
(This was before I implemented the <code>-R</code> option to greatly simplify things.)</p>
<p>Of course the last command was redundant in that I didn&rsquo;t need to show the first
part again; I could have just done the latter part but I wanted to show the way
the pipeline works with settings etc.</p>
<p>What happens if the plugboard pairs are the same but in a different order? It&rsquo;s
the same output:</p>
<pre><code> $ echo 1AA2AA3AA2AB..CDEFGHIJKLMNOPQRIOCCC|./prog - 2&gt;/dev/null
HQNVO
</code></pre>
<p>Also if you flip the order of the letters in the pair e.g. the AB as BA instead:</p>
<pre><code> $ echo 1AA2AA3AA2BA..CDEFGHIJKLMNOPQRIOCCC|./prog - 2&gt;/dev/null
HQNVO
</code></pre>
<h1><a name="onlyconfig" href="#toc">Only write config file</a></h1>
<pre><code> $ ./recode -v -oconfig -finput &gt;/dev/null
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 1
Input rotor 2 (1 - 5): 2
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): A
Input setting 2 (A - Z): C
Input setting 3 (A - Z): E
Input position 1 (A - Z): B
Input position 2 (A - Z): D
Input position 3 (A - Z): F
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: AB
Input plugboard pair 2: CD
Input plugboard pair 3: EF
Input plugboard pair 4: GHIJ
Input plugboard pair 5: IJ
Input plugboard pair 6: KL
Input plugboard pair 7: MN
Input plugboard pair 8: OP
Input plugboard pair 9: QR
Input plugboard pair 10: ST
Ring 1: ( I) EKMFLGDQVZNTOWYHXUSPAIBRCJ
Ring 2: ( II) AJDKSIRUXBLHWTMCQGZNPYFVOE
Ring 3: (III) BDFHJLCPRTXVZNYEIWGAKMUSQO
Ring settings: ACE
Ring positions: BDF
Reflector: (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Plugboard pair #01: AB
Plugboard pair #02: CD
Plugboard pair #03: EF
Plugboard pair #04: GH
Plugboard pair #05: IJ
Plugboard pair #06: KL
Plugboard pair #07: MN
Plugboard pair #08: OP
Plugboard pair #09: QR
Plugboard pair #10: ST
</code></pre>
<p>Notice that I redirect stdout to /dev/null so that the config is only written to
the file config. But also notice that for plugboard pair 4 I typed in <code>GHIJ</code> and
it didn&rsquo;t report an error. Neither did it complain about <code>IJ</code> in the next pair.
This is because it consumes input overflow.</p>
<p>It shouldn&rsquo;t be this way for the simulator though because that could cause
inconsistent number of characters expected before the text to encipher.</p>
<pre><code> $ cat config
1AB2CD3EF2ABCDEFGHIJKLMNOPQRST
$ ( cat config ; cat input ) | ./prog - 2&gt;/dev/null
LRAVE
$ ( cat config ; cat input ) | ./prog - 2&gt;/dev/null | ( cat config ; echo LRAVE ) | ./prog - 2&gt;/dev/null
IOCCC
</code></pre>
<p>What if you don&rsquo;t want to worry about having to specify input but just have the
settings written? You can do that too by either sending a newline or else
directly type ctrl-d (or whatever you have EOF set to) or give it an empty file.</p>
<p>The following are all equivalent in that they will write to a settings file (the
first one will print a newline with the echo but that won&rsquo;t matter):</p>
<pre><code> $ echo | ./recode -r -osettings
$ echo -n | ./recode -r -osettings
$ &gt; empty
$ ./recode -r -osettings &lt; empty
$ cat empty | ./recode -r -osettings
$ ./recode -r -osettings
^D
</code></pre>
<p>(Above ^D was not shown but I typed it.) The way it works: if nothing is read
the buffer remains NULL and so I don&rsquo;t print it but still do print the settings
file. Actually even if getdelim() fails you&rsquo;re supposed to free the buffer so I
set another variable to indicate if it should be printed.</p>
<h1><a name="reuseconfig" href="#toc">Reusing a configuration</a></h1>
<pre><code> $ echo -n|./recode -r -oconfig
4UH5II1RJ1SPIFEJLYGZWRTBHVCAMN$
$ cat input.txt
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
$ ( cat config ; cat input.txt ) | ./prog - 2&gt;/dev/null &gt; output
$ cat output
AAPRT 2020 Dkemny tpgnjsjai xpovrgl jvgs wxra
Fytt ly m xyiilaqh.
Ybbp ox dmuzerm oscwgytb.
$ ( cat config ; cat output ) | ./prog - 2&gt;/dev/null &gt; io
$ diff io input.txt
$
</code></pre>
<p>Alternatively you can just use the <code>-R</code> and <code>-f</code> options:</p>
<pre><code> $ ./recode -finput.txt -Rconfig | ./prog - 2&gt;/dev/null &gt; output2
$ diff output output2
$
</code></pre>
<h1><a name="passtoenigma" href="#toc">Write config file, read data file and pass to Enigma simulator</a></h1>
<pre><code> $ ./recode -finput.txt -oconfig | ./prog - 2&gt;/dev/null &gt; output
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 2
Input rotor 2 (1 - 5): 5
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): C
Input setting 2 (A - Z): O
Input setting 3 (A - Z): D
Input position 1 (A - Z): E
Input position 2 (A - Z): L
Input position 3 (A - Z): O
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: TR
Input plugboard pair 2: SN
Input plugboard pair 3: OG
Input plugboard pair 4: ME
Input plugboard pair 5: XY
Input plugboard pair 6: WZ
Input plugboard pair 7: UV
Input plugboard pair 8: AB
Input plugboard pair 9: CD
Input plugboard pair 10: FI
$ cat config
2CE5OL3DO2TRSNOGMEXYWZUVABCDFI
</code></pre>
<p>Besides a famous book that I happen to love (who doesn&rsquo;t? Ah, but what is it
Cody?) there&rsquo;s also a reference to code which I also love (just as all
participants of the IOCCC do). But what matters is the output:</p>
<pre><code> $ cat output
DBFAF 2020 Ittejg ltblwriac uqdfqvr dhqh ghhf
Jsjy ce v pxdmullo.
Sara tj rtaayak uxfhjcti.
$ ./recode -Rconfig -foutput | ./prog - 2&gt;/dev/null
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
</code></pre>
<h1><a name="directlytoenigma" href="#toc">Piping directly to the Enigma code once (with randomised settings, saved)</a></h1>
<p>This is like the above only randomised:</p>
<pre><code> $ ./recode -r -oconfig|./prog - 2&gt;/dev/null
IOCCC
UGEVP
</code></pre>
<p>Note that I typed in IOCCC and sent EOF (ctrl-d); the settings were written to
the config file (for deciphering later) and then all of it was piped to the
Enigma entry resulting in the line below IOCCC. But let&rsquo;s verify it worked out
okay:</p>
<pre><code> $ cat config
2BM4GJ3HK1LNCBXWRMGKSYIAZUTPVJ
</code></pre>
<p>Without having to copy/paste intermediate results:</p>
<pre><code> $ echo IOCCC | ./recode -Rconfig | ./prog - 2&gt;/dev/null | ./recode -Rconfig | ./prog - 2&gt;/dev/null
IOCCC
</code></pre>
<p>You can also use a string for the <code>-R</code> option. I&rsquo;ll use command substitution and
actual pasting to demonstrate:</p>
<pre><code> $ echo IOCCC | ./recode -R$(cat config) | ./prog - 2&gt;/dev/null | ./recode -R2BM4GJ3HK1LNCBXWRMGKSYIAZUTPVJ | ./prog - 2&gt;/dev/null
IOCCC
</code></pre>
<h1><a name="conclusion" href="#toc">Usage conclusion</a></h1>
<p>That should give you an idea of how to use the recode program. I leave it as
an exercise to the reader to implement additional features but here are some
ideas of what could be done and how this entry might be used (including that
delicious challenge).</p>
<h1><a name="additions" href="#toc">Example additions</a></h1>
<ul>
<li>Add code (to prog.c) that tries to determine possible decipherments based on
a given crib (or set of cribs).</li>
</ul>
<h1><a name="exampleuses" href="#toc">Example uses</a></h1>
<ul>
<li><p>Take an actual key sheet and message for that day and try and decipher the
message (might help if you know German!). I haven&rsquo;t actually done this for
reasons I explained in the remarks (including that I cannot easily verify one
particular as well as the fact that there were different procedures, different
machines etc. - plus my vision is not good enough for the quality of the
pictures).</p></li>
<li><p>Try making sense of a politician&rsquo;s speeches by putting them into the
simulator. It might not make much sense but can it honestly be that much worse ?
:) Actually yes it could be (and we don&rsquo;t need the Enigma helping them either)
and I can think of a whole host of other things more entertaining including
watching dry paint stay dry on a wall but why not poke fun at politicians
anyway?</p></li>
<li><p>Best idea: try the below experiment!</p></li>
</ul>
<h1><a name="cake" href="#toc">Delicious Enigma: Double-layered Chocolate Fudge Cake</a></h1>
<p>As I was making the above silly list something occurred to me. My other entries
this year include a recipe for a wonderful double-layered chocolate fudge cake
but why would it not be included in this one too? But then if that&rsquo;s the case
why on Earth should it be unscrambled?</p>
<p>So this is what I offer: if you take one of the settings below and run the
simulator on the file <a href="chocolate-cake.html">chocolate-cake.html</a> you will have a wonderful
chocolate cake recipe (that even my late stepmum who didn&rsquo;t even like chocolate
loved - it&rsquo;s a speciality of my mum&rsquo;s and they were the best of friends too). If
you&rsquo;re lazy just go and look at my other entry. Then again if you&rsquo;re lazy you&rsquo;re
probably not reading this far! :)</p>
<p>The settings is one of the below but a couple questions you might ask yourself:</p>
<ol>
<li><p>Are any invalid input?</p></li>
<li><p>Is there some other kind of trickery involved here?</p></li>
</ol>
<p>I can think of the best way to answer these and I think I need not even mention
it. Have fun and enjoy! BTW: Depending on where you are in this world and how
warm it is the icing can be a bit of an issue - I give some ideas in the file on
what can be done for this. At worst though the icing won&rsquo;t come out as good as
it usually does.</p>
<p>Hints:</p>
<ol>
<li><p>It&rsquo;s not the middle one.</p></li>
<li><p>Yes there are some things kind of spelt here. These include things about
cake and chocolate. Some things spelt mean nothing whatever and can be
considered coincidences. Some were randomised.</p></li>
<li><p>There is an obscure thing about my entry that can help locate the proper key
of the 16 given below! The questions are what is it and is is it worth going
this way? (I think the second answer is &lsquo;no&rsquo; but that&rsquo;s me.)</p></li>
<li><p>The above points might or might not be relevant. What is relevant is one
will reveal a wonderful <a href="chocolate-cake.html">Double-layered Chocolate Fudge Cake</a> recipe:</p>
<pre><code> 142CHOCOLATESVCAKESTBJLKMUMVWX
0EZ4PC1CC0PGTAQSOXWNMDRYKFUZEI
3UY0XF4QG1GTJQLARPKHBEMCOFVUIN
0WE1HK4PL0RVSGXFDKENZYTPCMAHUW
2LV0KC1IE0HTFPCLWOJDBQIRVMEAGN
1SS4QX2RY1SRAQGKUYHCBLPFJDVTNZ
3IW1QR0TZ0GQEDWIYJUPMFZBRAONHS
3OP1KN4MO0HPFZCEAKYQIRXGVMOTUW
4OC2CC0AK1CODELUVRSNGKIZBJPTMY
4MU0MS1CA1KELUVRSXTABJNOCDMQFG
0MU4MC2HO1CLATEFBJMONPQRVWXYZD
125CHOCOLATESEXCAKESJADFNOPQRS
0CH3OC1OL1ATEMBJNOCDLSIFWHRVXY
4MU1MS3CA0KECHOLATBJSNPXVUFGZY
4VW0SL1YB0IYJSLBECKTNAXGPUVHRF
0MC4OH2CO1LATEUMBJCDFGHINOPRQS
</code></pre></li>
</ol>
<p>BTW: What&rsquo;s the middle of a list with even numbered items anyway?</p>
<BR>
<HR>
<TABLE><TR>
<TD><a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="/png/by-sa-3.0-88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2020,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="https://validator.w3.org/check?uri=referer"><img src="https://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+564
View File
@@ -0,0 +1,564 @@
# The recode configurator documentation (and a fun way to explore my 2020 IOCCC Enigma simulator)
N.B. At the end of this file I have given a fun exercise that can be used to
explore my Enigma simulator. It's especially worth doing if you you like
good chocolate and could use a delicious [Double-layered Chocolate Fudge Cake][].
Alternatively if you just want the recipe you could look at my Snake entry
'Don't tread on me award' since it's also there and not enciphered.
<a name="toc"></a>
- [What is recode and why is it recommended?](#recode)
- [Options](#options)
* [Protecting against the same I/O file](#samefile)
* [File options parser limitation](#fileoptions)
* [-R option validation?](#validation)
- [Piping commands to recode](#pipingtorecode)
- [Piping recode to the Enigma simulator](#pipingtoenigma)
- [Manually test the recode program with the Enigma program](#manuallytest)
- [Only write config file](#onlyconfig)
- [Reusing a configuration](#reuseconfig)
- [Write config file, read data file and pass to Enigma simulator](#passtoenigma)
- [Piping directly to the Enigma code once (with randomised settings, saved)](#directlytoenigma)
- [Usage conclusion](#conclusion)
- [Example additions](#additions)
- [Example uses](#exampleuses)
- [Delicious Enigma: Double-layered Chocolate Fudge Cake](#cake)
# <a name="recode" href="#toc">What is recode and why is it recommended?</a>
To demonstrate how to and why you should use the recode program with the Enigma
simulator I have included some examples here as well as brief ('brief?!' I am sure
many would think but it's brief for me) commentary.
It would not be possible to do all that the recode program does in my entry
itself but I wanted to demonstrate the features of my entry and this seemed the
best way to do that. It also enhances the use of the simulator to make it
reusable etc.
The recode name idea is that it recodes the input (validating first) to be input
for the simulator itself. It can pseudo-randomly select all the settings, it can
write the settings to a file, read from input file (e.g. for the text to
encipher if piped to the simulator) etc.
Basically it's a configurator for the Enigma simulator that makes it easier to
use the simulator as well as to reuse the configuration to decipher messages
that have been enciphered by those settings. But it also tries to make it look
more like the real thing in that it shows the actual rotors (labelling them with
the Roman numeral), the reflectors (labelling them with B, C and showing the
actual strings) etc.
In this file I will show an example of each feature and then get to the
wonderful 'challenge' for everyone.
# <a name="options" href="#toc">Options</a>
usage: ./recode [options]
-v display selected settings
-r pseudo-randomly select settings
-f<input file> read file for Enigma input
-R<string|file> init settings from settings string or file
-o<output file> write settings to file
`-r` randomises settings. It won't prompt you for settings but it will for input
if you don't give the option to read in a file for input.
`-v` shows selected settings. For example combining `-r` and `-v`:
$ echo IOCCC | ./recode -r -v
Ring 1: ( I) EKMFLGDQVZNTOWYHXUSPAIBRCJ
Ring 2: ( V) VZBRGITYUPSDNHLXAWMJQOFECK
Ring 3: ( IV) ESOVPZJAYQUIRHXLNFTGKDCMWB
Ring settings: WAR
Ring positions: XKE
Reflector: (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
Plugboard pair #01: XE
Plugboard pair #02: HJ
Plugboard pair #03: SA
Plugboard pair #04: PY
Plugboard pair #05: CI
Plugboard pair #06: ZB
Plugboard pair #07: WD
Plugboard pair #08: QN
Plugboard pair #09: RU
Plugboard pair #10: VG
1WX5AK4RE1XEHJSAPYCIZBWDQNRUVGIOCCC
Though you won't find such strings in recode.c or prog.c. (You will find the
Roman numerals for the rotors and the 'A' and 'B' for the reflectors in recode.c
though). Yes the 'WAR' for the Ringstellung (Ring settings) is an amusing
coincidence *but it really did happen!*
As for `-f` the contents would be output with the settings e.g. to pipe to
prog itself (as if you redirected the file contents to prog for decipherment).
If the file cannot be opened it sets back to stdin.
`-o` outputs the settings to the file. If the file cannot be opened for writing
or is the same file name (see below) then only stdout will be used. Example of
randomised output going to a file:
$ ./recode -r -oconfig
IOCCC
3PP4UB5GG1ELGTKFCOPVBNUYXJAWSDIOCCC
$ cat config
3PP4UB5GG1ELGTKFCOPVBNUYXJAWSD$
Notice that a terminating newline isn't added. Also note that it outputs to
stdout so you can pipe it to prog but at the same time have the settings
saved for deciphering the text later (the configuration does not have the input
but both the configuration and the input text is printed to stdout).
If you want to initialise the settings from previously saved settings (as a
string or an input file that has the same format) use the `-R<settings>` option.
Again note that this does not validate input! Although it detects out of range
for the arrays it doesn't detect duplicates. This is because it wasn't meant to
be any given file nor anything but the direct output of a previous run (thus
validated). I'm not even guaranteeing that I got the array tests valid in
recode.c -R option!
## <a name="samefile" href="#toc">Protecting against the same I/O file</a>
Because some file systems are case-insensitive I have implemented a
case-insensitive strcmp(); if the input file name is the same as the output file
name I won't write to it. From a quick test this is important particularly if
neither file exist because if both calls to stat() fail then the inodes will be
the same (since what else could they be set to but the same initial value?).
This might be overprotective but I believe it better to prevent user error where
possible. Of course if neither file exists it might be argued that it's not
necessary to worry since you can't read from a file that doesn't exist. But then
what about if one exists but the other does not?
## <a name="fileoptions" href="#toc">File options parser limitation</a>
Due to the way the parsing of options is done (no spaces between option char and
argument) shell expansion will not work right so for example doing:
$ ./recode -R~/config
Will not read the file 'config' in the home directory. I show another way to
achieve this later.
This limitation also applies to the `-f` and `-o` options!
## <a name="validation" href="#toc">-R option validation?</a>
Again the `-R` option does not validate input. For validation you have to run
the program interactively.
# <a name="pipingtorecode" href="#toc">Piping commands to recode</a>
If stdin is not a tty (`!isatty(0)`) and neither randomised mode nor reading in
from a file is specified then you might just see something like:
$ echo testing test tests | ./recode
1AB2BB3CC1testing test tests
$ echo testing test tests | ./recode | ./prog - 2>/dev/null
mfrwxan lzng ofnlu
$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode
1AB2BB3CC1mfrwxan lzng ofnlu
$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog - 2>/dev/null
testing test tests
In other words just the defaults. This was to simplify the problems with
prompting again for input if it's invalid (though as you'll see it does a good
job at this anyway).
# <a name="pipingtoenigma" href="#toc">Piping recode to the Enigma simulator</a>
If you're using recode to recode the input so you don't have to type in the
input manually (if you randomise or read in from previously saved file no input
need be done at all) then make sure to redirect stderr to /dev/null. If you
don't you might see something like:
$ ./recode -r | ./prog -
Ring 1: IOCCC
Setting 1: Position 1: Ring 2: Setting 2: Position 2: Ring 3: Setting 3: Position 3: Reflector: Plugboard pair 1: Plugboard pair 2: Plugboard pair 3: Plugboard pair 4: Plugboard pair 5: Plugboard pair 6: Plugboard pair 7: Plugboard pair 8: Plugboard pair 9: Plugboard pair 10: DEVIY
What happened is that `Ring 1: ` is printed to stderr but since it's not been
redirected to /dev/null it prints this out; at this point however it prompts for
input. Why or how it shows the first prompt instead of later on I do not know.
Anyway at this point the simulator is already expecting input to en/decipher.
That's why after I sent EOF it printed out the remaining strings to stderr.
# <a name="manuallytest" href="#toc">Manually test the recode program with the Enigma program</a>
$ cat input
IOCCC
$ ./recode -finput
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 1
Input rotor 2 (1 - 5): 2
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): A
Input setting 2 (A - Z): A
Input setting 3 (A - Z): A
Input position 1 (A - Z): A
Input position 2 (A - Z): A
Input position 3 (A - Z): A
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: AB
Input plugboard pair 2: CD
Input plugboard pair 3: ..
Input plugboard pair 4: EF
Input plugboard pair 5: GH
Input plugboard pair 6: IJ
Input plugboard pair 7: KL
Input plugboard pair 8: MN
Input plugboard pair 9: OP
Input plugboard pair 10: QR
1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC
Notice that I skipped a plugboard pair; this can be done in a number of ways but
two dots is one. Notice also that it's in a different order than the simulator:
because with the size restrictions on my entry I saved bytes by using the same
loop where I could. It just felt more natural to have them grouped together in a
configurator for the simulator.
$ echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC | ./prog - 2>/dev/null
HQNVO
$ echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC | ./prog - 2>/dev/null | echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRHQNVO | ./prog - 2>/dev/null
IOCCC
As you can see the recode program prompts for the settings and outputs the
input for the Enigma program. I then copied/pasted that output to the program
and got the result HQNVO.
Following this I piped the original output (of recode) to the simulator and then
piped that to the echo of the input settings (replacing the IOCCC with the
Enigma enciphered output) and then got the result IOCCC: the original input!
(This was before I implemented the `-R` option to greatly simplify things.)
Of course the last command was redundant in that I didn't need to show the first
part again; I could have just done the latter part but I wanted to show the way
the pipeline works with settings etc.
What happens if the plugboard pairs are the same but in a different order? It's
the same output:
$ echo 1AA2AA3AA2AB..CDEFGHIJKLMNOPQRIOCCC|./prog - 2>/dev/null
HQNVO
Also if you flip the order of the letters in the pair e.g. the AB as BA instead:
$ echo 1AA2AA3AA2BA..CDEFGHIJKLMNOPQRIOCCC|./prog - 2>/dev/null
HQNVO
# <a name="onlyconfig" href="#toc">Only write config file</a>
$ ./recode -v -oconfig -finput >/dev/null
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 1
Input rotor 2 (1 - 5): 2
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): A
Input setting 2 (A - Z): C
Input setting 3 (A - Z): E
Input position 1 (A - Z): B
Input position 2 (A - Z): D
Input position 3 (A - Z): F
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: AB
Input plugboard pair 2: CD
Input plugboard pair 3: EF
Input plugboard pair 4: GHIJ
Input plugboard pair 5: IJ
Input plugboard pair 6: KL
Input plugboard pair 7: MN
Input plugboard pair 8: OP
Input plugboard pair 9: QR
Input plugboard pair 10: ST
Ring 1: ( I) EKMFLGDQVZNTOWYHXUSPAIBRCJ
Ring 2: ( II) AJDKSIRUXBLHWTMCQGZNPYFVOE
Ring 3: (III) BDFHJLCPRTXVZNYEIWGAKMUSQO
Ring settings: ACE
Ring positions: BDF
Reflector: (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Plugboard pair #01: AB
Plugboard pair #02: CD
Plugboard pair #03: EF
Plugboard pair #04: GH
Plugboard pair #05: IJ
Plugboard pair #06: KL
Plugboard pair #07: MN
Plugboard pair #08: OP
Plugboard pair #09: QR
Plugboard pair #10: ST
Notice that I redirect stdout to /dev/null so that the config is only written to
the file config. But also notice that for plugboard pair 4 I typed in `GHIJ` and
it didn't report an error. Neither did it complain about `IJ` in the next pair.
This is because it consumes input overflow.
It shouldn't be this way for the simulator though because that could cause
inconsistent number of characters expected before the text to encipher.
$ cat config
1AB2CD3EF2ABCDEFGHIJKLMNOPQRST
$ ( cat config ; cat input ) | ./prog - 2>/dev/null
LRAVE
$ ( cat config ; cat input ) | ./prog - 2>/dev/null | ( cat config ; echo LRAVE ) | ./prog - 2>/dev/null
IOCCC
What if you don't want to worry about having to specify input but just have the
settings written? You can do that too by either sending a newline or else
directly type ctrl-d (or whatever you have EOF set to) or give it an empty file.
The following are all equivalent in that they will write to a settings file (the
first one will print a newline with the echo but that won't matter):
$ echo | ./recode -r -osettings
$ echo -n | ./recode -r -osettings
$ > empty
$ ./recode -r -osettings < empty
$ cat empty | ./recode -r -osettings
$ ./recode -r -osettings
^D
(Above ^D was not shown but I typed it.) The way it works: if nothing is read
the buffer remains NULL and so I don't print it but still do print the settings
file. Actually even if getdelim() fails you're supposed to free the buffer so I
set another variable to indicate if it should be printed.
# <a name="reuseconfig" href="#toc">Reusing a configuration</a>
$ echo -n|./recode -r -oconfig
4UH5II1RJ1SPIFEJLYGZWRTBHVCAMN$
$ cat input.txt
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
$ ( cat config ; cat input.txt ) | ./prog - 2>/dev/null > output
$ cat output
AAPRT 2020 Dkemny tpgnjsjai xpovrgl jvgs wxra
Fytt ly m xyiilaqh.
Ybbp ox dmuzerm oscwgytb.
$ ( cat config ; cat output ) | ./prog - 2>/dev/null > io
$ diff io input.txt
$
Alternatively you can just use the `-R` and `-f` options:
$ ./recode -finput.txt -Rconfig | ./prog - 2>/dev/null > output2
$ diff output output2
$
# <a name="passtoenigma" href="#toc">Write config file, read data file and pass to Enigma simulator</a>
$ ./recode -finput.txt -oconfig | ./prog - 2>/dev/null > output
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 2
Input rotor 2 (1 - 5): 5
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): C
Input setting 2 (A - Z): O
Input setting 3 (A - Z): D
Input position 1 (A - Z): E
Input position 2 (A - Z): L
Input position 3 (A - Z): O
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: TR
Input plugboard pair 2: SN
Input plugboard pair 3: OG
Input plugboard pair 4: ME
Input plugboard pair 5: XY
Input plugboard pair 6: WZ
Input plugboard pair 7: UV
Input plugboard pair 8: AB
Input plugboard pair 9: CD
Input plugboard pair 10: FI
$ cat config
2CE5OL3DO2TRSNOGMEXYWZUVABCDFI
Besides a famous book that I happen to love (who doesn't? Ah, but what is it
Cody?) there's also a reference to code which I also love (just as all
participants of the IOCCC do). But what matters is the output:
$ cat output
DBFAF 2020 Ittejg ltblwriac uqdfqvr dhqh ghhf
Jsjy ce v pxdmullo.
Sara tj rtaayak uxfhjcti.
$ ./recode -Rconfig -foutput | ./prog - 2>/dev/null
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
# <a name="directlytoenigma" href="#toc">Piping directly to the Enigma code once (with randomised settings, saved)</a>
This is like the above only randomised:
$ ./recode -r -oconfig|./prog - 2>/dev/null
IOCCC
UGEVP
Note that I typed in IOCCC and sent EOF (ctrl-d); the settings were written to
the config file (for deciphering later) and then all of it was piped to the
Enigma entry resulting in the line below IOCCC. But let's verify it worked out
okay:
$ cat config
2BM4GJ3HK1LNCBXWRMGKSYIAZUTPVJ
Without having to copy/paste intermediate results:
$ echo IOCCC | ./recode -Rconfig | ./prog - 2>/dev/null | ./recode -Rconfig | ./prog - 2>/dev/null
IOCCC
You can also use a string for the `-R` option. I'll use command substitution and
actual pasting to demonstrate:
$ echo IOCCC | ./recode -R$(cat config) | ./prog - 2>/dev/null | ./recode -R2BM4GJ3HK1LNCBXWRMGKSYIAZUTPVJ | ./prog - 2>/dev/null
IOCCC
# <a name="conclusion" href="#toc">Usage conclusion</a>
That should give you an idea of how to use the recode program. I leave it as
an exercise to the reader to implement additional features but here are some
ideas of what could be done and how this entry might be used (including that
delicious challenge).
# <a name="additions" href="#toc">Example additions</a>
* Add code (to prog.c) that tries to determine possible decipherments based on
a given crib (or set of cribs).
# <a name="exampleuses" href="#toc">Example uses</a>
* Take an actual key sheet and message for that day and try and decipher the
message (might help if you know German!). I haven't actually done this for
reasons I explained in the remarks (including that I cannot easily verify one
particular as well as the fact that there were different procedures, different
machines etc. - plus my vision is not good enough for the quality of the
pictures).
* Try making sense of a politician's speeches by putting them into the
simulator. It might not make much sense but can it honestly be that much worse ?
:) Actually yes it could be (and we don't need the Enigma helping them either)
and I can think of a whole host of other things more entertaining including
watching dry paint stay dry on a wall but why not poke fun at politicians
anyway?
* Best idea: try the below experiment!
# <a name="cake" href="#toc">Delicious Enigma: Double-layered Chocolate Fudge Cake</a>
As I was making the above silly list something occurred to me. My other entries
this year include a recipe for a wonderful double-layered chocolate fudge cake
but why would it not be included in this one too? But then if that's the case
why on Earth should it be unscrambled?
So this is what I offer: if you take one of the settings below and run the
simulator on the file [chocolate-cake.html][] you will have a wonderful
chocolate cake recipe (that even my late stepmum who didn't even like chocolate
loved - it's a speciality of my mum's and they were the best of friends too). If
you're lazy just go and look at my other entry. Then again if you're lazy you're
probably not reading this far! :)
The settings is one of the below but a couple questions you might ask yourself:
1. Are any invalid input?
2. Is there some other kind of trickery involved here?
I can think of the best way to answer these and I think I need not even mention
it. Have fun and enjoy! BTW: Depending on where you are in this world and how
warm it is the icing can be a bit of an issue - I give some ideas in the file on
what can be done for this. At worst though the icing won't come out as good as
it usually does.
Hints:
1. It's not the middle one.
2. Yes there are some things kind of spelt here. These include things about
cake and chocolate. Some things spelt mean nothing whatever and can be
considered coincidences. Some were randomised.
3. There is an obscure thing about my entry that can help locate the proper key
of the 16 given below! The questions are what is it and is is it worth going
this way? (I think the second answer is 'no' but that's me.)
4. The above points might or might not be relevant. What is relevant is one
will reveal a wonderful [Double-layered Chocolate Fudge Cake][] recipe:
142CHOCOLATESVCAKESTBJLKMUMVWX
0EZ4PC1CC0PGTAQSOXWNMDRYKFUZEI
3UY0XF4QG1GTJQLARPKHBEMCOFVUIN
0WE1HK4PL0RVSGXFDKENZYTPCMAHUW
2LV0KC1IE0HTFPCLWOJDBQIRVMEAGN
1SS4QX2RY1SRAQGKUYHCBLPFJDVTNZ
3IW1QR0TZ0GQEDWIYJUPMFZBRAONHS
3OP1KN4MO0HPFZCEAKYQIRXGVMOTUW
4OC2CC0AK1CODELUVRSNGKIZBJPTMY
4MU0MS1CA1KELUVRSXTABJNOCDMQFG
0MU4MC2HO1CLATEFBJMONPQRVWXYZD
125CHOCOLATESEXCAKESJADFNOPQRS
0CH3OC1OL1ATEMBJNOCDLSIFWHRVXY
4MU1MS3CA0KECHOLATBJSNPXVUFGZY
4VW0SL1YB0IYJSLBECKTNAXGPUVHRF
0MC4OH2CO1LATEUMBJCDFGHINOPRQS
BTW: What's the middle of a list with even numbered items anyway?
[chocolate-cake.html]: chocolate-cake.html
[Double-layered Chocolate Fudge Cake]: chocolate-cake.html
+572
View File
@@ -0,0 +1,572 @@
# The recode configurator documentation (and a fun way to explore my 2020 IOCCC Enigma simulator)
N.B. At the end of this file I have given a fun exercise that can be used to
explore my Enigma simulator. It's especially worth doing if you you like
good chocolate and could use a delicious [Double-layered Chocolate Fudge Cake][].
Alternatively if you just want the recipe you could look at my Snake entry
'Don't tread on me award' since it's also there and not enciphered.
<a name="toc"></a>
- [What is recode and why is it recommended?](#recode)
- [Options](#options)
* [Protecting against the same I/O file](#samefile)
* [File options parser limitation](#fileoptions)
* [-R option validation?](#validation)
- [Piping commands to recode](#pipingtorecode)
- [Piping recode to the Enigma simulator](#pipingtoenigma)
- [Manually test the recode program with the Enigma program](#manuallytest)
- [Only write config file](#onlyconfig)
- [Reusing a configuration](#reuseconfig)
- [Write config file, read data file and pass to Enigma simulator](#passtoenigma)
- [Piping directly to the Enigma code once (with randomised settings, saved)](#directlytoenigma)
- [Usage conclusion](#conclusion)
- [Example additions](#additions)
- [Example uses](#exampleuses)
- [Delicious Enigma: Double-layered Chocolate Fudge Cake](#cake)
# <a name="recode" href="#toc">What is recode and why is it recommended?</a>
To demonstrate how to and why you should use the recode program with the Enigma
simulator I have included some examples here as well as brief ('brief?!' I am sure
many would think but it's brief for me) commentary.
It would not be possible to do all that the recode program does in my entry
itself but I wanted to demonstrate the features of my entry and this seemed the
best way to do that. It also enhances the use of the simulator to make it
reusable etc.
The recode name idea is that it recodes the input (validating first) to be input
for the simulator itself. It can pseudo-randomly select all the settings, it can
write the settings to a file, read from input file (e.g. for the text to
encipher if piped to the simulator) etc.
Basically it's a configurator for the Enigma simulator that makes it easier to
use the simulator as well as to reuse the configuration to decipher messages
that have been enciphered by those settings. But it also tries to make it look
more like the real thing in that it shows the actual rotors (labelling them with
the Roman numeral), the reflectors (labelling them with B, C and showing the
actual strings) etc.
In this file I will show an example of each feature and then get to the
wonderful 'challenge' for everyone.
# <a name="options" href="#toc">Options</a>
usage: ./recode [options]
-v display selected settings
-r pseudo-randomly select settings
-f<input file> read file for Enigma input
-R<string|file> init settings from settings string or file
-o<output file> write settings to file
`-r` randomises settings. It won't prompt you for settings but it will for input
if you don't give the option to read in a file for input.
`-v` shows selected settings. For example combining `-r` and `-v`:
$ echo IOCCC | ./recode -r -v
Ring 1: ( I) EKMFLGDQVZNTOWYHXUSPAIBRCJ
Ring 2: ( V) VZBRGITYUPSDNHLXAWMJQOFECK
Ring 3: ( IV) ESOVPZJAYQUIRHXLNFTGKDCMWB
Ring settings: WAR
Ring positions: XKE
Reflector: (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
Plugboard pair #01: XE
Plugboard pair #02: HJ
Plugboard pair #03: SA
Plugboard pair #04: PY
Plugboard pair #05: CI
Plugboard pair #06: ZB
Plugboard pair #07: WD
Plugboard pair #08: QN
Plugboard pair #09: RU
Plugboard pair #10: VG
1WX5AK4RE1XEHJSAPYCIZBWDQNRUVGIOCCC
Though you won't find such strings in recode.c or prog.c. (You will find the
Roman numerals for the rotors and the 'A' and 'B' for the reflectors in recode.c
though). Yes the 'WAR' for the Ringstellung (Ring settings) is an amusing
coincidence *but it really did happen!*
As for `-f` the contents would be output with the settings e.g. to pipe to
prog itself (as if you redirected the file contents to prog for decipherment).
If the file cannot be opened it sets back to stdin.
`-o` outputs the settings to the file. If the file cannot be opened for writing
or is the same file name (see below) then only stdout will be used. Example of
randomised output going to a file:
$ ./recode -r -oconfig
IOCCC
3PP4UB5GG1ELGTKFCOPVBNUYXJAWSDIOCCC
$ cat config
3PP4UB5GG1ELGTKFCOPVBNUYXJAWSD$
Notice that a terminating newline isn't added. Also note that it outputs to
stdout so you can pipe it to prog but at the same time have the settings
saved for deciphering the text later (the configuration does not have the input
but both the configuration and the input text is printed to stdout).
If you want to initialise the settings from previously saved settings (as a
string or an input file that has the same format) use the `-R<settings>` option.
Again note that this does not validate input! Although it detects out of range
for the arrays it doesn't detect duplicates. This is because it wasn't meant to
be any given file nor anything but the direct output of a previous run (thus
validated). I'm not even guaranteeing that I got the array tests valid in
recode.c -R option!
## <a name="samefile" href="#toc">Protecting against the same I/O file</a>
Because some file systems are case-insensitive I have implemented a
case-insensitive strcmp(); if the input file name is the same as the output file
name I won't write to it. From a quick test this is important particularly if
neither file exist because if both calls to stat() fail then the inodes will be
the same (since what else could they be set to but the same initial value?).
This might be overprotective but I believe it better to prevent user error where
possible. Of course if neither file exists it might be argued that it's not
necessary to worry since you can't read from a file that doesn't exist. But then
what about if one exists but the other does not?
## <a name="fileoptions" href="#toc">File options parser limitation</a>
Due to the way the parsing of options is done (no spaces between option char and
argument) shell expansion will not work right so for example doing:
$ ./recode -R~/config
Will not read the file 'config' in the home directory. I show another way to
achieve this later.
This limitation also applies to the `-f` and `-o` options!
## <a name="validation" href="#toc">-R option validation?</a>
Again the `-R` option does not validate input. For validation you have to run
the program interactively.
# <a name="pipingtorecode" href="#toc">Piping commands to recode</a>
If stdin is not a tty (`!isatty(0)`) and neither randomised mode nor reading in
from a file is specified then you might just see something like:
$ echo testing test tests | ./recode
1AB2BB3CC1testing test tests
$ echo testing test tests | ./recode | ./prog - 2>/dev/null
mfrwxan lzng ofnlu
$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode
1AB2BB3CC1mfrwxan lzng ofnlu
$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog - 2>/dev/null
testing test tests
In other words just the defaults. This was to simplify the problems with
prompting again for input if it's invalid (though as you'll see it does a good
job at this anyway).
# <a name="pipingtoenigma" href="#toc">Piping recode to the Enigma simulator</a>
If you're using recode to recode the input so you don't have to type in the
input manually (if you randomise or read in from previously saved file no input
need be done at all) then make sure to redirect stderr to /dev/null. If you
don't you might see something like:
$ ./recode -r | ./prog -
Ring 1: IOCCC
Setting 1: Position 1: Ring 2: Setting 2: Position 2: Ring 3: Setting 3: Position 3: Reflector: Plugboard pair 1: Plugboard pair 2: Plugboard pair 3: Plugboard pair 4: Plugboard pair 5: Plugboard pair 6: Plugboard pair 7: Plugboard pair 8: Plugboard pair 9: Plugboard pair 10: DEVIY
What happened is that `Ring 1: ` is printed to stderr but since it's not been
redirected to /dev/null it prints this out; at this point however it prompts for
input. Why or how it shows the first prompt instead of later on I do not know.
Anyway at this point the simulator is already expecting input to en/decipher.
That's why after I sent EOF it printed out the remaining strings to stderr.
# <a name="manuallytest" href="#toc">Manually test the recode program with the Enigma program</a>
$ cat input
IOCCC
$ ./recode -finput
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 1
Input rotor 2 (1 - 5): 2
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): A
Input setting 2 (A - Z): A
Input setting 3 (A - Z): A
Input position 1 (A - Z): A
Input position 2 (A - Z): A
Input position 3 (A - Z): A
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: AB
Input plugboard pair 2: CD
Input plugboard pair 3: ..
Input plugboard pair 4: EF
Input plugboard pair 5: GH
Input plugboard pair 6: IJ
Input plugboard pair 7: KL
Input plugboard pair 8: MN
Input plugboard pair 9: OP
Input plugboard pair 10: QR
1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC
Notice that I skipped a plugboard pair; this can be done in a number of ways but
two dots is one. Notice also that it's in a different order than the simulator:
because with the size restrictions on my entry I saved bytes by using the same
loop where I could. It just felt more natural to have them grouped together in a
configurator for the simulator.
$ echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC | ./prog - 2>/dev/null
HQNVO
$ echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRIOCCC | ./prog - 2>/dev/null | echo 1AA2AA3AA2ABCD..EFGHIJKLMNOPQRHQNVO | ./prog - 2>/dev/null
IOCCC
As you can see the recode program prompts for the settings and outputs the
input for the Enigma program. I then copied/pasted that output to the program
and got the result HQNVO.
Following this I piped the original output (of recode) to the simulator and then
piped that to the echo of the input settings (replacing the IOCCC with the
Enigma enciphered output) and then got the result IOCCC: the original input!
(This was before I implemented the `-R` option to greatly simplify things.)
Of course the last command was redundant in that I didn't need to show the first
part again; I could have just done the latter part but I wanted to show the way
the pipeline works with settings etc.
What happens if the plugboard pairs are the same but in a different order? It's
the same output:
$ echo 1AA2AA3AA2AB..CDEFGHIJKLMNOPQRIOCCC|./prog - 2>/dev/null
HQNVO
Also if you flip the order of the letters in the pair e.g. the AB as BA instead:
$ echo 1AA2AA3AA2BA..CDEFGHIJKLMNOPQRIOCCC|./prog - 2>/dev/null
HQNVO
# <a name="onlyconfig" href="#toc">Only write config file</a>
$ ./recode -v -oconfig -finput >/dev/null
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 1
Input rotor 2 (1 - 5): 2
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): A
Input setting 2 (A - Z): C
Input setting 3 (A - Z): E
Input position 1 (A - Z): B
Input position 2 (A - Z): D
Input position 3 (A - Z): F
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: AB
Input plugboard pair 2: CD
Input plugboard pair 3: EF
Input plugboard pair 4: GHIJ
Input plugboard pair 5: IJ
Input plugboard pair 6: KL
Input plugboard pair 7: MN
Input plugboard pair 8: OP
Input plugboard pair 9: QR
Input plugboard pair 10: ST
Ring 1: ( I) EKMFLGDQVZNTOWYHXUSPAIBRCJ
Ring 2: ( II) AJDKSIRUXBLHWTMCQGZNPYFVOE
Ring 3: (III) BDFHJLCPRTXVZNYEIWGAKMUSQO
Ring settings: ACE
Ring positions: BDF
Reflector: (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Plugboard pair #01: AB
Plugboard pair #02: CD
Plugboard pair #03: EF
Plugboard pair #04: GH
Plugboard pair #05: IJ
Plugboard pair #06: KL
Plugboard pair #07: MN
Plugboard pair #08: OP
Plugboard pair #09: QR
Plugboard pair #10: ST
Notice that I redirect stdout to /dev/null so that the config is only written to
the file config. But also notice that for plugboard pair 4 I typed in `GHIJ` and
it didn't report an error. Neither did it complain about `IJ` in the next pair.
This is because it consumes input overflow.
It shouldn't be this way for the simulator though because that could cause
inconsistent number of characters expected before the text to encipher.
$ cat config
1AB2CD3EF2ABCDEFGHIJKLMNOPQRST
$ ( cat config ; cat input ) | ./prog - 2>/dev/null
LRAVE
$ ( cat config ; cat input ) | ./prog - 2>/dev/null | ( cat config ; echo LRAVE ) | ./prog - 2>/dev/null
IOCCC
What if you don't want to worry about having to specify input but just have the
settings written? You can do that too by either sending a newline or else
directly type ctrl-d (or whatever you have EOF set to) or give it an empty file.
The following are all equivalent in that they will write to a settings file (the
first one will print a newline with the echo but that won't matter):
$ echo | ./recode -r -osettings
$ echo -n | ./recode -r -osettings
$ > empty
$ ./recode -r -osettings < empty
$ cat empty | ./recode -r -osettings
$ ./recode -r -osettings
^D
(Above ^D was not shown but I typed it.) The way it works: if nothing is read
the buffer remains NULL and so I don't print it but still do print the settings
file. Actually even if getdelim() fails you're supposed to free the buffer so I
set another variable to indicate if it should be printed.
# <a name="reuseconfig" href="#toc">Reusing a configuration</a>
$ echo -n|./recode -r -oconfig
4UH5II1RJ1SPIFEJLYGZWRTBHVCAMN$
$ cat input.txt
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
$ ( cat config ; cat input.txt ) | ./prog - 2>/dev/null > output
$ cat output
AAPRT 2020 Dkemny tpgnjsjai xpovrgl jvgs wxra
Fytt ly m xyiilaqh.
Ybbp ox dmuzerm oscwgytb.
$ ( cat config ; cat output ) | ./prog - 2>/dev/null > io
$ diff io input.txt
$
Alternatively you can just use the `-R` and `-f` options:
$ ./recode -finput.txt -Rconfig | ./prog - 2>/dev/null > output2
$ diff output output2
$
# <a name="passtoenigma" href="#toc">Write config file, read data file and pass to Enigma simulator</a>
$ ./recode -finput.txt -oconfig | ./prog - 2>/dev/null > output
Rotors:
(1) I: EKMFLGDQVZNTOWYHXUSPAIBRCJ
(2) II: AJDKSIRUXBLHWTMCQGZNPYFVOE
(3) III: BDFHJLCPRTXVZNYEIWGAKMUSQO
(4) IV: ESOVPZJAYQUIRHXLNFTGKDCMWB
(5) V: VZBRGITYUPSDNHLXAWMJQOFECK
Input rotor 1 (1 - 5): 2
Input rotor 2 (1 - 5): 5
Input rotor 3 (1 - 5): 3
Input setting 1 (A - Z): C
Input setting 2 (A - Z): O
Input setting 3 (A - Z): D
Input position 1 (A - Z): E
Input position 2 (A - Z): L
Input position 3 (A - Z): O
Reflector:
(1) (B) YRUHQSLDPXNGOKMIEBFZCWVJAT
(2) (C) FVPJIAOYEDRZXWGCTKUQSBNMHL
Input reflector (1 - 2): 2
Input plugboard pair 1: TR
Input plugboard pair 2: SN
Input plugboard pair 3: OG
Input plugboard pair 4: ME
Input plugboard pair 5: XY
Input plugboard pair 6: WZ
Input plugboard pair 7: UV
Input plugboard pair 8: AB
Input plugboard pair 9: CD
Input plugboard pair 10: FI
$ cat config
2CE5OL3DO2TRSNOGMEXYWZUVABCDFI
Besides a famous book that I happen to love (who doesn't? Ah, but what is it
Cody?) there's also a reference to code which I also love (just as all
participants of the IOCCC do). But what matters is the output:
$ cat output
DBFAF 2020 Ittejg ltblwriac uqdfqvr dhqh ghhf
Jsjy ce v pxdmullo.
Sara tj rtaayak uxfhjcti.
$ ./recode -Rconfig -foutput | ./prog - 2>/dev/null
IOCCC 2020 Enigma simulator example text file
This is a sentence.
This is another sentence.
# <a name="directlytoenigma" href="#toc">Piping directly to the Enigma code once (with randomised settings, saved)</a>
This is like the above only randomised:
$ ./recode -r -oconfig|./prog - 2>/dev/null
IOCCC
UGEVP
Note that I typed in IOCCC and sent EOF (ctrl-d); the settings were written to
the config file (for deciphering later) and then all of it was piped to the
Enigma entry resulting in the line below IOCCC. But let's verify it worked out
okay:
$ cat config
2BM4GJ3HK1LNCBXWRMGKSYIAZUTPVJ
Without having to copy/paste intermediate results:
$ echo IOCCC | ./recode -Rconfig | ./prog - 2>/dev/null | ./recode -Rconfig | ./prog - 2>/dev/null
IOCCC
You can also use a string for the `-R` option. I'll use command substitution and
actual pasting to demonstrate:
$ echo IOCCC | ./recode -R$(cat config) | ./prog - 2>/dev/null | ./recode -R2BM4GJ3HK1LNCBXWRMGKSYIAZUTPVJ | ./prog - 2>/dev/null
IOCCC
# <a name="conclusion" href="#toc">Usage conclusion</a>
That should give you an idea of how to use the recode program. I leave it as
an exercise to the reader to implement additional features but here are some
ideas of what could be done and how this entry might be used (including that
delicious challenge).
# <a name="additions" href="#toc">Example additions</a>
* Add code (to prog.c) that tries to determine possible decipherments based on
a given crib (or set of cribs).
# <a name="exampleuses" href="#toc">Example uses</a>
* Take an actual key sheet and message for that day and try and decipher the
message (might help if you know German!). I haven't actually done this for
reasons I explained in the remarks (including that I cannot easily verify one
particular as well as the fact that there were different procedures, different
machines etc. - plus my vision is not good enough for the quality of the
pictures).
* Try making sense of a politician's speeches by putting them into the
simulator. It might not make much sense but can it honestly be that much worse ?
:) Actually yes it could be (and we don't need the Enigma helping them either)
and I can think of a whole host of other things more entertaining including
watching dry paint stay dry on a wall but why not poke fun at politicians
anyway?
* Best idea: try the below experiment!
# <a name="cake" href="#toc">Delicious Enigma: Double-layered Chocolate Fudge Cake</a>
As I was making the above silly list something occurred to me. My other entries
this year include a recipe for a wonderful double-layered chocolate fudge cake
but why would it not be included in this one too? But then if that's the case
why on Earth should it be unscrambled?
So this is what I offer: if you take one of the settings below and run the
simulator on the file [chocolate-cake.html][] you will have a wonderful
chocolate cake recipe (that even my late stepmum who didn't even like chocolate
loved - it's a speciality of my mum's and they were the best of friends too). If
you're lazy just go and look at my other entry. Then again if you're lazy you're
probably not reading this far! :)
The settings is one of the below but a couple questions you might ask yourself:
1. Are any invalid input?
2. Is there some other kind of trickery involved here?
I can think of the best way to answer these and I think I need not even mention
it. Have fun and enjoy! BTW: Depending on where you are in this world and how
warm it is the icing can be a bit of an issue - I give some ideas in the file on
what can be done for this. At worst though the icing won't come out as good as
it usually does.
Hints:
1. It's not the middle one.
2. Yes there are some things kind of spelt here. These include things about
cake and chocolate. Some things spelt mean nothing whatever and can be
considered coincidences. Some were randomised.
3. There is an obscure thing about my entry that can help locate the proper key
of the 16 given below! The questions are what is it and is is it worth going
this way? (I think the second answer is 'no' but that's me.)
4. The above points might or might not be relevant. What is relevant is one
will reveal a wonderful [Double-layered Chocolate Fudge Cake][] recipe:
142CHOCOLATESVCAKESTBJLKMUMVWX
0EZ4PC1CC0PGTAQSOXWNMDRYKFUZEI
3UY0XF4QG1GTJQLARPKHBEMCOFVUIN
0WE1HK4PL0RVSGXFDKENZYTPCMAHUW
2LV0KC1IE0HTFPCLWOJDBQIRVMEAGN
1SS4QX2RY1SRAQGKUYHCBLPFJDVTNZ
3IW1QR0TZ0GQEDWIYJUPMFZBRAONHS
3OP1KN4MO0HPFZCEAKYQIRXGVMOTUW
4OC2CC0AK1CODELUVRSNGKIZBJPTMY
4MU0MS1CA1KELUVRSXTABJNOCDMQFG
0MU4MC2HO1CLATEFBJMONPQRVWXYZD
125CHOCOLATESEXCAKESJADFNOPQRS
0CH3OC1OL1ATEMBJNOCDLSIFWHRVXY
4MU1MS3CA0KECHOLATBJSNPXVUFGZY
4VW0SL1YB0IYJSLBECKTNAXGPUVHRF
0MC4OH2CO1LATEUMBJCDFGHINOPRQS
BTW: What's the middle of a list with even numbered items anyway?
[chocolate-cake.html]: chocolate-cake.html
[Double-layered Chocolate Fudge Cake]: chocolate-cake.html
-----------------------------------------------------------------------------------------------------
(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-----------------------------------------------------------------------------------------------------
+21
View File
@@ -0,0 +1,21 @@
3
I
O
1
C
C
5
C
Z
2
CO
DE
SN
XY
MS
AT
VF
UR
KL
BJ
IOCCC