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}"