The following are:

1) Upgraded procedure for an up-to-date operating system on the Raspberry Pi True HWRNG OTP/DRYAD/CEOI (G6-Pi) now also with FULL DISK ENCRYPTION;

2) A proposed Expanded-37 character OTP/CodeBook system;

3) A minor update to the Password Generator script.

Short note: I updated Password Generator script to include the option for hexadecimal as some devices’ keys (uh, like some of my own radios…) use that format. A simple fix.

On to the meat…

Hardware issues and SIGNIFICANT OS upgrades to include near FULL-DISK ENCRYPTION.

 

But first:

Sandisk considers using their regular SD cards as unsuitable for the R-Pi and therefore does not warranty them for such use. They told me that for the R-Pi to use the “High Endurance” variety and those would be warrantied. Yeah – they cost more, but are made for high read/write applications like video cameras – and the Pi.

Get a good – GOOD power supply – Cigar-plug to USB (even if sold as 3+ amps) => Manufacturers are LIARS. Even my 110V PS for the Pi will sometimes indicate low power on boot-up (but I did get backlit peripherals, soooo…..) I can say that others who had problems with the previous procedure reported back that once they got a good PS that all went well.

Mice and Keyboards can drag power down especially when starting up and also if they are backlit. I’ve learned to start up with those unplugged and once up to then attach them, in order to avoid the dreaded lightning bolt indicating low power. Helps keep from corrupting the SD card.

I would also recommend that you set the /boot directory to read-only AFTER you have set up the Pi’s settings as you want. You do this through the “configure” window (or raspi-config from the CLI.) Just remember to unset it should you ever want to do an update/upgrade which may include system things then reset it afterwards. (However, once you’ve got the G6-Pi set up with everything working, why would you re-attach this to the internet?!? You will have just compromised the whole thing – it is no longer air-gapped.)

Other people on the net have indicated setting up a ramdisk specifically for collecting the Pi’s logfiles to prevent constant writes/rewrites and increase the longevity of the SD card. While we will be setting up a ramdisk for the G6-Pi, we won’t be including this particular application as this Pi is not a full-uptime system, instead only running for its designed purpose of creating CEOI/OTP related documents.

Turns out that Buster was less trouble than Stretch overall. It’s also 2 major OS versions newer.

The updated procedure for Raspberry OS – Buster, Lite, clean install:

——

sudo apt update

sudo apt upgrade

sudo apt dist-upgrade

sudo apt clean

sudo apt autoremove

sudo reboot

sudo apt install raspberrypi-ui-mods

sudo reboot

 

open a terminal window and run:

 

sudo apt install synaptic

sudo apt install leafpad

sudo apt install libgtk-3-dev

sudo apt install xclip

sudo apt install iceweasel

(It may just say it’s Firefox after you install it.)

 

cups and the hp printer were already installed in Buster

rng-tools already installed

 

sudo synaptic (or through the drop-down menu)

search for and install the following:

 

python-pip

libreoffice-writer

libreoffice-calc

python-gi-dev

gpa

 

for veracrypt to work you will need: libwxgtk3.0-gtk3-0v5 and libayatana-appindicator3-1

sudo dpkg -i “veracrypt filename”

