Don Marti
Tue 23 Dec 2008 10:26:43 AM PST
dotted quad to decimal in bash
(updated 24 December 2008: Seth's functions, int2dq.)
GNU seq doesn't accept dotted quads for ranges, but fortunately most of the commands that accept an IP address will also take it in the form of a regular decimal. (Spammers used to use this to hide their naughty domains from scanners that only looked for the dotted quad while the browser would happily go to http://3232235520/barely-legal-mortgage-replicas.html or something.)
So here's an ugly-ass shell function to convert an IP address to a decimal. If you have a better one, please let me know and I'll update this page. (Yes, I know this would be one line in Perl.)
dq2int()
{
if [ $(echo $1 | grep -q '\.') ]; then
dq2int $(echo $1 | tr '.' ' ')
elif [ $# -eq 1 ]; then
echo $1
else
total=$1; next=$2; shift 2
dq2int $(($total*2**8+$next)) $@
fi
}
Seth David Schoen has two shorter versions, using interation instead of recursion.
dq2int(){
a=0
for b in $(echo $1 | tr . ' '); do
a=$((256*$a+$b))
done
echo $a
}
dq2int(){
a=0
for b in ${1//./ }; do
a=$((256*$a+$b))
done
echo $a
}
And if you want to go the other way, Seth points out that you can set the "obase" variable for bc. Here's an int2dq function based on that idea.
int2dq()
{
{ echo obase=256; echo $1; } | \
bc | tr ' ' . | cut -c2-
}
(To quote the bc manual, "For bases greater than 16, bc uses a multi-character digit method of printing the numbers where each higher base digit is printed as a base 10 number." Trick.)