18 October 2010

Base Conversions

Every now and then, it may be necessary to do base conversions on numbers.
While some may be readily able to read 0x17 in hexadecimal as 23 in
decimal as 10111 in binary as 27 in octal, there are those who may not.
A simple example of how this information may be of use would be in

figuring out an interface's netmask from ifconfig's output.  In this
output, the netmask is printed in hexadecimal:

    FreeBSD:
    bsdbox [0] ifconfig vlan371
    vlan371: flags=8843 mtu 1500
                inet 7.7.6.52 netmask 0xffffff00 broadcast 7.7.6.255
                ether 00:11:43:59:86:ac


    Solaris:
    sunbox [0] ifconfig bge0
    bge0: flags=1000843 mtu 1500 index 2
                inet 7.7.6.213 netmask ffffff00 broadcast 7.7.6.255
                ether 0:3:ba:d8:98:54

In the above output, the netmask in both cases is 255.255.255.0, however
I know this because I've seen it enough times and I know "ff" in hex is
255 and 00 is 0.  It would be nice though not to have to remember these
conversions, instead having a means of providing this information.
What if the netmask had been instead, ffffffC0 (hint: its binary form
would be 11111111.11111111.11111111.11000000)?  The following will provide
examples of base conversions for binary, octal, hexadecimal, and decimal.
These examples utilize bc to perform the conversions which should be
available on any standard UNIX.  Of note, obase is the output base,
ibase is the input base, base 2 is binary, base A is decimal, base 16
is hexadecimal, and base 8 is octal.

     binary to decimal:
                unixbox [0] echo "obase=A;ibase=2;11010" | /usr/bin/bc
                26

     binary to hexadecimal:
                unixbox [0] echo "obase=16;ibase=2;11010" | /usr/bin/bc
                1A

     binary to octal:
                unixbox [0] echo "obase=8;ibase=2;11010" | /usr/bin/bc
                32

     decimal to binary:
                unixbox [0] echo "obase=2;ibase=A;26" | /usr/bin/bc
                11010

     decimal to hexadecimal:
                unixbox [0] echo "obase=16;ibase=A;26" | /usr/bin/bc
                1A

     decimal to octal:
                unixbox [0] echo "obase=8;ibase=A;26" | /usr/bin/bc
                32

     hexadecimal to binary:
                unixbox [0] echo "obase=2;ibase=16;1A" | /usr/bin/bc
                11010

     hexadecimal to decimal:
                unixbox [0] echo "obase=A;ibase=16;1A" | /usr/bin/bc
                26

     hexadecimal to octal:
                unixbox [0] echo "obase=8;ibase=16;1A" | /usr/bin/bc
                32

     octal to binary:
                unixbox [0] echo "obase=2;ibase=8;32" | /usr/bin/bc
                11010

     octal to decimal:
                unixbox [0] echo "obase=A;ibase=8;32" | /usr/bin/bc
                26

     octal to hexadecimal:
                unixbox [0] echo "obase=16;ibase=8;32" | /usr/bin/bc
                1A

see also:
    basecon.pl on the Tools page for handling of base conversions.