(make sure you grab the right version – Debian 11 “Bullseye” no-worky for Buster

 

for Paranoiaworks software you will need: default-jre

programs are started from commandline with “java -jar (filename)”

getting an icon or into start menu is a pain – I just did a Bash script (whoda thought?)                                    and put that on my desktop.

 

–>

(Optional – may improve speed) – Install zram boot-up script:

⁃ “ sudo wget -O /usr/bin/zram.sh raw.githubusercontent.com/novaspirit/rpi_zram/master/\zram.sh “

⁃ “ sudo chmod +x /usr/bin/zram.sh “

⁃ “ sudo leafpad “

⁃ edit /etc/rc.local – add “ /usr/bin/zram.sh & “ at end but before “exit 0”

Save and reboot.

–>

 

next we’ll set up the new ramdisk:

 

sudo mkdir /ramdisk

sudo leafpad

 

( this will open up a graphical text editor with su privileges – remember you must be su to edit many configuration files like rc.local and fstab. ) – open /etc/fstab and add the following:

 

tmpfs /ramdisk tmpfs nodev,nosuid,size=64M 0 0

# tmpfs /ramdisk tmpfs nodev,nosuid,size=148M 0 0

# for the shuffler. If you really want to generate the codetable too, use 160M

 

save and close.

 

At the command line type:

 

sudo mount -a

 

This will mount the ramdisk right now. You can verify it mounted correctly by entering:

 

df -h

 

You should see a table with a bunch entries that should include one line that looks like:

 

tmpfs   64M     0          64M     0%       /ramdisk

 

There, now a ramdisk of the size you’ve specified will be set up every time you boot.

 

After a little bit more research I’ve come to the conclusion that setting the GPU RAM to 256M is…dumb, especially considering what we’re doing with this Pi. I’ve since set mine down to whatever it lets me that is 64M or higher (68M.) Not sure why 64 isn’t an option, but I don’t care that much.

As I had just done a clean install (well, minus some dumb things I did that isn’t worth mentioning…) I decided to try to encrypt the /root filesystem. After much searching I found one procedure that was fairly recent and complete enough for me that I would risk it. It is recent enough to apply to Buster (another good reason to NOT quickly adopt a new OS like Bullseye) and complete enough that I didn’t have to know too much – yay – as I don’t know practically anything about this but I CAN follow a recipe. The recipe is at https://rr-developer.github.io/LUKS-on-Raspberry-Pi/  .

It was mostly correct, except that the long command for the actual encrypting of the drive had an incorrect setting: instead of “-keysize” it should be “–key-size”  . Fortunately, when I entered the command it reported back what the problem setting was, and the recipe had a link to the manpage for the command so I could fix the problem with little trouble. Also, I had to use a SD card as the temporary drive for copying the filesystem back and forth, and not a thumbdrive as the Pi wouldn’t see it for some reason. Also, near the end of the procedure, where you type “exit” the first time, the Pi will reboot – apparently normally. It is after you shut it down to power off and then reboot that the shell comes up and you have to type the final stuff. After starting up cold the first time, I didn’t get anything resembling a prompt – it just sat there at the R-Pi logo screen. It happens after a soft-reboot too, like you would want. So you just type the password you gave when encrypting and hit enter as soon as the logo pops up and it’s good to go. I then checked the disk size in the file manager and it reported that I had 52.6 Gig free out of 58.3 Gig total. looks like it’s working. I then locked the /boot partition in the Pi’s configuration, rebooted, and it all still worked. yay. I then removed the SD card and plugged it into my laptop which still has an old version of linux (Mint 18.3.) /boot would open – but not /root. After entering the passphrase it reported back that it was an unsupported LUKS ver. 2 – It appears to be the system on the laptop is too old. I’ve been meaning to upgrade it. I tried it on another with Mint 20.2 and it was able to decrypt the drive just fine. Now I’ll be backing up an image of that SD card with dd so I don’t have to go through all this again when the card craps itself later.

Put it in another Linux machine. Under most circumstances, and if it’s the only SD card attached it will probably be /dev/mmcblk0 (note that if it’s got p1 or something like that after it. it is talking about the partitions on the card – we don’t want that, we want to reference the WHOLE card as a unit.) If you don’t know how to find out what the card is listed as, you will want to do a little research to figure it out. Assuming you do know (using “Disks” or some such other utility like that) the basic command would be “dd if=/dev/mmcblk0 of=~/G6PiCard.img” to put the clone of the SD card in your home directory. If you’re running old computer (and I would argue more secure from a hardware standpoint – maybe – but a topic for another day…) it will probably take a while. I’m using 64Gig Extreme Duty Sandisk cards. When done, the image registered as a hair under 60Gig. When compressed (as a tar.gz file) it was about 6.8 Gig. Before deleting the .img file I used Balena Etcher to burn another copy onto another SD card that was exactly the same. The important thing here is that it must be AT LEAST as big as the original. Just because they both say they’re 64 Gig (in this case) doesn’t mean they are the same. Different manufacturers measure it differently (for marketing purposes) and I have had the burning of images not work because the image copied from one 16Gig card was a few bytes more than the new 16 Gig card I was trying to burn from. How nice. So, I opt to use the exact same card for a backup. If you don’t make a backup/clone you’ll wish you had at some point. It’s relatively painless to make an image – once – and then burn it – once – then when (note that temporal term) your SD card fails because you (without thinking, of course) yanked the power cord from the Pi forgetting to “shutdown” first. (Ask me how I know.) Under normal circumstances this is bad ju-ju and can easily result in a corrupted file-system, something the Pi is infamous for. With an encrypted /root directory the chances are magnitudes higher for this problem. I keep my basic encrypted system with what is needed on it image-burned to another card (inserted in a larger SD card adapter) taped with electrical tape right to the case of the Pi. So, if “something” happens there is my backup ready to go instantly. Next chance I get after such an incident, I will burn another backup to replace the fubar’d card. MUCH easier than creating a new one from scratch, and quicker. Once is all it takes to learn this.

Now I just need to figure out a better monitor resolution configuration, (must unlock /boot) but that’s not your problem…So, on to the next thing.

As noted in the previous paper on CEOI Additions, I have found a new and more capable way of handling the ramdisk. While not really necessary for the majority of these scripts, it IS for anything dealing with the Code Books. A 64Meg ramdisk is more than enough for the Code Book scripts if you will not be using the 37-character versions below, but if you are, it will have to be bumped up to about 160Meg for the generator and 148 Meg for the shuffler – which is a lot on the Pi2. My recommendation is to leave it at 64 Meg, and if/when you do need more for the Code Book scripts, then do the edit to the /etc/fstab file for them, then re-edit back when done. (Don’t forget to reboot. There’s a command you could instead, but I can’t remember it without looking it up, and the Pi reboots fast anyway.) The simplest method is to have two lines in the fstab file, and just comment out the one you don’t need as required.

 

——-

On to the proposed 37-character OTP and Code Book…

I tend to wake up in the middle of the night and out of the dark recesses of that thing masquerading as a mind pops out things of questionable value, or maybe not, but seeing as it’s in my vacuum-chamber on top of C1 I can’t always give an honest evaluation, so I’ll put it out there for people to evaluate/ridicule, or secretly use when no-one is watching…A lot of times you look back on something you worked at and wonder, “what was I thinking? How did I miss that?” This may be one of those times.

One of the prime considerations when transmitting a message over the radio (for us anyway) is to keep the opposition from seeing, hearing and/or understanding us. We do this with a combination of a number of different methods:

  • We use as little power as needed.
  • We send faster, e.g., burst transmissions.
  • We use antennas designed to send a stronger signal in the direction we want, while sending a weaker signal in the other direction (or even none if we can.) This includes modifying polarization and the use of NVIS.
  • We obfuscate our message through encryption of some sort.

Needless to say, the other guy we’re sending to must be able to successfully copy our message, or what’s the point?

When it comes to sending digital, we have a bunch of options (if not many actual software choices.) Different modes have different strengths. Some like MT-63-2000 or MFSK64 can send up to or over 200 wpm but require a high bandwidth while providing different levels of error correction and then there are their propagation issues. On the other end would be voice dictating a message encrypted with a One Time Pad. Regardless of the method, a shorter message results in a shorter transmission for a given protocol. Note that there are some (or at least one) notable exceptions: e.g., JS-8Call. From the manual:

——->

…[i]n general, you can just type words and sentences and let the code compress it efficiently.

Now, there is a word suggestion feature that marks up your transmission text while you are typing your message (like a spell check). It will mark words that do not appear in the code dictionary (often, weird abbreviations), because counterintuitively, using a lot of abbreviations will often result in LESS efficient transmission.

Example:

Say we transmit “CONGRATULATIONS AND WELL WISHES FRIEND”. This compresses to 67 bits, for 20 words per minute and 1.76 bits per character (34 characters) in one transmit cycle.

But, let’s say you want to be clever and use some weird abbreviations to help it transmit faster… “CNGRATS ES WL WISHS FRND” has 10 fewer characters. but compresses to 122 bits, for 10 words per minute and 5.08 bits per character. That’s almost 2x the bits (and clearly IS 2x the number of transmit cycles)

 

——->

So, from this we can see that it might be quicker to send our OTP encrypted message with a space in between each character we transmit, as each letter or number would be in the dictionary, but 25343 or AJRLD would not be. It is good to pay attention to the mark-up. But I digress…(Just info for you to ponder.)

Our OTP systems seem to be either number only, or alphabet only. Considering that we were using these before the computer era, it isn’t surprising that we didn’t go beyond that, but why not now? I figured it’s not much trouble to combine the numbers and letters and corresponding OTP with my Raspberry Pi and its HWRNG. In fact, if I were so inclined, there would be nothing but good sense and sobriety from preventing me from making it 100 characters. But that would be…silly. Instead, I opted for adding just one more character, an *. (Turns out it wasn’t the best choice, but that’s because of some computer/linux issues that I had to work around among a few others.)

With a number-based OTP, we have to use 2 digits to encode everything except the most common 6 letters, plus use a solitary 0 to say “look at the codebook.”  If we want to send a number we have to signal it with a 2-digit code to turn it “on” and then again to turn it “off.” Even if we don’t triple the digits like we are supposed to, that could be a lot of overhead. With an alphabetic OTP we either spell out numbers and can’t use other symbols, or we have to use a “signal” (like QQ) to indicate a special encoding for numbers, codebook entries or something else. With all letters plus numbers and the *, we could use the * for the “signal” followed by a single letter or number to denote what special thing we want to convey. For example, *5 could mean a 5-character code from the codebook, *3 a 3-character code, *Q for a question, *S for a space (if you even really need it), and so on. For the code signals you could also have it mean “keep using that codebook until another * comes up.” (Note that this could be a problem if one of your codes begins with a *. To prevent that problem just use another code for the same word/phrase that doesn’t start with a *. You’ve got 1.8 million entries in the 37-character code book after all.) By having letters and numbers, along with a shortened signal system, that would reduce the overall size of the transmission. Plus we get to directly use the numbers without a special signal.

Those are the pros, now the cons.

It wouldn’t be as easy as using the numeric OTP. However, for the number-based OTP you would still need the correct CT chart unless you’ve got the whole thing memorized. (Quick – what’s the code for a parenthesis? Who cares? Has anyone ever used that in their OTPs???) If you’re using a reciprocal alphabet OTP (like DIANA) then maybe (MAYBE) you’ve done it enough that you don’t need the chart and have the 126 (125? I can’t remember…) codes memorized, so no chart needed there. If you’re using a Vigenere OTP now I’ll bet you really need the chart, and would like to slap the clown that sent you the message.

I think that the 37-character set would not be much more difficult, if at all, than using the 26-character OTP system. For the reciprocal, the size of the trigram set gets to be almost twice the size (247.) For Vigenere, it’s pretty much the same amount pain.

So, for those who would like to give it a shot I’ve taken away the biggest impediment to testing it out: I’ve incorporated it into the scripts previously put out for the Raspberry Pi. (You can run them on other Linux systems, just be aware of the issues of doing so as presented in the previous papers. Pay attention to the use of the ramdisk and its issues in regards to the CodeBook Generator scripts in particular.)

These are all drop-in replacements. I’ve included the basic OTP generator, the SplitOTP Generator (has ANYBODY given that one a shot? Bueller? Bueller?) and the Codebook Generator and Shuffler scripts just recently presented (a replacement for the Index Generator was not needed.) I did make some changes to the first two scripts eliminating the need for as many temporary files for copying and reduced the space required for the ramdisk, but as the size of a 37-character codebook is a little over 4x the size of a 26-character one, it still requires a substantial ramdisk. Note that you really, really do not want to generate the first codetable file on the Pi. Before you would have needed a 256Meg ramdisk to generate the initial Key but now that’s reduced to 148Meg, and it will still take a couple of days by my calculations. (As a comparison, I ran it on an old iMac with the latest Mint 20.2, 2000GHz dual-core w/4G ram. It took 13 hours, 20 minutes 54 seconds to generate the unscrambled and unshuffled code-table.) Use something else other than a Pi for generating the first codetable as recommended in the last paper (re: CEOI Additions.) The Shuffler script needs a really large ramdisk, but finishes in minutes on the Pi. I have also provided a short script that will generate a copy of a Vigenere chart, reciprocal chart, and trigram list for the 37-character set. The file “trigrams-37” also needs to be present in the same folder as SplitOTP-37.sh.

The scripts:

 

—————————————————————————————————–

 

 

PasswordGen.sh

 

 

#!/bin/bash

#

# Password Generator Program

#

# Have user pick algorithm to use for picking numbers or letters

read -p “Which RNG Device? hwrng-(1), urandom-(2) or random-(3). Default is 1 ” DEVICE

case $DEVICE in

3)

