String En/Decoding

In a project I was working on, I needed to hand over a couple of parameters to another script running on a different machine on the network behind a firewall. Copying a file or opening a socket was not an option.

I decided to use a simple encoding scheme for all the information, so the executing shell wouldn't trip over possible spaces in the parameter.

Since my script had to run on a UNIX box where perl might not be an option, I had to stay simple korn shell. I only use the UNIX commands echo, bc, od, tr and awk.

I am sure that this could be much more obfuscated, eg. loosing the tr and only using sed, but this works, is reasonably elegant and I can move on.

updated 03/11/2005: moved on too quickly. /usr/bin/od on different CPU architectures behaves differently, namely swapping the bytes. So on x86 the byte-order of every pair needs to be reversed.

#!/bin/env bash

die () { echo -e "$1";exit}  

encode () {
    # translate argument into hex, tr to uppercase and remove leading numbers
    # diffrent HW archs have different MSN/LSN order (uname -m)
    echo "$1"|/usr/bin/od -x|tr "[:lower:]" "[:upper:]"|sed -e 's/^[0-9]\{7\}//;s/^ //;/^[ ]*$/d' | \
    { case $(uname -m) in
        *86*) sed -e 's/^ //;/^[ ]*$/d;s/\([A-z,0-9][A-z,0-9]\)\([A-z,0-9][A-z,0-9]\)/\2\1/g' ;;
        *) cat;;
    esac; } | tr -d '\n '
}

decode () {
    echo -e "ibase=16;$(echo "$1"|sed -e 's/[A-z,0-9][A-z,0-9]/\\n&/g;s/^ //')"|\
    bc|\
    awk '{printf("%c",$0)}'
}

[ $(command -v bc 2>/dev/null) ] || die "command bc does not exist";

TEXT=${1:-this is a test}

echo "CLEAR   = ${TEXT}"
ENCODED=$(encode "${TEXT}");
echo "ENCODED = $ENCODED"
DECODED=$(decode "$ENCODED");
echo "DECODED = ${DECODED}"