---

blog: Don Marti

---

dotted quad to decimal in bash

24 December 2008

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.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 Schoen has two shorter versions:

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 GNU 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.