Et lite skriv om det heksadesimale tallsystemet

Arkiverer denne artikkelen som jeg hadde skrevet på den gamle nettsiden på engelsk.

PHP Bitwise IP Handling

How to properly compare an IP address against a bitmask. Useful for e.g. blocking subnets without using abundant string comparisons.

$BlockedNetworks = array(ip2long(""),
$BlockRange = ip2long("");
$VisitIP = ip2long($_SERVER['REMOTE_ADDR']);
foreach ($BlockedNetworks as $BN) {
	if (($VisitIP & $BlockRange) == $BN)
		exit(); // or redirect or whatever you want.

In the example above, any IP in the 192.168.x.x and 10.0.x.x ranges will be matched. The 255 numbers you see in masks represent all 8 bits in an octet being turned on, so comparing against it will always reserve the octet bits without turning them off. Meaning & equals because the last two octets will be turned off during comparison.

How Does It Work?
Bitwise AND(& operator). It's what network masks are all about. It's the bitwise operator used in programming if you need to turn off a bit, by comparing to a off-bit/0.

1 & 1 = 1
1 & 0 = 0
0 & 1 = 0

In Detail

Let's investigate, and use that as our IP address of choice. To find out the binary version of this address, we just need to take an empty octet/set of 8 binary bits and turn some of them on so they add up to 192, 168, 1 and 10.

Here's a turned off byte/octet:
[0 0 0 0 0 0 0 0] Which represents:
[128 64 32 16 8 4 2 1] in decimal values when individually turned on.

To get 192 we need to turn on 128 + 64. The octet now looks like this:
[1 1 0 0 0 0 0 0]

Now that we know how to convert binary into decimal, let's do the whole address:
[11000000].[10101000].[00000001].[00001010] =

Let's put it on top of the mask and compare bits one by one:
  [11000000].[10101000].[00000001].[00001010] (
& [11111111].[11111111].[00000000].[00000000] (
= [11000000].[10101000].[00000000].[00000000] (

As you see, when comparing 1 AND 1 it will stay 1, while 0 turns it off. Hence why will equal when using bitwise AND comparison. This should give a deeper understanding of network masks works in general and how they work in normal networking.

Same thing works on IPv6 adresses, they are just bigger to deal with (128 bits vs 32) and use hexadecimal number groups instead of octets.
= 0010000000000001:0000110110111000:1000010110100011:0000000001000010:0001000000000000:1000101000101110:0000001101110000:0111001100110100

A bitmask could look something like:

To match everything in the network when compared directly to it with the algorithm at the beginning of this document:

A Quick Note on The Hexadecimal System

It's just a number system with a base of 16 instead of 2 and 10 (0-9 and a-f/A-F). E.g. a value like 0xABCD consists of a prefix (0x) to tell the parser it's actually a hexadecimal value, and the value itself. Since A follows after 9, its value is 10 - and so on up until 15(F). So you got 10, 11, 12 and 13. These are actually just easier ways of representing binary and decimal values since the base of 16 is bigger. A B C and D represents groups of 4 binary bits with a base of 2, and those bits represents the same decimal values with a base of 10 as in the binary system. Knowing this, a convertion between them is always possible even if you choose to do it through math or just value mapping/representation.

One Simple Illustration, To Rule Them All:
Hexidecimal: 0xABCD
   = Binary: 0x[1010][1011][1100][1101] > [8+2=10][8+2+1=11][8+4=12][8+4+1=13].
  = Decimal: 0x[32768+0+8192+0][2048+0+512+256][128+64+0+0][8+4+0+1] = 43981.

Publisert: 13.jul.2023 12:21 | Oppdatert: 13.jul.2023 12:33.

Erklæring om bruk av informasjonskapsler/cookies

Ditt personvern er ivaretatt; Informasjonskapsler brukes kun for funksjon.

Tredjeparter som har sine egne erklæringer:
Site Stats
OK / Skjul