RNGAlg=random

;;

2)

RNGAlg=urandom

;;

*)

RNGAlg=hwrng

;;

esac

 

# This determines how many columns per line (period) of the PWs

read -p “How many passwords per period?” blockrow

 

# This determines how many Periods (rows) to print down the page

read -p “How many Periods? ” pagecount

 

# This determines how many characters in the Passwords

read -p “How many characters in passwords? Enter # or (r)andom (1-99). Default=16. Limit=99.” CHARACTERS

 

case $CHARACTERS in

[$(($CHARACTERS))]*)

blocksize=$CHARACTERS

;;

r*)

randnum=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c 2)

blocksize=$randnum

;;

*)

blocksize=16

;;

esac

if [ $blocksize -lt 1 ]

then

blocksize=16

fi

if [ $blocksize -gt 99 ]

then

blocksize=16

fi

 

read -p “Types of characters: (u)ppercase only, (l)owercase only, (b)oth cases, (n)umbers only, (ua/la/ba/)add numbers to letters, (h)exadecimal, (default ba).” TYPE

case $TYPE in

u)

KEY=’A-Z’

;;

l)

KEY=’a-z’

;;

b)

KEY=”‘A-Z”a-z'”

;;

n)

KEY=’0-9’

;;

ua)

KEY=”‘A-Z”0-9′”

;;

la)

KEY=”‘a-z”0-9′”

;;

h)

KEY=”‘A-F”0-9′”

;;

*)

KEY=”‘A-Z”a-z”0-9′”

;;

esac

 

read -p “Append underscore (_) to passwords? y or n(default).” UNDERSCORE

 

# where to generate the page of PWs – putting it in a ramdisk

PWpath=’/ramdisk/PW.txt’

 

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

#Un-remark these if you are using this script on a non-Pi (clear the #.)

# mkfs -q /dev/ram1 49152

# mkdir -p /ramdisk

# mount /dev/ram1 /ramdisk

 

echo

echo “$RNGAlg it is…”

echo

echo

echo ”                 grinding away…”

echo

# Generate a row of Callsigns

for ((x=1; x<=$pagecount; x++))

do

for ((y=1; y<=$blockrow; y++))

do

randnum=$(base64 /dev/$RNGAlg | tr -dc $KEY | head -c $blocksize)

echo -n $randnum >> $PWpath;

if [ $UNDERSCORE == y ]

then

echo -n “_” >> $PWpath

fi

if [ $y -lt $blockrow ]

then

echo -n ”     ” >> $PWpath

fi

done

echo “” >> $PWpath

echo “” >> $PWpath

done

# Send the table to X’s clipboard

xclip -i /ramdisk/PW.txt -sel clip

echo

echo “The Password table is now in X’s clipboard.”

echo

 

 

echo

# Prepare to erase the table from the ramdisk

read -p “Press (return) to delete the OTP table from the ramdisk…” dumpit

rm $PWpath

 

echo

echo “Don’t forget to clear X’s clipboard when you are done!!!”

 

 

 

—————————————————————————————————–

 

 

OTP-37.sh

————

 

 

#!/bin/bash

#

# One Time Pad Table Generator Programs

#

# These lines are alternative ways to pick characters. They are provided for testing

# by anyone interested. Just comment out the relevant line in the script and place the

# relevant one here in place of it. These are not placed above in a meager attempt to

# reduce execution speed.

# Note: the ‘tr’ command is a real drag on speed.

