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.
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.
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:
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!
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?
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).
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.
$ 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.
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:
$ ./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.
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):
(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.
$ ./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.
-
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:
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).
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?
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:
-
-
-
Are any invalid input?
-
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:
-
-
-
It’s not the middle one.
-
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.
-
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.)
-
The above points might or might not be relevant. What is relevant is one
-will reveal a wonderful Double-layered Chocolate Fudge Cake recipe:
-
-
diff --git a/2020/ferguson2/try.alt.sh b/2020/ferguson2/try.alt.sh
new file mode 100755
index 000000000..2b1fbe45e
--- /dev/null
+++ b/2020/ferguson2/try.alt.sh
@@ -0,0 +1,124 @@
+#!/usr/bin/env bash
+#
+# try.sh - demonstrate IOCCC winner 2020/ferguson2
+#
+# I, Cody Boone Ferguson, 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.
+#
+
+# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
+# this way allows us to have the user specify a different compiler in an easy
+# way.
+if [[ -z "$CC" ]]; then
+ CC="cc"
+fi
+
+make CC="$CC" alt >/dev/null || exit 1
+
+# clear screen after compilation so that only the entry is shown
+clear
+
+# IOCCC obfuscated!
+read -r -n 1 -p "Press any key to encrypt IOCCC with default settings: "
+echo 1>&2
+echo "$ echo IOCCC | ./prog.alt" 1>&2
+echo IOCCC | ./prog.alt
+echo 1>&2
+
+# IOCCC obfuscated and de-obfuscated!:
+read -r -n 1 -p "Press any key to encrypt and then decrypt IOCCC with default settings: "
+echo 1>&2
+echo "$ echo IOCCC | ./prog | ./prog.alt" 1>&2
+echo IOCCC | ./prog | ./prog.alt
+echo 1>&2
+
+# more input fun:
+read -r -n 1 -p "Press any key to show try.this.txt: "
+echo 1>&2
+echo "$ cat try.this.txt" 1>&2
+cat try.this.txt
+read -r -n 1 -p "Press any key to encrypt text of try.this.txt with its own settings: "
+echo 1>&2
+echo "$ ./prog.alt - < try.this.txt 2>/dev/null" 1>&2
+echo 1>&2
+./prog.alt - < try.this.txt 2>/dev/null
+echo 1>&2
+
+# more obfuscated fun:
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode" 1>&2
+echo testing test tests | ./recode
+echo 1>&2
+
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode -> prog.alt: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode | ./prog.alt - 2>/dev/null" 1>&2
+echo testing test tests | ./recode | ./prog.alt - 2>/dev/null
+echo 1>&2
+
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode -> prog -> recode: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode" 1>&2
+echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode
+echo 1>&2
+
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode -> prog -> recode -> prog.alt: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog.alt - 2>/dev/null" 1>&2
+echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog.alt - 2>/dev/null
+echo 1>&2
+
+# even more obfuscated fun saving and reading from files:
+#
+# initial clean up:
+rm -f conf input output output2
+# encrypt "testing test tests" with randomised settings saved in conf, saving
+# original string to input and original output to output:
+read -r -n 1 -p "Press any key to save settings and output, then encrypt: "
+echo 1>&2
+echo "$ echo testing test tests | tee input | ./recode -r -oconf | ./prog - 2>/dev/null >output" 1>&2
+echo testing test tests | tee input | ./recode -r -oconf | ./prog - 2>/dev/null >output
+read -r -n 1 -p "Press any key to show input file: "
+echo 1>&2
+cat input
+echo 1>&2
+read -r -n 1 -p "Press any key to show output file: "
+echo 1>&2
+cat output
+echo 1>&2
+# configure Enigma machine from conf file and read from output file, thus decrypting:
+read -r -n 1 -p "Press any key to decrypt the output from the above command: "
+echo 1>&2
+echo "$ ./recode -Rconf -foutput | ./prog - 2>/dev/null > output2" 1>&2
+./recode -Rconf -foutput | ./prog - 2>/dev/null > output2
+read -r -n 1 -p "Press any key to show output2: "
+echo 1>&2
+cat output2
+read -r -n 1 -p "Press any key to show input again: "
+echo 1>&2
+cat input
+echo 1>&2
+# make sure input and output2 are the same:
+read -r -n 1 -p "Press any key to compare input and output2: "
+echo 1>&2
+diff -s input output2
+diff -s input output2
+# final clean up
+rm -f conf input output output2
diff --git a/2020/ferguson2/try.sh b/2020/ferguson2/try.sh
new file mode 100755
index 000000000..2d70f4f2c
--- /dev/null
+++ b/2020/ferguson2/try.sh
@@ -0,0 +1,124 @@
+#!/usr/bin/env bash
+#
+# try.sh - demonstrate IOCCC winner 2020/ferguson2
+#
+# I, Cody Boone Ferguson, 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.
+#
+
+# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
+# this way allows us to have the user specify a different compiler in an easy
+# way.
+if [[ -z "$CC" ]]; then
+ CC="cc"
+fi
+
+make CC="$CC" all >/dev/null || exit 1
+
+# clear screen after compilation so that only the entry is shown
+clear
+
+# IOCCC obfuscated!
+read -r -n 1 -p "Press any key to encrypt IOCCC with default settings: "
+echo 1>&2
+echo "$ echo IOCCC | ./prog" 1>&2
+echo IOCCC | ./prog
+echo 1>&2
+
+# IOCCC obfuscated and de-obfuscated!:
+read -r -n 1 -p "Press any key to encrypt and then decrypt IOCCC with default settings: "
+echo 1>&2
+echo "$ echo IOCCC | ./prog | ./prog" 1>&2
+echo IOCCC | ./prog | ./prog
+echo 1>&2
+
+# more input fun:
+read -r -n 1 -p "Press any key to show try.this.txt: "
+echo 1>&2
+echo "$ cat try.this.txt" 1>&2
+cat try.this.txt
+read -r -n 1 -p "Press any key to encrypt text of try.this.txt with its own settings: "
+echo 1>&2
+echo "$ ./prog - < try.this.txt 2>/dev/null" 1>&2
+echo 1>&2
+./prog - < try.this.txt 2>/dev/null
+echo 1>&2
+
+# more obfuscated fun:
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode" 1>&2
+echo testing test tests | ./recode
+echo 1>&2
+
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode -> prog: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode | ./prog - 2>/dev/null" 1>&2
+echo testing test tests | ./recode | ./prog - 2>/dev/null
+echo 1>&2
+
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode -> prog -> recode: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode" 1>&2
+echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode
+echo 1>&2
+
+read -r -n 1 -p "Press any key to send 'testing test tests' to recode -> prog -> recode -> prog: "
+echo 1>&2
+echo "$ echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog - 2>/dev/null" 1>&2
+echo testing test tests | ./recode | ./prog - 2>/dev/null | ./recode | ./prog - 2>/dev/null
+echo 1>&2
+
+# even more obfuscated fun saving and reading from files:
+#
+# initial clean up:
+rm -f conf input output output2
+# encrypt "testing test tests" with randomised settings saved in conf, saving
+# original string to input and original output to output:
+read -r -n 1 -p "Press any key to save settings and output, then encrypt: "
+echo 1>&2
+echo "$ echo testing test tests | tee input | ./recode -r -oconf | ./prog - 2>/dev/null >output" 1>&2
+echo testing test tests | tee input | ./recode -r -oconf | ./prog - 2>/dev/null >output
+read -r -n 1 -p "Press any key to show input file: "
+echo 1>&2
+cat input
+echo 1>&2
+read -r -n 1 -p "Press any key to show output file: "
+echo 1>&2
+cat output
+echo 1>&2
+# configure Enigma machine from conf file and read from output file, thus decrypting:
+read -r -n 1 -p "Press any key to decrypt the output from the above command: "
+echo 1>&2
+echo "$ ./recode -Rconf -foutput | ./prog - 2>/dev/null > output2" 1>&2
+./recode -Rconf -foutput | ./prog - 2>/dev/null > output2
+read -r -n 1 -p "Press any key to show output2: "
+echo 1>&2
+cat output2
+read -r -n 1 -p "Press any key to show input again: "
+echo 1>&2
+cat input
+echo 1>&2
+# make sure input and output2 are the same:
+read -r -n 1 -p "Press any key to compare input and output2: "
+echo 1>&2
+diff -s input output2
+diff -s input output2
+# final clean up
+rm -f conf input output output2
diff --git a/thanks-for-help.md b/thanks-for-help.md
index 20519e210..aa8246a0d 100644
--- a/thanks-for-help.md
+++ b/thanks-for-help.md
@@ -4368,6 +4368,11 @@ and I encourage you to do so as the cake is quite picky!
[Cody](#cody), with intentional irony here :-), fixed formatting, links and typos in
various files.
+He also added the [try.sh](/2020/ferguson2/try.sh) script.
+
+He also added the [alt code](/2020/ferguson2/README.md#alternate-code) and the
+[try.alt.sh](/2020/ferguson2/try.alt.sh) script.
+
He also fixed some issues that occurred when files were renamed to `.md` from
`.markdown`.