Last active
October 9, 2023 13:07
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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