# Note: the ‘-i’ (alphaj flag for base32 and base64 includes digits. It is NOT

# alpha-only!

#  ORIGINAL PICKER HERE for both numbers and letters. Replaces the if-then-else routine.

#               randnum=$(base64 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

#    letters were selected -> converts lowercase letters to uppercase:

#               randnum=$(base64 /dev/$RNGAlg | tr -dc ‘A-z’ | tr [:lower:] [:upper:] | head -c $blocksize)

#    numbers were selected -> convert A-Y and a-y to digits

#    Note: range mapping of the base64 charset is different from that used by ‘tr’

#              randnum=$(base64 /dev/$RNGAlg | tr -dc ‘A-z’ | tr ‘A-E’ 0 | tr ‘F-J’ 1 | tr ‘K-O’ 2 | tr ‘P-T’ 3 | tr ‘U-Y’ 4 | tr ‘a-e’ 5 | tr ‘f-j’ 6 | tr ‘k-o’ 7 | tr ‘p-t’ 8 | tr ‘u-y’ 9 | tr -dc ‘0-9′ | head -c $blocksize)

 

 

# This determines how many characters per group in the OTPs

blocksize=5

 

# This determines how many groups per line of the OTPs

blockrow=5

 

# This determines how many OTPs across the page to print

read -p “How many pads across the paper? ” tablerow

 

# This determines how many lines of characters in each OTP

rowcount=10

 

# This determines how many rows of OTPs to print down the page

read -p “How many rows of pads? ” pagecount

 

#numbers or letters in the OTP?

read -p “OTP of numbers 0-9 (n), letters A-Z (l) or eXpanded-37 (x)? default = n ” NorL

#if [ $NorL == l ]

#then

#  TYPE=’A-Z’

#else

#  TYPE=’0-9′

#  read -p “Arabic numerals (a) or symbols [O\|/+A>V<X] (s)?” AorS

#fi

 

case $NorL in

x)

TYPE=”‘A-Z”0-9”+'”

;;

l)

TYPE=’A-Z’

;;

*)

TYPE=’0-9′

;;

esac

 

# Have user pick algorithm to use for picking numbers or letters

read -p “Which RNG Device? hwrng-(1), urandom-(2) or random-(3). Default is 1 ” DEVICE

case $DEVICE in

3)

RNGAlg=random

;;

2)

RNGAlg=urandom

;;

*)

RNGAlg=hwrng

;;

esac

 

# where to generate the page of OTPs – putting it in a ramdisk

otpath=’/ramdisk/otp.txt’

 

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

#Un-remark these if you are using this script on a non-Pi (clear the #.)

mkfs -q /dev/ram1 49152

mkdir -p /ramdisk

mount /dev/ram1 /ramdisk

 

echo

echo “$RNGAlg it is…”

echo

echo “Generating a Table of $tablerow by $pagecount of ($TYPE – type) OTPs.”

echo

echo ”                 grinding away…”

echo

 

# Reset BASH time counter

SECONDS=0

 

# Generate a row of OTPs

for ((x=1; x<=$pagecount; x++))

do

# Generate a full line of characters for eact OTP in the current row of OTPs

#  echo “” >> $otpath;

for ((i=1; i<=$rowcount; i++))

do

# Generate a row of groups for the current OTP in the current row of OTPs

for ((k=1; k<=$tablerow; k++))

do

# Generate the groups for the current line of groups in the current OTP

for ((j=1; j<=$blockrow; j++))

do

# Generate the current group of characters using the selected atributes

#    NOTE: using this if-then-else here instead of earlier in the script with two

#    longer generating branches results in an extra 2-seconds per OTP to generate with

#    hwrng, while reducing script length

case $NorL in

l)

randnum=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

;;

x)

randnum=$(base64 /dev/$RNGAlg | tr -dc $TYPE | tr ‘+’ ‘*’ | head -c $blocksize)

;;

*)

randnum=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

if [ $AorS == s ]

then

randnum=”$(echo $randnum | tr ‘0123456789’ ‘O\\|/+A>V<X’)”

# the first \ is required to make the second \ display – it is otherwise a special meaning chaacter

fi

;;

esac

 

#            if [ $NorL == l ]

#           then

#             randnum=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

#         else

#          if [ $NorL == x ]

#          then

#

#          randnum=$(base64 /dev/urandom | tr -dc $KEY | tr ‘+’ ‘*’ | head -c $blocksize)

#

#          else

#          randnum=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

#                      if [ $AorS == s ]

#                      then

#           randnum=”$(echo $randnum | tr ‘0123456789’ ‘O\\|/+A>V<X’)”

## the first \ is required to make the second \ display – it is otherwise a special meaning chaacter

#                                  fi

#                      fi

#           fi

echo -n $randnum >> $otpath;

echo -n ” ” >> $otpath;

done

echo -n ”   ” >> $otpath;

done

echo “” >> $otpath;

done

echo “” >> $otpath

echo “” >> $otpath

done

 

# Send the table to X’s clipboard

xclip -i /ramdisk/otp.txt -sel clip

echo

echo “The OTP table is now in X’s clipboard.”

echo

 

ELAPSED=”$(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec”

echo “Time taken to generate the OTP Table was $ELAPSED”

echo

 

# Prepare to erase the table from the ramdisk

read -p “Press (return) to delete the OTP table from the ramdisk…” dumpit

rm $otpath

echo

echo “Don’t forget to clear X’s clipboard when you are done!!!”

 

 

 

—————————————————————————————————–

 

 

SplitOTP-37.sh

—————–

 

#!/bin/bash

 

# One Time Pad Split Key Generator

 

# This determines how many characters per group in the OTPs

# held-over from OTP.sh – runs quicker there with the ‘head’ command ‘5’

blocksize=1

 

# This is the characters in a block

position=5

 

# This determines how many groups per line of the OTPs

blockrow=5

 

# This determines how many OTPs across the page to print

read -p “How many pads across the paper? ” tablerow

 

# This determines how many lines of characters in each OTP

rowcount=10

 

# This determines how many rows of OTPs to print down the page

read -p “How many rows of pads? ” pagecount

 

#numbers or letters in the OTP? Keeping in case of updating later.

read -p “OTP of numbers 0-9 (n), Vigenere A-Z (v), Reciprocal A-Z (r), Expanded-37 Vig (EV) or Expanded-37 Recip (ER)? default = n ” NorL

 

case $NorL in

v)

TYPE=’A-Z’

CLASS=”Alphabetic Vigenere”

NUM2LTR=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z )

declare -A LTR2NUM

LTR2NUM=([A]=0 [B]=1 [C]=2 [D]=3 [E]=4 [F]=5 [G]=6 [H]=7 [I]=8 [J]=9 [K]=10 [L]=11 [M]=12 [N]=13 [O]=14 [P]=15 [Q]=16 [R]=17 [S]=18 [T]=19 [U]=20 [V]=21 [W]=22 [X]=23 [Y]=24 [Z]=25)

RVRSLTTR=( Z Y X W V U T S R Q P O N M L K J I H G F E D C B A )

;;

r)

TYPE=’A-Z’

CLASS=”Alphabetic Reciprocal”

NUM2LTR=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z )

declare -A LTR2NUM

LTR2NUM=([A]=0 [B]=1 [C]=2 [D]=3 [E]=4 [F]=5 [G]=6 [H]=7 [I]=8 [J]=9 [K]=10 [L]=11 [M]=12 [N]=13 [O]=14 [P]=15 [Q]=16 [R]=17 [S]=18 [T]=19 [U]=20 [V]=21 [W]=22 [X]=23 [Y]=24 [Z]=25)

RVRSLTTR=( Z Y X W V U T S R Q P O N M L K J I H G F E D C B A )

;;

EV)

TYPE=”‘A-Z”0-9”+'”

CLASS=”Expanded-37 Vigenere”

NUM2LTR=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 + )

declare -A LTR2NUM

LTR2NUM=([A]=0 [B]=1 [C]=2 [D]=3 [E]=4 [F]=5 [G]=6 [H]=7 [I]=8 [J]=9 [K]=10 [L]=11 [M]=12 [N]=13 [O]=14 [P]=15 [Q]=16 [R]=17 [S]=18 [T]=19 [U]=20 [V]=21 [W]=22 [X]=23 [Y]=24 [Z]=25 [0]=26 [1]=27 [2]=28 [3]=29 [4]=30 [5]=31 [6]=32 [7]=33 [8]=34 [9]=35 [+]=36)

RVRSLTTR=( + 9 8 7 6 5 4 3 2 1 0 Z Y X W V U T S R Q P O N M L K J I H G F E D C B A )

;;

ER)

TYPE=”‘A-Z”0-9”+'”

CLASS=”Expanded-37 Reciprocal”

NUM2LTR=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 + )

declare -A LTR2NUM

LTR2NUM=([A]=0 [B]=1 [C]=2 [D]=3 [E]=4 [F]=5 [G]=6 [H]=7 [I]=8 [J]=9 [K]=10 [L]=11 [M]=12 [N]=13 [O]=14 [P]=15 [Q]=16 [R]=17 [S]=18 [T]=19 [U]=20 [V]=21 [W]=22 [X]=23 [Y]=24 [Z]=25 [0]=26 [1]=27 [2]=28 [3]=29 [4]=30 [5]=31 [6]=32 [7]=33 [8]=34 [9]=35 [+]=36)

RVRSLTTR=( + 9 8 7 6 5 4 3 2 1 0 Z Y X W V U T S R Q P O N M L K J I H G F E D C B A )

;;

*)

TYPE=’0-9′

read -p “Arabic numerals (a) or symbols [O\|/+A>V<X] (s)?” AorS

if [ $AorS == s ]

then

CLASS=”Symbol Replaced Numbers”

else

CLASS=”Numbers”

fi

;;

esac

 

# Have user pick algorithm to use for picking numbers or letters

read -p “Which RNG Device? hwrng-(1), urandom-(2) or random-(3). Default is 1 ” DEVICE

 

case $DEVICE in

3)

RNGAlg=random

;;

2)

RNGAlg=urandom

;;

*)

RNGAlg=hwrng

;;

esac

 

# where to generate the page of OTPs – putting them in a ramdisk

 

K1path=’/ramdisk/K1.txt’

K2path=’/ramdisk/K2.txt’

K3path=’/ramdisk/K3.txt’

K4path=’/ramdisk/K4.txt’

OTPath=’/ramdisk/OTP.txt’

EVERPath=’/ramdisk/EVERPath.txt’

 

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

 

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

#Un-remark these if you are using this script on a non-Pi (clear the #.)

# mkfs -q /dev/ram1 49152

# mkdir -p /ramdisk

# mount /dev/ram1 /ramdisk

 

echo

echo “$RNGAlg it is…”

echo

echo “Generating a Table of $tablerow by $pagecount of ($CLASS – type) OTPs.”

echo

echo ”                 grinding away…”

echo

 

# Reset BASH time counter

 

SECONDS=0

 

#K1 and K2 generated randomly, K3 and K4 derived from K1 & K2.

 

# Generate a row of OTPs

 

for ((x=1; x<=$pagecount; x++))

do

 

# Generate a full line of characters for each OTP in the current row of OTPs.

 

echo -n “” >> $K1path;

echo -n “” >> $K2path;

echo -n “” >> $K3path;

echo -n “” >> $K4path;

 

for ((i=1; i<=$rowcount; i++))

do

 

# Generate a row of groups for the current OTP in the current row of OTPs

 

for ((k=1; k<=$tablerow; k++))

do

 

# Generate the groups for the current line of groups in the current OTP

 

for ((j=1; j<=$blockrow; j++))

do

 

# Generate the groups for the current line of groups in the current OTP

 

for ((z=1; z<=$position; z++))

do

 

# Generate a single character

case $NorL in

  1. r)

randK1=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

randK2=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

drvdK3=”$(mawk -v f1=”$randK1″ -v s2=”$randK2″ -f sort-tri.awk trigrams)”

drvdK4=””

# There is no “Delta” for reverse-letter OTP – it would be identical to “Alpha”

;;

ER)

