Applications of Bitwise Operations

Contributed by [TrIpLe]

Applications of Bitwise Operations

This tutorial is a small development, which started out as just a code snippet to demonstrate the basics of boolean algebra, but I was told to make it into a tutorial, so here I am. Bitwise operations have many useful, different applications and can be used in many different places. In this tutorial I intend to show you the basic use of bitwise operations through an example of the $longip() identifier. This identifier converts a dotted decimal IP address (192.168.0.1) to its long integer format (3232235521), and vice-versa. This tutorial will show you how to apply boolean arithmetic to achieve such an identifier.

Ok, before we start, I should take you through the basics of logic gates. Also take note that mydnzi has also written a tutorial on bitwise operators here

Here is the truth table for the OR gate where A and B are the inputs:

A  B  OUT
---------
0  0   0
0  1   1
1  0   1
1  1   1

Ok, this truth table is saying that if at least one of the inputs are true, or 1, then the output is 1.

...the AND gate:

A  B  OUT
---------
0  0   0
0  1   0
1  0   0
1  1   1

This states that if, and only if, both of the inputs are true, or 1, then the output is 1.

I only included the truth tables for these two gates as they are the ones that I will be using for this tutorial. Maybe if I create another tutorial on bitwise operations I will include the usage of those. But please, by all means, feel free to look up the other gates: NOT, NAND, NOR, XOR and XNOR. They all have many uses.

Dotted Decimal to Integer Conversion

Now I will show you how to apply these gates to convert a dotted decimal IP address (192.168.0.1) into its long integer format.

Ok, so first we turn each octet into its binary form with a width of 8 bits:

192 = 11000000
168 = 10101000
  0 = 00000000
  1 = 00000001

Now, we have to shift each of the binary numbers into their approriate positions using a bit shifting operator (which we have to make in mIRC):

192 << 24
----------
11000000 00000000 00000000 00000000

168 << 16
---------
00000000 10101000 00000000 00000000

0 << 8
---------
00000000 00000000 00000000 00000000

1 << 0
---------
00000000 00000000 00000000 00000001

Now, this is where we perform our OR on all four lines:

192 = 11000000 00000000 00000000 00000000 |
168 = 00000000 10101000 00000000 00000000 |
0   = 00000000 00000000 00000000 00000000 |
1   = 00000000 00000000 00000000 00000001
-----------------------------------------
      11000000 10101000 00000000 00000001 = 3232235521

And this leaves us with our long integer format of the original dotted decimal IP address.

Integer to Dotted Decimal Conversion

Now we get into the process of reversing this long integer to regain our dotted decimal IP address.

To achieve such a goal, we must make use of the AND gate to remove the unneeded octets so we can retrieve the octet that we want. Once AND'd, we then shift the bits back to their original positions, like so:

  11000000 10101000 00000000 00000001
& 11111111 00000000 00000000 00000000
-------------------------------------
  11000000 00000000 00000000 00000000 >> 24 = 11000000 = 192

  11000000 10101000 00000000 00000001
& 00000000 11111111 00000000 00000000
-------------------------------------
  00000000 10101000 00000000 00000000 >> 16 = 10101000 = 168

  11000000 10101000 00000000 00000001
& 00000000 00000000 11111111 00000000
-------------------------------------
  00000000 00000000 00000000 00000000 >> 8 = 00000000 = 0

  11000000 10101000 00000000 00000001
& 00000000 00000000 00000000 11111111
-------------------------------------
  00000000 00000000 00000000 00000001 >> 0 = 00000001 = 1

Now, we join each integer with a decimal point in between and we are left with the original dotted decimal IP address as before: 192.168.0.1

Some Code

I couldn't possibly write a tutorial for a mIRC scripting site and not include the code to perform what I have just demonstrated. The code looks a little different to what may seem to be explained, but it is correct.

alias _longip {
  if ($regex($1,/^\d+\.\d+\.\d+\.\d+$/)) return $dot2dec($1)
  else return $dec2dot($1)
}
alias dot2dec {
  ; Originally all this code was on one line without any variables (as is the
  ; $dec2dot identifier), but this is for the sake of example.
  tokenize 46 $1
  var %one = $or($shiftl($1,24),$shiftl($2,16))
  var %two = $or(%one,$shiftl($3,8))
  var %three = $or(%two,$4)
  return %three
}
alias dec2dot {
  var %one = $shiftr($and($1,$base(ff000000,16,10)),24)
  var %two = $shiftr($and($1,$base(00ff0000,16,10)),16)
  var %three = $shiftr($and($1,$base(0000ff00,16,10)),8)
  var %four = $and($1,$base(000000ff,16,10))
  return %one $+ . $+ %two $+ . $+ %three $+ . $+ %four
}
; These next two bit shifting aliases were coded poorly but work in this example. I
; cannot guarantee that they will work in every case that you use them, but they seem
; ok to me. Please, if you have a better example, use it, this one sucks.
alias shiftl return $base($base($1,10,2,8) $+ $str(0,$calc(($2 + 8) - $len($base($1,10,2,8)))),2,10)
alias shiftr return $iif($base($left($base($1,10,2),- $+ $2),2,10),$ifmatch,$chr(48))

End Notes

See? Applying the knowledge of bitwise operations is not a difficult thing to do and anyone can do it. If you have any questions or suggestions, please feel free to email me at [email protected]

All content is copyright by mircscripts.org and cannot be used without permission. For more details, click here.