bashxor

XOR command fails


I am trying to create an One Time Pad for cryptography, But I am stuck in an error

The plan is

#!/bin/bash

#Create Message #1
plaintext=`cat /dev/urandom | tr -dc 0-9 | head -c8`
sleep 1

#Generate Random Sequence
key=`cat /dev/urandom | tr -dc 0-9 | head -c8`

#Ascii to Binary Convertion
key_bin=$(echo $key | perl -lpe '$_=unpack"B*"')

plaintext_bin=$(echo $plaintext | perl -lpe '$_=unpack"B*"')

plaintext_bin_size=${#plaintext_bin}

key_bin_size=${#key_bin}


    for ((i=0; i < $plaintext_bin_size; i++)); do
        byte=$((${plaintext_bin[$i]} ^ ${key_bin[$i % $key_bin_size]}))

        cipher="$cipher($byte)"
    done

    echo -e "$cipher"

But I get syntax error: operand expected (error token is "^ ")


Solution

  • Focusing solely on the syntax error ...

    As mentioned in comments, ${variable[...]} is an array reference but your variables are not arrays. Net result is you're trying to access array entries that do not exist, ie, you're trying to run an xor / ^ operation against blank fields. We can generate the same error with:

    $ echo $((   ^   ))
    -bash: ^ : syntax error: operand expected (error token is "^ ")
    

    Assuming the intention is to access the individual digits/positions of the values stored in a variable try ${variable:start:length}, eg:

    $ x=123456
    
    $ echo "${x:0:1}"      # start at 0th position for length of 1
    1
    
    $ echo "${x:2:2}"      # start at 2nd position for length of 2
    34
    

    Pulling this into the current code:

    byte=$(( ${plaintext_bin:i:1} ^ ${key_bin:((i % key_bin_size)):1} ))
    
    ### the embedded ((..)) are redundant so this also works:
    
    byte=$(( ${plaintext_bin:i:1} ^ ${key_bin:i % key_bin_size:1} ))