randK1=$(base64 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

randK2=$(base64 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

drvdK3=”$(mawk -v f1=”$randK1″ -v s2=”$randK2″ -f sort-tri.awk trigrams-37)”

drvdK4=””

# There is no “Delta” for reverse-letter OTP – it would be identical to “Alpha”

;;

v)

randK1=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

VigNum1=${LTR2NUM[$randK1]}

randK2=$(base32 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

VigNum2=${LTR2NUM[$randK2]}

VigNum3=$( expr $VigNum1 – $VigNum2 )

if [ $VigNum3 -lt 0 ]

then

(( VigNum3 += 26 ))

fi

drvdK3=${NUM2LTR[$VigNum3]}

VigNum4=$( expr $VigNum2 – $VigNum3 )

if [ $VigNum4 -lt 0 ]

then

(( VigNum4 += 26 ))

fi

drvdK4=${NUM2LTR[$VigNum4]}

;;

EV)

randK1=$(base64 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

VigNum1=${LTR2NUM[$randK1]}

randK2=$(base64 /dev/$RNGAlg | tr -dc $TYPE | head -c $blocksize)

VigNum2=${LTR2NUM[$randK2]}

VigNum3=$( expr $VigNum1 – $VigNum2 )

if [ $VigNum3 -lt 0 ]

then

(( VigNum3 += 37 ))

fi

drvdK3=${NUM2LTR[$VigNum3]}

VigNum4=$( expr $VigNum2 – $VigNum3 )

if [ $VigNum4 -lt 0 ]

then

(( VigNum4 += 37 ))

fi

drvdK4=${NUM2LTR[$VigNum4]}

;;

*)

randK1=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

randK2=$(xxd -p /dev/$RNGAlg | tr -dc [:digit:] | head -c $blocksize)

drvdK3=$( expr $randK1 – $randK2 )

if [ $drvdK3 -lt 0 ]

then

(( drvdK3 += 10 ))

fi

drvdK4=$( expr $randK2 – $drvdK3 )

if [ $drvdK4 -lt 0 ]

then

(( drvdK4 += 10 ))

fi

if [ $AorS == s ]

then

randK1=”$(echo $randK1 | tr ‘0123456789’ ‘O\\|/+A>V<X’)”

randK2=”$(echo $randK2 | tr ‘0123456789’ ‘O\\|/+A>V<X’)”

drvdK3=”$(echo $drvdK3 | tr ‘0123456789’ ‘O\\|/+A>V<X’)”

drvdK4=”$(echo $drvdK4 | tr ‘0123456789’ ‘O\\|/+A>V<X’)”

# the first \ is required to make the second \ display – it is a special meaning chaacter

fi

;;

esac

 

# Set first 5-character block of all 4 associated pads equal for use as a serial number

 

if [ $i = 1 ] && [ $j = 1 ]

then

randK2=$randK1

drvdK3=$randK1

drvdK4=$randK1

fi

 

echo -n $randK1 >> $K1path;

echo -n $randK2 >> $K2path;

echo -n $drvdK3 >> $K3path;

echo -n $drvdK4 >> $K4path;

done

 

echo -n ” ” >> $K1path;

echo -n ” ” >> $K2path;

echo -n ” ” >> $K3path;

echo -n ” ” >> $K4path;

 

done

 

echo -n ”   ” >> $K1path;

echo -n ”   ” >> $K2path;

echo -n ”   ” >> $K3path;

echo -n ”   ” >> $K4path;

done

 

echo “” >> $K1path;

echo “” >> $K2path;

echo “” >> $K3path;

echo “” >> $K4path;

done

 

echo “” >> $K1path;

echo “” >> $K2path;

echo “” >> $K3path;

echo “” >> $K4path;

echo “” >> $K1path;

echo “” >> $K2path;

echo “” >> $K3path;

echo “” >> $K4path;

done

 

# Send OTPs to X’s clipboard

echo “Alpha” >> $OTPath

cat $K1path >> $OTPath

echo “Beta” >> $OTPath

cat $K2path >> $OTPath

echo “Gamma” >> $OTPath

cat $K3path >> $OTPath

 

if [ $NorL == r ] || [ $NorL == ER ] || [ $NorL == EV ]

then

echo “no Delta table for Reciprocal OTPs”

else

echo “Delta” >> $OTPath

cat $K4path >> $OTPath

fi

 

if [ $NorL == EV ] || [ $NorL == ER ]

then

tr ‘+’ ‘*’ < $OTPath > $EVERPath

cat $EVERPath > $OTPath

fi

 

xclip -i /ramdisk/OTP.txt -sel clip

echo

 

#echo “The OTP table is now in X’s clipboard.”

echo

 

ELAPSED=”$(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec”

echo “Time taken to generate the OTP Table was $ELAPSED”

echo

 

# Prepare to erase the table from the ramdisk

read -p “Press (return) to delete the OTP table from the ramdisk…” dumpit

 

rm $K1path

rm $K2path

rm $K3path

rm $K4path

rm $OTPath

rm $EVERPath

 

echo

echo “Don’t forget to clear X’s clipboard when you are done!!!”

 

 

 

—————————————————————————————————–

 

 

Vig-Rec-ChartGen.sh

————————

 

#!/bin/bash

#

# Vigenere and Reciprocal Table Generator Program

# This generator creates a Vigenere and Reciprocal table with trigrams for a 37-character OTP.

#

 

NUM2LTR=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 + )

declare -A LTR2NUM

LTR2NUM=([A]=0 [B]=1 [C]=2 [D]=3 [E]=4 [F]=5 [G]=6 [H]=7 [I]=8 [J]=9 [K]=10 [L]=11 [M]=12 [N]=13 [O]=14 [P]=15 [Q]=16 [R]=17 [S]=18 [T]=19 [U]=20 [V]=21 [W]=22 [X]=23 [Y]=24 [Z]=25 [0]=26 [1]=27 [2]=28 [3]=29 [4]=30 [5]=31 [6]=32 [7]=33 [8]=34 [9]=35 [+]=36)

RVRSLTTR=( + 9 8 7 6 5 4 3 2 1 0 Z Y X W V U T S R Q P O N M L K J I H G F E D C B A )

 

read -p “(V)igenere or (R)eciprocal? ” VorR

case $VorR in

V)

# Print Column Header

echo -n ”    ” > V.txt

 

for ((COLHDR=0; $COLHDR<=36; COLHDR++))

do

echo -n ${NUM2LTR[$COLHDR]}” ” >> V.txt

done

echo “” >> V.txt

echo ”  —————————————————————————-” >> V.txt

 

for ((ROWHDR=0; $ROWHDR<=36; ROWHDR++))

do

echo -n ${NUM2LTR[$ROWHDR]}” | ” >> V.txt

for ((CODE=0; $CODE<=36; CODE++))

do

CODE1=$( expr “$ROWHDR” + “$CODE” )

if [ $CODE1 -gt 36 ]

then

CODE2=$( expr “$CODE1″ – 37 )

else

CODE2=$CODE1

fi

echo -n ${NUM2LTR[$CODE2]}” ” >> V.txt

done

echo “” >> V.txt

done

tr “+” “*” < V.txt > Vigenere.txt

rm V.txt

echo “Table is saved as Vigenere.txt.”

;;

R)

# Print Column Header

echo -n “” > R.txt

for ((COLHDR=0; $COLHDR<=36; COLHDR++))

do

echo -n ${NUM2LTR[$COLHDR]}”  ” >> R.txt

done

echo -n “” >> R.txt

echo “—————————————————————————————————————” >> R.txt

echo -n “” > TRIGRAM4.txt

for ((ROWHDR=0; $ROWHDR<=36; ROWHDR++))

do

for ((COLUMN=0; $COLUMN<=36; COLUMN++))

do

CODE1=$( expr “$ROWHDR” + “$COLUMN” )

if [ $CODE1 -gt 36 ]

then

CODE2=$( expr “$CODE1″ – 37 )

else

CODE2=$CODE1

fi

echo ${NUM2LTR[$COLUMN]} > TRIGRAM1.txt

echo -n ${NUM2LTR[$ROWHDR]} >> R.txt

echo ${NUM2LTR[$ROWHDR]} >> TRIGRAM1.txt

