Robert's Virtual Networking | east82.com |
"There are 10 kinds of people in the world ...those who understand binary and those who do not"
There are four basic numbering systems that are used in the human, networking, and computer science worlds. Binary, octal, decimal and hexadecimal. Decimal, the numbering system we are most familiar with has a base, or radix, of 10 and to us this is natural. Why 10? Most of us have 10 fingers and that is how it was selected as our numbering system; it's as simple as that. The Yuki people of California on the other hand (pun intended) use an octal numbering system, counting the spaces between their fingers and not the fingers themselves. Pretty cool, huh?
The other systems widely in use in the
networking and computer science world are binary, octal and
hexadecimal (See table below). In this tutorial we'll concern
ourselves only with binary, decimal and hexadecimal, ignoring octal
altogether. As a side note, one use of octal numbering is with Linux
and UNIX systems to set file permissions using the chmod command.
Yes, we're talking binary here. I start here by asking that you don't think of a binary number as being a just series of 1's and 0's, such as 01000001 (65 decimal), but rather as a valid numbering system. So, why binary and not decimal? Take our previous example of 01000001. It's really a sort of computer Morse code, but instead of dots and dashes, it's the presence or absence of state, on or off; whether it be electrical pulses on an Cat5 cable or the state of transistors within a CPU or memory stick. Individually a bit, that is a 1 or 0, is pretty useless. However, put them together in a byte (8 bits) for example, then you have something. With our previous example, the byte 01000001 represents the character 'A'. With the computer's ability to process and transmit millions of bytes in miliseconds it can give us letters, words, pictures, music, videos and oodles of other things almost instantly. No matter what we type or create via keyboard or mouse, eventually it all gets translated into a numerical series of 1's and 0's to represent our intent. So, you see it IS all just 1's and 0's! Oh, I almost forgot ...a nibble is half a byte, 4 bits.
With the decimal numbering system we have 10 digits to work with, 0 thru 9 and when we count we start at 0, then 1, then 2 and so on until we reach 9. Then what? Well, we've run out of digits. So, we start again at 0, but we place a 1 to the left giving us 10 (ten). And once the 1's and 10's columns reach 9 and 9 (99) they both flip, giving us 100. Same thing goes with binary except we only have 2 digits to work with, 1 and 0.
The principal is the same we start at 0 then 1, then ...well, we've run out of digits haven't we? So, we flip that 1 to 0 and place a 1 to the left giving us 10 (two). Increment by 1 again and we have 11 (three) and once again they both flip and we move into a new column giving us 100 (four). This is probably not so bad for small numbers, but once you get past 8 or so binary digits it becomes unmanageable. I mean what does 10011100 equate to in human terms? Don't even mention that binary numbers are unwieldy; 3,000 is 101110111000 in binary ...geez! So, while it is true that we need to think in binary, we can represent these binary numbers in a more human friendly form. Anyone say decimal? Fortunately we have the ability (and absolute need) to convert between the two.
For this section I'll start by examining and
explaining the table below.
First thing to take note of is that there are 8 individual bits giving us a byte. When working with IP addresses, networking folks refer to this as an octet. Obviously, binary numbers can be larger than a simple byte. However, the byte is the most basic representation of data and as such, for the most part, we'll stay at the byte level.
The 'Bit Set' row is for our binary digits, either 0 or 1. Here they are all 1.
The 'Exponent Value' row is how we arrive mathematically at the 'Decimal Value' row. An exponential value such as 2^{3} means 2 x 2 x 2 = 8. By the way, any number with an exponent of 0 ALWAYS equates to 1 (2^{0 }= 1 and 400^{0} also = 1).
The 'Decimal Value' row represents positionally the decimal value of the binary digit in question. It's imperative that you commit this row to memory. Practice by writing it down over and over 'till its part of your DNA :-)
The labels 'MSB' and 'LSB' stand for 'Most Significant Bit' and 'Least Significant Bit' respectively. This lets us know which end of the binary number we are talking about. For example, if I had a binary number of 11010101 and I say 'Starting at bit 1' ...that might be confusing. However, if I say 'Starting with the bit at LSB 1'. Well, you get the picture.
Previously we talked about thinking in binary means knowing how to count in binary and that still holds valid, but now, in order to convert between the two, we are going to only concern ourselves with the position of each binary digit as it relates to its decimal equivalent. What?? OK, take for example the binary number 00001010. Referring to the table above just add the positional decimal equivalents where the 1's occur. So, 00001010 means 128 (no), 64 (no), 32 (no), 16 (no), 8 (yes), 4 (no), 2 (yes) 1 (no). Given that, we see that 8 + 2 =10. In other words 00001010 binary is 10 decimal. Here are a few more examples.
11000000 - 128 + 64 = 192
00000001 - = 1
00110011 - 32 + 16 + 2 + 1 = 51
11011011 - 128 + 64 + 16 + 8 + 2 + 1 = 219
00000000 - = 0
11111111 - 128 + 64 + 32 +16 + 8 + 4 + 2 + 1 = 255
If you encounter a binary number less than a byte such as 11001 (25 decimal), just pad the missing binary digits with 0's, making the number 00011001, a complete byte. Also, if you are presented with a binary number larger than a byte then double the decimal number with each subsequent binary position to the left. See table below. Later, when we work with subnetting, we'll use these larger values.
At this point you should be comfortable with converting binary to decimal. Now let's go the other way, decimal to binary. I'll show you two different methods. Use the one that best works for you.
This method is pretty straight forward. The first
thing to do is write down the decimal value row previously covered.
Next, somewhere off to the side, write down your decimal number. With a byte, or octet, the smallest number is 0 and the largest 255, so your number must be within this range. Next, follow the procedure below:
Compare the decimal number with the MSB (128). If your number is larger than or equal to 128 then place a 1 under the 128 column, subtract 128 from your number and move to the next position (64). However, if your number is less than 128 then place a 0 under the 128 column and move to the next number (64) without subtracting.
Repeat the above process with 64, 32, 16 etc.
until your original number is reduced to zero. If you
reach zero before reaching the LSB (1) fill in the remaining columns
with 0's. below are a few examples:
This method has you repeatedly dividing a decimal
number by 2 and saving the remainder, either 1 or 0, as a binary
digit. Keep doing this until, again, your original number has been
reduced to 0. It's not as confusing as it sounds. Let's walk through an
example:
Refer
to the example above. Given the decimal number 41 and the
divide-and-conquer method, we derive its binary equivalent with the
following logic:
41 divided by 2 is 20, remainder 1. Place a 1 in the remainder column and 20 in the division column. This is the LSB and will be the rightmost binary digit.
20 divided by 2 is 10, remainder 0. Place a 0 in the remainder column and 10 in the division column.
10 divided by 2 is 5, remainder 0. Place a 0 in the remainder column and 5 in the division column.
5 divided by 2 is 2, remainder 1. Place a 1 in the remainder column and 2 in the division column.
2 divided by 2 is 1, remainder 0. Place a 0 in the remainder column and 1 in the division column.
1 divided by 2 is 0, remainder 1. Place a 1 in the remainder column and we're done ...
... well almost. Our solution came out to be only
6 binary digits long. Since we are working with bytes, just pad the
left with 0's until the binary number is 8 digits in length. One
more thing. Your last operation will always be 1/2
= 0, remainder 1. Here a couple more examples:
At times you might have a binary or decimal that is larger than a byte. Don't panic. All you need to do is extend the binary byte row to the left, doubling as you go along.
now becomes the following if we have a 12 bit binary number:
Here is a sample conversion from binary to decimal
using process of elimination:
Just when you got your head around binary and decimal, along comes hexadecimal, hex for short. Before, I mentioned that everything in the computing and networking arena is nothing more that 1's and 0's and that axiom remains unchanged. We now know how to convert back and forth between binary (what the computer speaks) and decimal (what we speak), so why do we even need hex? Besides being an efficient numbering system, hexadecimal is widely used to represent to us humans the 1's and 0's that traverse circuits and wires. A few examples where hex numbers are used are colors, memory references, IPv6 addresses and MAC addresses. Let's explore this a little more in detail.
A binary byte is exactly eight digits long, e.g.
00101110 and a hex byte number is exactly two digits in length, e.g.
6A. A decimal byte on the other hand is anywhere between one and
three digits long, e.g. 4, 64 or 233. Yes, you could pad
these with 0's making 004, 064 and 233, but this is still not as
efficient or as practical as hex. (as we'll see when we start
converting hex and binary numbers). Download my extended ASCII
table; it will help with the following illustration and serve as
a useful refernece for your studies:
This screenshot is a memory dump of my computer. Imagine if those numbers
were represented in binary!
Let's get on with it.
Below is a hex table with decimal equivalents:
With hex, the first 10 digits, 0 thru 9, are the same as decimal. However, 10 thru 15 decimal are represented as a single hex digit A thru F. The number 5 in decimal is 5 in hex and the number 13 in decimal is D in hex. What happens when we reach F (15 decimal) and need to increment by 1 is that, just like with all other numbering systems, we flip that to 0 and place a one to the left. 0xF + 0x1 = 0x10. What is this 0x business? Placing 0x in front of a hex number is the typical way to indicate it's really hex. It makes it clear that 11 (decimal) and 0x11 (hex) are two different numbers entirely. So, from here on out I'll use the 0x to indicate hexadecimal numbers. Sometimes you'll see the hex numbers 0xA thru 0xF written in lower case (0xa thru 0xf). There's nothing wrong with that and it does not change the numerical value of the number in question. I use caps in this how-to.
To convert a binary byte to hex byte, first split the
binary number into two nibbles, treating them as separate numbers,
and then compute the hex equivalent for each half. Finally,
concatenate the two hex numbers into a single solution. This works
perfectly because a nibble has a value from 0 thru 15 or 0x0 thru
0xF.
Here's some examples:
The conversion process from hex to binary is not
much different, we just reverse the process. A picture is worth a
thousand words. Here's 4,000 of them.
Once in a while you may find yourself presented with a binary or hex number larger than a byte. The methods are the same, just expanded. If you have a binary number to convert then you may have to pad the MSB with 0's in order to have a binary number that falls on nibble boundaries, multiples of 4. For example, the binary number 1001100101 won't convert correctly, because it's ten digits in length. Add two 0's making the number 001001100101. A few illustrations:
Up to now we've been able to accomplish our
conversions armed with only paper and pencil. It's time to break out
your calculator for converting decimal to hex and vice versa. Take
Look at these decimal / hex equivalents:
16 = 0x10 | 34 = 0x22 | 214 = 0xD6 |
175 = 0xAF
Here's how we get from the decimal value on the left of the = sign
to its hexadecimal equivalent on the right. Remember the divide and
conquer method we used for converting decimal to binary? We are
going to use the same method except that we are going to be dividing
by 16 rather than 2. The upside is that the process is a lot
shorter.
225 divided by 16 is 14, remainder 0x1. Place a 0x1 in the remainder column and 14 in the division column. This is our rightmost hex digit.
14 divided by 16 is 0, remainder 14. Since we are converting to hex we use 0xE. Place 0xE in the remainder column and we're done.
If you have a small decimal number such as 12, you'll have your answer on the first divide. 12 / 16 = 0, remainder 12 or 0xC. Place a leading 0 in from of the C to keep things uniform. So, the answer would be 0x0C
How easy is that? Here are a few more:
It's no different with numbers larger than a byte:
Whew! Nearly done. This is our last number
conversion segment, hexadecimal to decimal. With a hex number each
position represents a power of 16 and what we do is calculate each
position's decimal equivalent and then add them all up. We are going
to use a large hex number to illustrate this concept. Given the hex
number 0xA59C we find its decimal equivalent with the following
logic.
(10 x 16^{3}) + (5 x 16^{2}) + (9 x 16^{1}) + (12 x 16^{0})
= 43,296. Here's how it breaks down:
...And a few more:
I encourage you to practice, practice, practice. Download this worksheet to work thru various conversion exercises.
Parting shot - If you are an aspiring network or systems admin then make sure you understand without question binary and decimal conversion through and through.
Coming soon - Part II Understanding IP addresses, subnet masks and subnetting.
./Robert