Convert a Hex Address to an IP Address
Recently I have been using a proprietary application which stores IP address in a hex notation. Unfortunately this hex address is far from useful when doing troubleshooting or diagnosing. Originally I was told to pull each two hex digits and convert them via the calculator of my operating system. This was very manual and annoying to say the least. I decided to write a short script with the limited tools available on the machine I had to use for this purpose. While I am sure there would be a more elegant way of doing this, it gets the job done.
The script first converts the hex address to all upper-case (using 'tr' tool), as the 'bc' tool didn't like lowercase letters. The script next calculates each octet of the IP address, much like the manual method I was doing before. Finally, the script does some diagnostic tests (whois and nslookup) against the resulting IP address, which are useful for further research.
#!/bin/sh
#
# Convert hex to be uppercase for bc to accept it.
#
IN=`echo $1 | tr "[:lower:]" "[:upper:]" `
#
# Begin converting each octet
#
IN1=`echo $IN| sed 's/^\(..\).*/ibase=16;\1/'|bc`
IN2=`echo $IN| sed 's/^..\(..\).*/ibase=16;\1/'|bc`
IN3=`echo $IN| sed 's/^....\(..\).*/ibase=16;\1/'|bc`
IN4=`echo $IN| sed 's/^......\(..\)/ibase=16;\1/'|bc`
#
# Begin gathering info on the resulting IP.
#
whois "$IN1.$IN2.$IN3.$IN4"
echo "IP Address = $IN1.$IN2.$IN3.$IN4"
nslookup "$IN1.$IN2.$IN3.$IN4" 4.2.2.1

1 comment
A number of other approaches...
First, there's the Bash one-liner approach with AWK:
/bin/echo -n 'f7E45678' | sed 's/\(..\)/0x\1\n/g' | awk '{printf( "%hu.", $1)}' | sed 's/\.$/\n/'or without AWK:
for i in $(/bin/echo -n 'f7E45678' | sed 's/\(..\)/0x\1 /g'); do printf "%hu." $i; done | sed 's/\.$/\n/'As you can see above, Bash actually has some built-in capability to interpret hex. For example:
echo $[0xf7].$[0xE4].$[0x56].$[0x78]works like a charm when typed, but none of backticking, expr'ing, ()'ing, (())'ing, nor even eval'ing seems to suffice to force Bash to interpret $[] constructs when generated via script. This actually led me to come up with (IMHO) a very clean solution:
echo "$[0x${1:0:2}].$[0x${1:2:2}].$[0x${1:4:2}].$[0x${1:6:2}]"Alternatively, then, we must give some time to consideration of the silly approach:
ping -c 1 -w 1 0xf7E45678 | head -n 1 | awk '{print $3}' | sed 's/[()]//g'Lastly, I would be remiss if I didn't mention the Perl approach, but I was unsure if it was acceptable given that you said your choice of tools on the machine was limited:
perl -e 'print join(".",unpack("C*",pack("H*",$ARGV[0]))) . "\n";' f7E45678There's probably an easier way to do that in Perl, but my code is certainly one option.
Regards,
Dan
Senior Network Engineer
BlackMesh Managed Hosting