echo -n ${RVRSLTTR[$CODE2]}” ” >> R.txt

echo ${RVRSLTTR[$CODE2]} >> TRIGRAM1.txt

sort TRIGRAM1.txt > TRIGRAM2.txt

sort -r TRIGRAM2.txt | tr -d “\n” > TRIGRAM3.txt

echo “” >> TRIGRAM3.txt

cat TRIGRAM3.txt >> TRIGRAM4.txt

done

echo “” >> R.txt

done

sort TRIGRAM4.txt > TRIGRAM5.txt

sort -u TRIGRAM5.txt > TRIGRAM6.txt

tr “+” “*” < R.txt > Reciprocal.txt

tr “+” “*” < TRIGRAM6.txt > TRIGRAMS.txt

echo “Tables are saved as Reciprocal.txt and TRIGRAMS.txt”

rm TRIGRAM1.txt

rm TRIGRAM2.txt

rm TRIGRAM3.txt

rm TRIGRAM4.txt

rm TRIGRAM5.txt

rm TRIGRAM6.txt

rm R.txt

;;

*)

echo “Try again bonehead.”

;;

esac

 

 

 

 

 

 

 

 

 

 

—————————————————————————————————–

 

 

trigrams-37

————-

 

AA+

B++

BA9

BB8

C9+

CA8

CB7

CC6

D8+

D99

DA7

DB6

DC5

DD4

E7+

E98

EA6

EB5

EC4

ED3

EE2

F6+

F88

F97

FA5

FB4

FC3

FD2

FE1

FF0

G5+

G87

G96

GA4

GB3

GC2

GD1

GE0

H4+

H77

H86

H95

HA3

HB2

HC1

HD0

I3+

I76

I85

I94

IA2

IB1

IC0

J2+

J66

J75

J84

J93

JA1

JB0

K1+

K65

K74

K83

K92

KA0

L0+

L55

L64

L73

L82

L91

M54

M63

M72

M81

M90

MMM

N44

N53

N62

N71

N80

NML

NNK

O43

O52

O61

O70

OLL

OMK

ONJ

OOI

P33

P42

P51

P60

PLK

PMJ

PNI

POH

PPG

Q32

Q41

Q50

QKK

QLJ

QMI

QNH

QOG

QPF

QQE

R22

R31

R40

RKJ

RLI

RMH

RNG

ROF

RPE

RQD

RRC

S21

S30

SJJ

SKI

SLH

SMG

SNF

SOE

SPD

SQC

SRB

SSA

T11

T20

TJI

TKH

TLG

TMF

TNE

TOD

TPC

TQB

TRA

TS+

TT9

U10

UII

UJH

UKG

ULF

UME

UND

UOC

UPB

UQA

UR+

US9

UT8

UU7

V00

VIH

VJG

VKF

VLE

VMD

VNC

VOB

VPA

VQ+

VR9

VS8

VT7

VU6

VV5

WHH

WIG

WJF

WKE

WLD

WMC

WNB

WOA

WP+

WQ9

WR8

WS7

WT6

WU5

WV4

WW3

XHG

XIF

XJE

XKD

XLC

XMB

XNA

XO+

XP9

XQ8

XR7

XS6

XT5

XU4

XV3

XW2

XX1

YGG

YHF

YIE

YJD

YKC

YLB

YMA

YN+

YO9

YP8

YQ7

YR6

YS5

YT4

YU3

YV2

YW1

YX0

ZGF

ZHE

ZID

ZJC

ZKB

ZLA

ZM+

ZN9

ZO8

ZP7

ZQ6

ZR5

ZS4

ZT3

ZU2

ZV1

ZW0

ZYY

ZZX

 

—————————————————————————————————–

 

 

CodeTableGenerator-37.sh

——————————-

 

#!/bin/bash

#

# Codebook Key Generator with Mutilation Table

#

# Create a ramdisk to put the tables in to keep them in memory and not write to SD card

#Remark these if you are using this script on a Pi (Add a # to the beginning of each of the next 3 lines.)

mkfs -q /dev/ram1 151552

mkdir -p /ramdisk

mount /dev/ram1 /ramdisk

 

# where to generate the Tables – putting them in a ramdisk

CodeTable=’/ramdisk/CodeTable.txt’

OrderedCodeTable=’/ramdisk/OrderedCodeTable.txt’

PreSort2=’/ramdisk/PreSort2.txt’

MT=’/ramdisk/MT.txt’

MT2=’/ramdisk/MT2.txt’

 

echo -n “” > $OrderedCodeTable

echo -n “” > $PreSort2

echo -n “” > $MT

echo -n “” > $MT2

 

read -p “How many different characters/letters? 10/26/37 (Default=10.) ” CHAR

 

case $CHAR in

37)

SIZE=37

;;

5)

SIZE=5

;;

6)

SIZE=6

;;

9)

SIZE=9

;;

11)

SIZE=11

;;

12)

SIZE=12

;;

26)

SIZE=26

;;

*)

SIZE=10

;;

esac

 

# Determine if odd or even number of characters

if [ $(expr $SIZE % 2) != “0” ]

then

EVEN=0

else

EVEN=1

fi

 

OFFSET=0

read -p “Offset 3rd character? (# for offset) Must be less than # of characters. (Default is 0.) ” P3

case $P3 in

[$((P3))]*)

OFFSET=$P3

;;

*)

OFFSET=0

;;

esac

if [ $( expr $OFFSET ) -gt $( expr $SIZE – 1 ) ]

then

OFFSET=0

fi

 

# determine actual number of characters adjusted for odd/even required for mutilation table

S=$( expr $SIZE + $EVEN – 1 )

 

# Reset BASH time counter

SECONDS=0

 

for ((AColumn=0; AColumn<=$( expr $S ); AColumn++))

do

for ((ARow=0; ARow<=$( expr $S ); ARow++))

do

# determine value of poistion #1

A=$( expr $ARow + 0 )

 

B1=$( expr $A + $AColumn )

# determine value of position #2

if [ $( expr $B1 + 0 ) -gt $S ]

then

B=$( expr $B1 – $S – 1 )

else

B=$( expr $B1 + 0 )

fi

CRowCounter=0

while [ $( expr $CRowCounter + 0 ) -le $S ]

do

 

for (( Dc=0; Dc<=$( expr $S ); Dc++ ))

do

C1=$( expr $CRowCounter + $AColumn + $OFFSET )

if [ $( expr $C1 + 0 ) -gt $S ]

then

C2=$( expr $C1 – $S – 1 )

else

C2=$( expr $C1 )

fi

# Check it again as the CRowCounter + AColumn + OFFSET could send C1 >2x S

# determine value of position #3

if [ $( expr $C2 + 0 ) -gt $S ]

then

C=$( expr $C2 – $S – 1 )

else

