grimoire/bash/vigenere

61 lines
1.3 KiB
Bash
Executable file

#!/usr/bin/env bash
numeric() {
printf %d "$(( $(printf %d \'"${1,}") - $(printf %d \'a) ))"
}
vigenere_enc() {
local key=$1 plain=$2 idx {plain,key}_pos incr offset
for (( idx = 0; idx < ${#plain}; idx += 1 )); do
if [[ ${plain:idx:1} = [[:alpha:]] ]]; then
plain_pos=$(numeric "${plain:idx:1}")
key_pos=$(numeric "${key:0:1}")
if [[ ${plain:idx:1} = [[:lower:]] ]]; then
offset=97
else
offset=65
fi
(( incr = ((plain_pos + key_pos) % 26) + offset ))
printf \\"$(printf %03o "$incr")"
key=${key:1}${key:0:1}
else
printf %c "${plain:idx:1}"
fi
done
printf "\n"
}
vigenere_dec() {
local key=$1 enc=$2 idx {enc,key}_pos decr offset
for (( idx = 0; idx < ${#enc}; idx += 1 )); do
if [[ ${enc:idx:1} = [[:alpha:]] ]]; then
enc_pos=$(numeric "${enc:idx:1}")
key_pos=$(numeric "${key:0:1}")
if [[ ${enc:idx:1} = [[:lower:]] ]]; then
offset=97
else
offset=65
fi
(( decr = ((enc_pos - key_pos + 26) % 26) + offset ))
printf \\"$(printf %03o "$decr")"
key=${key:1}${key:0:1}
else
printf %c "${enc:idx:1}"
fi
done
printf "\n"
}
if [[ -n $1 && encrypt = $1* ]]; then
vigenere_enc "$2" "$3"
elif [[ -n $1 && decrypt = $1* ]]; then
vigenere_dec "$2" "$3"
fi