Onderstaand is een artikel dat ik in 2000 heb geschreven voor het destijds online magazine Hackers 4 Hackers. Nee, het was geen ‘hogere wiskunde’. De versie hieronder is iets herschreven, de taalfouten zijn er zoveel mogelijk uit. Het artikel gaat over het omrekenen van IP-adressen naar het decimale talstelsel, of Base 10, en omgekeerd. Dit was een techniek die spammers vaak gebruikten om IP adressen en URLs te verbergen in mailberichten en e-mailheaders. Bear with me, het was 24 jaar geleden :) Lees hieronder verder.

Je hebt ze vast wel eens gezien, rare getallen wat later toch een soort IP-adres blijkt te zijn. Veelal gebruikt door spammers die hopen zo anoniem te blijven. Hier leg ik dus uit wat dat is en hoe je zoiets kan omrekenen.

Wat is Base 10 eigenlijk?

Base 10 zijn getallen gevormd volgens het decimale talstelsel of tientallig talstelsel. Binair is dus Base 2, octaal is Base 8 en hexadecimaal is Base 16. Base 10 is een talstelsel om getallen weer te geven met behulp van de tien cijfers 0 tot en met 9.

Base 10 omrekenen en vice versa

Wat heb je nodig? Ik ga ervan uit dat je een Linux shell(account) bij de hand hebt. Heb je die niet dan moet je zelf alles uitrekenen (d.m.v. een rekenmachine of gewoon op papier :-)).

In mijn voorbeelden gebruik ik 209.237.160.164 (network-tools.com) als IP nummer. Waarom ? Omdat ik wat informatie hierover daar heb gevonden =)

Nu moet je dus een manier bedenken om die IP-nummers te converteren naar Base10 nummers. Dat kan met de volgende formule:

$1 * 256^3 + $2 * 65536 + $3* 256 + $4
  • $1 = het 1e deel (octet) van een IP-adres, dus : 209
  • $2 = het 2e octet van een IP-adres, dus : 237
  • $3 = het 3e octet van een IP-adres, dus : 160
  • $4 = het 4e octet van een IP-adres, dus : 164

Dat wordt dus : 209 x (256)^3 + 237 x (256)^2 + 160 x (256)^1 + 164 en de uitkomst is : 3522011300.

Dit Base 10 adres kun je pingen:

~$ ping 3522011300
PING 3522011300 (209.237.160.164): 56 data bytes
64 bytes from 209.237.160.164: icmp_seq=0 ttl=115 time=116.8 ms

--- 3522011300 ping statistics ---
2 packets transmitted, 1 packets received, 50% packet loss
round-trip min/avg/max = 116.8/116.8/116.8 ms

Zo zie je dat dit klopt. Als er een webserver draait kun je ook http://3522011300/ bezoeken met een browser.

Alles wat links van een Base 10 nummer staat kan je weglaten. Dus als iemand spamt met anonymous@3522011300 als afzendadres, dan kun je anonymous@ weglaten.

Heb je een shell dan kan je het heel snel omrekenen met dit command-prompt scriptje:

~$ echo $1|awk -F. '{print $1" * 256^3 + "$2" * 65536 + "$3"* 256 + "$4}'|bc

Verander de eerste $1 (echo $1) in het IP-adres.

Andere omrekenmanieren

Zijn er nog andere manieren om dit te doen? Ja, je kan ook het IP nummer eerst omrekenen naar binair, haal de punten eruit en reken het dan om naar decimaal.

Voorbeeld: 209.237.160.164

Alle octets moeten apart, dus eerst reken je 209 om naar binary. Er is een handige manier om een getal naar binair om te zetten. Deel het getal steeds weer door 2 en schrijf de rest op. Schrijf die resten van rechts naar links en je hebt het binaire getal.

209 / 2 = 104 rest 1
104 / 2 = 52 rest 0
52 / 2 = 26 rest 0
26 / 2 = 13 rest 0
13 / 2 = 6 rest 1
6 / 2 = 3 rest 0
3 / 2 = 1 rest 1
1 / 2 = 0 rest 1

Dit maakt 209 in binair: 11010001

  • 237 : 11101101
  • 160 : 10100000
  • 164 : 10100100

Dus: 209.237.160.164 is 11010001.11101101.10100000.10100100 in binary.

Dit kan heel makkelijk met het volgende Bash scriptje:

!/bin/sh
for i in `echo $1|tr "." " "`; do printf "obase=2\n$i\n"|bc; done

Maak het script uitvoerbaar met chmod: chmod +x script en je kunt het uitvoeren: ./script ip-adres

Zet de uitkomst achterelkaar en haal de dots (punten) eruit: 11010001111011011010000010100100. Reken dit weer om naar decimaal met het volgende scriptje:

#!/bin/sh
printf "ibase=2\n$1\n" |bc

Maak ook dit script uitvoerbaar: chmod +x script2 en je kunt het uitvoeren: ./script2 binary-getal.

Update 2024: PowerShell voor Windows equivalenten zijn:

PS > $ip = '209.237.160.164'
PS > $binary =  $ip -split '\.' | ForEach-Object {
>>     [System.Convert]::ToString($_,2).PadLeft(8,'0')
>> }
PS > $binary
11010001
11101101
10100000
10100100
PS > $binary -join '.'
11010001.11101101.10100000.10100100
PS > $decimal = $binary | ForEach-Object {
>>     [System.Convert]::ToByte($_,2)
>> }
PS > $decimal
209
237
160
164
PS > $decimal -join '.'
209.237.160.164