C=$( expr $C2 )

fi

# determine value of position #4

D=$( expr $Dc + 0 )

# determine value of position #5

E=$( expr $D – $CRowCounter )

if [ $( expr $E + 0 ) -lt 0 ]

then

E=$( expr $E + $S + 1 )

fi

# print to screen to show its working

echo $A”-“$B”-“$C”-“$D”-“$E

 

At=$( expr $A ); Bt=$( expr $B ); Ct=$( expr $C ); Dt=$( expr $D ); Et=$( expr $E )

 

 

# if an even number of characters then check to see if it’s an invalid code (* in mutilation table.) If ok then add to codetable.

if [ $EVEN -eq 1 ] && [ $At != $S ] && [ $Bt != $S ] && [ $Ct != $S ] && [ $Dt != $S ] && [ $Et != $S ]

then

# Column 1 – the 5-character code and then the 4-character  code#

echo -n “@”$A”@@”$B”@@”$C”@@”$D”@@”$E”@,” >> $CodeTable

echo “@”$A”@@”$B”@@”$D”@@”$E”@” >> $CodeTable

else

# if an odd number of characters then add code to codetable

if [ $EVEN -eq 0 ]

then

echo -n “@”$A”@@”$B”@@”$C”@@”$D”@@”$E”@,” >> $CodeTable

echo “@”$A”@@”$B”@@”$D”@@”$E”@” >> $CodeTable

fi

fi

done

((CRowCounter++))

done

done

done

 

ELAPSED=”$(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec”

echo “Time taken to generate the CodeList was $ELAPSED”

echo

 

# NOTE: sed is flaky when trying to write back to the same file. Must use holding files.

 

if [ $SIZE -le 10 ]

then

echo “NOTE: This decision cannot be undone – ”

read -p “Will you be Scrambling the numerical-codes later? y/n (Default=y.) ” SCR

if [ $SCR != y ]

then

tr -d ‘@’ < $CodeTable > $PreSort2

rm $CodeTable

mv $PreSort2 $OrderedCodeTable

else

mv $CodeTable $OrderedCodeTable

fi

fi

 

if [ $SIZE -gt 10 ]

then

#          (convert to letters)

if [ $EVEN -eq 1 ]

then

sed “s:@[email protected]:*:g” $CodeTable > $PreSort2

cat $PreSort2 > $CodeTable

fi

sed ‘s:@[email protected]:*:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:j:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:i:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:h:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:g:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:f:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:e:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:d:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:c:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:b:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:a:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:Z:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:Y:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:X:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:W:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:V:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:U:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:T:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:S:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:R:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:Q:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:P:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:O:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:N:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:M:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:L:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:K:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:J:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:I:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:H:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:G:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:F:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:E:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:D:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:C:g’ $CodeTable > $PreSort2

sed ‘s:@[email protected]:B:g’ $PreSort2 > $CodeTable

sed ‘s:@[email protected]:A:g’ $CodeTable > $PreSort2

 

rm $CodeTable

mv $PreSort2 $OrderedCodeTable

 

fi

 

ELAPSED=”$(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec”

echo “Time taken to clean and sort the Code Table was $ELAPSED”

echo

 

# Time to Build the Mutilation Table

 

echo “” > $MT

 

# Upper-Left Table

 

for ((A=0; A<=$( expr $S ); A++))

do

for ((B1=0; B1<=$( expr $S ); B1++))

do

B2=$( expr $A + $B1 )

if [ $B2 -gt $S ]

then

B=$( expr $A + $B1 – $S – 1 )

else

B=$( expr $A + $B1 )

fi

echo -n “@”$A”@@”$B”@ ” >> $MT

done

echo “” >> $MT

done

echo “” >> $MT

 

# Bottom-Left Table

 

for ((j1=0; j1<=$( expr $S ); j1++))

do

for ((j2=$j1; j2<=$( expr $S + $j1 ); j2++))

do

if [ $j2 -gt $S ]

then

j3=$( expr $j2 – $S – 1 + $OFFSET )

else

j3=$( expr $j2 + $OFFSET )

fi

if [ $j3 -gt $S ]

then

j4=$( expr $j3 – $S – 1 )

else

j4=$( expr $j3 )

fi

echo -n ” @”$j4″@ ” >> $MT

done

echo -n ”   ” >> $MT

 

# Bottom-Right Table

 

row=$j1

 

for ((column=0; column<=$( expr $S ); column++))

do

X5=$( expr $column – $row )

if [ $X5 -lt 0 ]

then

X5=$( expr $X5 + $S + 1 )

fi

 

echo -n “@”$column”@@”$X5″@ ” >> $MT

done

echo “” >> $MT

done

 

# Convert Numbers to Letters

 

# NOTE: sed is flaky when trying to write back to the same file. Must use holding files.

 

# if 10 or less characters then use numerals

if [ $SIZE -le 10 ]

then

if [ $EVEN -eq 1 ]

then

sed “s:@[email protected]:*:g” $MT > $MT2

rm $MT

mv $MT2 $MT

fi

fi

# if >10 characters then use letters

if [ $SIZE -gt 10 ]

then

#          (convert to letters)

 

if [ $EVEN -eq 1 ]

then

sed “s:@[email protected]:*:g” $MT > $MT2

cat $MT2 > $MT

fi

sed ‘s:@[email protected]:*:g’ $MT > $MT2

sed ‘s:@[email protected]:j:g’ $MT2 > $MT

sed ‘s:@[email protected]:i:g’ $MT > $MT2

sed ‘s:@[email protected]:h:g’ $MT2 > $MT

sed ‘s:@[email protected]:g:g’ $MT > $MT2

sed ‘s:@[email protected]:f:g’ $MT2 > $MT

sed ‘s:@[email protected]:e:g’ $MT > $MT2

sed ‘s:@[email protected]:d:g’ $MT2 > $MT

sed ‘s:@[email protected]:c:g’ $MT > $MT2

sed ‘s:@[email protected]:b:g’ $MT2 > $MT

sed ‘s:@[email protected]:a:g’ $MT > $MT2

sed ‘s:@[email protected]:Z:g’ $MT2 > $MT

sed ‘s:@[email protected]:Y:g’ $MT > $MT2

sed ‘s:@[email protected]:X:g’ $MT2 > $MT

sed ‘s:@[email protected]:W:g’ $MT > $MT2

sed ‘s:@[email protected]:V:g’ $MT2 > $MT

sed ‘s:@[email protected]:U:g’ $MT > $MT2

sed ‘s:@[email protected]:T:g’ $MT2 > $MT

sed ‘s:@[email protected]:S:g’ $MT > $MT2

sed ‘s:@[email protected]:R:g’ $MT2 > $MT

sed ‘s:@[email protected]:Q:g’ $MT > $MT2

sed ‘s:@[email protected]:P:g’ $M