Skip to content

Instantly share code, notes, and snippets.

@gkthiruvathukal
Last active September 13, 2020 15:25
Show Gist options
  • Save gkthiruvathukal/b3eb1533322ef44473a527b1527128a3 to your computer and use it in GitHub Desktop.
Save gkthiruvathukal/b3eb1533322ef44473a527b1527128a3 to your computer and use it in GitHub Desktop.
#!/bin/bash
# This tries all rotations of Caesar cipher
# These are all parameters. I am going to make command line options to handle them.
# for now, however, you can just change them as needed.
# Parameters (options)
ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZ" # -a
WORDLIST=(`cat /usr/share/dict/words`) # -w
SENTENCES=25 # -s
MIN_SENTENCE_LENGTH=3 # -l
MAX_ADDL_SENTENCE_WORDS=25 # -h
while getopts ":a:w:s:l:" opt; do
case $opt in
a)
ALPHABET=$OPTARG
;;
w)
if [ -f "$OPTARG" ]; then
WORDLIST=`cat $OPTARG`
else
echo "$OPTARG does not exist; defaulting to /usr/share/dict/words"
fi
;;
s)
SENTENCES=$OPTARG
;;
l)
MIN_SENTENCE_LENGTH=$OPTARG
echo "Min sentence length set to $MIN_SENTENCE_LENGTH."
;;
h)
MAX_ADDL_SENTENCE_WORDS=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG"
exit 1
;;
:)
echo "Option -$OPTARG requires an argument."
exit 1
;;
esac
done
NUM_WORDS=${#WORDLIST[@]}
while read line; do
line_key=${#ALPHABET}
line_key_errors=$(echo "$line" | wc -w)
line_plaintext=""
for ((i=0; i < ${#ALPHABET}; i++)); do
SHIFT_VALUE=$i
CAESAR=${ALPHABET:$SHIFT_VALUE}${ALPHABET:0:$SHIFT_VALUE}
#echo "$line" | tr '[:lower:]' '[:upper:]' | tr -d '[:punct:]' | tr $CAESAR $ALPHABET
this_shift_errors=`echo "$line" | tr '[:lower:]' '[:upper:]' | tr -d '[:punct:]' | tr $CAESAR $ALPHABET | aspell list | wc -l`
#echo "shift $SHIFT_VALUE errors: $this_shift_errors"
if [ $this_shift_errors -lt $line_key_errors ]; then
line_key=$SHIFT_VALUE
line_key_errors=$this_shift_errors
line_plaintext=`echo "$line" | tr '[:lower:]' '[:upper:]' | tr -d '[:punct:]' | tr $CAESAR $ALPHABET`
fi
done
echo "{ key: $line_key, errors: $line_key_errors, plaintext: \"$line_plaintext\"" }
done
#!/bin/bash
# This tries all rotations of Caesar cipher
# These are all parameters. I am going to make command line options to handle them.
# for now, however, you can just change them as needed.
# Parameters (options)
ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZ" # -a
SENTENCES=25 # -s
MIN_SENTENCE_LENGTH=3 # -l
MAX_ADDL_SENTENCE_WORDS=25 # -h
WORDLIST=(`cat /usr/share/dict/words`) # -w ... note: You can use your own wordlist, but the words must spell correctly
while getopts ":a:w:s:l:p" opt; do
case $opt in
a)
ALPHABET=$OPTARG
;;
w)
if [ -f "$OPTARG" ]; then
WORDLIST=(`cat $OPTARG`)
fi
;;
s)
SENTENCES=$OPTARG
;;
l)
MIN_SENTENCE_LENGTH=$OPTARG
echo "Min sentence length set to $MIN_SENTENCE_LENGTH."
;;
h)
MAX_ADDL_SENTENCE_WORDS=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG"
exit 1
;;
:)
echo "Option -$OPTARG requires an argument."
exit 1
;;
esac
done
NUM_WORDS=${#WORDLIST[@]}
for ((i=0; i < $SENTENCES; i++))
do
# get random shift (the key)
while true; do
SHIFT_VALUE=$(($RANDOM % ${#ALPHABET}))
[[ $SHIFT_VALUE -eq 0 ]] || break
done
# Don't allow shift of 0, which is the same ALPHABET
if [ $SHIFT_VALUE -lt 0 ]; then
s=1
fi
# generate some words
SENTENCE_LENGTH=$(($MIN_SENTENCE_LENGTH + $RANDOM % $MAX_ADDL_SENTENCE_WORDS))
SENTENCE=""
C_SENTENCE=""
CAESAR=${ALPHABET:$SHIFT_VALUE}${ALPHABET:0:$SHIFT_VALUE}
for ((j=0; j < $SENTENCE_LENGTH; j++))
do
while true; do
RANDOM_WORD_POS=$(($RANDOM % $NUM_WORDS))
WORD=`echo ${WORDLIST[$RANDOM_WORD_POS]} | tr '[:lower:]' '[:upper:]'`
C_WORD=$(echo $WORD | tr $ALPHABET $CAESAR)
# For a word to be valid, every character must translate to a new character
# There are many non-ASCII characters in the English dictionary!
VALID_WORD=1
for ((k=0; k < ${#WORD}; k++))
do
if [ "${WORD:k:1}" == "${C_WORD:k:1}" ]; then
VALID_WORD=0
fi
done
# In addition, aspell seems to have a minor bug where sometimes words do not
# check correctly. So any word that does not encode to a spellable word is
# not emitted.
if [ $VALID_WORD -eq 1 ]; then
WORD_SPELLING_ERRORS=$(echo "$WORD" | aspell --ignore-case list | wc -l)
if [ $WORD_SPELLING_ERRORS -eq 0 ]; then
break
fi
fi
done
SENTENCE="$SENTENCE ${WORD}"
C_SENTENCE="$C_SENTENCE ${C_WORD}"
done
SENTENCE=${SENTENCE:1}
C_SENTENCE=${C_SENTENCE:1}
echo $C_SENTENCE
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment