33. Back to basics: Base 256

Note
some of this material comes from how to obscure a URL (http://www.pc-help.org/obscure.htm).

The maximum ibase for bc is 16; the maximum obase is 256. Since we don't have an agreed upon ordered set of 256 symbols, bc outputs base 256 numbers in decimal, separated by spaces.

echo "obase=256; ibase=2;  10000000" | bc
 128
echo "obase=256; ibase=2;  11111111" | bc
 255
echo "obase=256; ibase=2;  100000000" | bc
 001 000

echo "obase=256; ibase=10;  256" | bc
 001 000
echo "obase=256; ibase=10;  256*16" | bc
 016 000
echo "obase=256; ibase=10;  256*256" | bc
 001 000 000

echo "obase=256; ibase=16;  100" | bc
 001 000
echo "obase=256; ibase=16;  400" | bc
 004 000
echo "obase=256; ibase=16;  1000" | bc
 016 000
echo "obase=256; ibase=16;  F000" | bc
 240 000
echo "obase=256; ibase=16;  FFFF" | bc
 255 255
echo "obase=256; ibase=16;  10000" | bc
 001 000 000

Computers linked by a network are identified by a unique unsigned 32 bit number (called an IP). The IP on your machine can be seen in base 256 by running the command ifconfig (unix, cygwin) (or possibly /sbin/ifconfig) or ipconfig (windows). The IP for the machine I use to write these class notes (in base 256 notation) is 192.168.1.3. The notation is called "dotted quad" (4 numbers separated by dots).

dennis:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:A0:CC:56:9B:6A  
	  inet addr:192.168.1.3  Bcast:192.168.1.255  Mask:255.255.255.0
	  UP BROADCAST RUNNING ALLMULTI MULTICAST  MTU:1500  Metric:1
	  RX packets:21532458 errors:1 dropped:0 overruns:0 frame:0
	  TX packets:15254713 errors:4 dropped:0 overruns:0 carrier:4
	  collisions:0 txqueuelen:1000 
	  RX bytes:3417783082 (3259.4 Mb)  TX bytes:3357752091 (3202.2 Mb)
	  Interrupt:11 Base address:0xdc00 

The base 256 notation is easier for humans to use than a 32-bit number particularly since on any network the first 3 base 256 numbers don't change (in this example 192.168.1, only the last number is different for each computer). What is the decimal value for this IP (192.168.1.3) [370] ?

The IP for a fixed machine will be assigned by a sysadmin from free addresses on the network. Machines that connect only now and again and at different places (e.g. laptops) are given a temporary IP from a small pool by a machine already on the network (called a dhcp server). In dhcp language, the laptop is "leasing" the IP. Since the dhcp server doesn't know when the laptop will disconnect, the laptop is given the lease for only a short time (5-30mins) and has to renew its lease by the end of the lease period or loose its connection to the network. Users are not and need not be aware of any of this. Users just connect the ethernet cable to their ethernet card, or plug in their wifi card and programs already installed on the laptop handle everything else.

Find the IP on your machine. Then remove your wifi card (on windows you'll have to tell the machine that you're about to pull the card) and see that you loose that IP. Plug the wifi card back in and see that you get an IP back (probably the same one).

The notes for this class are being served by a machine with IP=192.168.2.254. You surf to this IP by using a name rather than a base 256 number (easier for humans). In this case the name is router.masp.net, a name that's only known privately on my network. The translation between names and IP numbers is done by the computer equivalent of a phone book (called DNS). Check that you can get to the class notes at http://router.masp.net/python_class/ and http://192.168.2.254/python_class/

What's the decimal equivalent of the base 256 number 192.168.2.254 [371] ?

Hexadecimal will require twice as many digits as base 256. What's the hexadecimal equivalent of the base 256 number 192.168.2.254 [372] ?

In earlier times, web browsers were quite happy to surf to http://3232236286/, but most don't allow it anymore to stop phishing (IEv5 did it). Still the decimal number is a valid IP. Try ping'ing the IP using some different formats for the IP.

ping router.masp.net
PING router.masp.net (192.168.2.254): 56 octets data
64 octets from 192.168.2.254: icmp_seq=0 ttl=64 time=2.1 ms

ping 192.168.2.254
PING 192.168.2.254 (192.168.2.254): 56 octets data
64 octets from 192.168.2.254: icmp_seq=0 ttl=64 time=2.2 ms

ping 3232236286 
PING 3232236286 (192.168.2.254): 56 octets data
64 octets from 192.168.2.254: icmp_seq=0 ttl=64 time=2.4 ms

Not everything is as you might expect. Here's the IP in hexadecimal

echo "obase=16; ibase=10;  192*256*256*256 + 168*256*256 + 2*256 +254" | bc
C0A802FE

Seeing that the decimal version works, a reasonable person might expect that some of these would work.

ping C0A802FE
ping: unknown host C0A802FE

ping 0xC0A802FE
ping: unknown host 0xC0A802FE

ping 0xC0.0xA8.0x02.0xFE
ping: unknown host 0xC0.0xA8.0x02.0xFE

These might have worked some time in the past, but it seems that code writers have trapped any attempts to use addresses that are more than 32 bits. You might think that the numbers beyond 32 bits would overflow and the remainder be used as the real address, but the numbers are all recognised as being invalid.

#ping an address more than 32 bits
ping 1.192.168.2.254
ping: unknown host 1.192.168.2.254

#calculate an address that's 1 base 256 digit more than a known IP address
#since hex adddresses don't work for ping, you wouldn't expect much success
echo "obase=16; ibase=10;  1*256*256*256*256+ 192*256*256*256 + 168*256*256 + 2*256 +254" | bc
1C0A802FE
ping 1C0A802FE
ping: unknown host 1C0A802FE

#try it in decimal; this at least works for a valid IP.
echo "obase=10; ibase=10;  1*256*256*256*256+ 192*256*256*256 + 168*256*256 + 2*256 +254" | bc
7527203582
ping 7527203582
ping: unknown host 7527203582

Find the IP of your machine, ping that IP (in dotted quad format), then ping the IP in decimal format. Convert the decimal IP back to dotted quad format [373]



[370] root@routera:/scratch# echo "obase=10; ibase=10; 192*256*256*256 + 168*256*256 + 1*256 +3" | bc 3232235779

[371]

echo "obase=10; ibase=10;  192*256*256*256 + 168*256*256 + 2*256 +254" | bc
3232236286

[372]

echo "obase=16; ibase=10;  192*256*256*256 + 168*256*256 + 2*256 +254" | bc
C0A802FE

[373] If your IP is 10.1.2.7

echo "obase=10; ibase=10;  10*256*256*256 + 1*256*256 + 2*256 +7" | bc
167838215

ping 10.1.2.7

ping 167838215

echo "obase=256; ibase=10; 167838215" | bc
010 001 002 007