Skip to content

Instantly share code, notes, and snippets.

@GregTonoski
Last active October 9, 2023 13:07
Show Gist options
  • Save GregTonoski/3b081090e5fc1fd21470f699bb3054e6 to your computer and use it in GitHub Desktop.
Save GregTonoski/3b081090e5fc1fd21470f699bb3054e6 to your computer and use it in GitHub Desktop.
bxor.bash: bitwise exclusive OR (XOR) of two numbers represented in hexadecimal numerals
#!/bin/bash
# bxor.bash: bitwise exclusive OR (XOR) of two numbers represented in hexadecimal numerals. Result is padded with leading zeros if the number is smaller than 2**256.
# The script could be used to encrypt or decrypt (Vernam cipher).
# Examples:
# $ bash bxor.bash "000ffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139" "fedc09"
# $ for i in {1..8}; do printf "%08X" "$SRANDOM" >> b256random.key; done && bash ./bxor.bash 012345b $( < b256random.key )
# $ head -c 32 /dev/random >> b256random.key && bash ./bxor.bash $( head -c 32 plaindata.bin | basenc --base16 -w 0 ) $( basenc --base16 -w 0 < b256random.key )
# $ zsh bxor.bash "ffff" "011"
# $ sh bxor.bash "ffff" "011"
export LC_ALL=C
CHAR_COUNT1=${#1}
CHAR_COUNT2=${#2}
if [ "${CHAR_COUNT1}" -lt "${CHAR_COUNT2}" ]; then
SHORTER_INPUT_STRING="$1"
LONGER_INPUT_STRING="$2"
else
SHORTER_INPUT_STRING="$2"
LONGER_INPUT_STRING="$1"
char_count=${CHAR_COUNT2}
CHAR_COUNT2=${CHAR_COUNT1}
CHAR_COUNT1=${char_count}
fi
result=""
min_size_in_bits=256
count_of_bits_in_nibble=4
position=1
nibble=""
char_s=""
char_l=""
prefix_substring_s=${SHORTER_INPUT_STRING%?}
prefix_substring_l=${LONGER_INPUT_STRING%?}
while [ "${position}" -le "${CHAR_COUNT1}" ] ; do
char_s=$( printf "%c" "${SHORTER_INPUT_STRING##${prefix_substring_s}}" )
char_l=$( printf "%c" "${LONGER_INPUT_STRING##${prefix_substring_l}}" )
nibble=$( printf "%01X" $(( 0x${char_s} ^ 0x${char_l} )) )
result="${nibble}${result}"
prefix_substring_s=${prefix_substring_s%?}
prefix_substring_l=${prefix_substring_l%?}
position=$(( ${position} + 1 ))
done
while [ "${position}" -le "${CHAR_COUNT2}" ] ; do
char_l=$( printf "%c" "${LONGER_INPUT_STRING##${prefix_substring_l}}" )
nibble=$( printf "%01X" $(( 0x${char_l} )) )
result="${nibble}${result}"
prefix_substring_l=${prefix_substring_l%?}
position=$(( ${position} + 1 ))
done
while [ "${position}" -le $(( $min_size_in_bits / $count_of_bits_in_nibble )) ] ; do
result="0${result}"
position=$(( ${position} + 1 ))
done
echo "${result}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment