Spredehagl
go to homego to top

Én bit netværksmasker

Antallet af IP adresser er:

    4.2949e9   IPv4 adresser
    3.4028e38  IPv6 adresser

Adresserne er simpelthen bitstrenge af henholdsvis længde 32 og 128. Så antallene er bare 232 og 2128.

Men hvor mange netværk er der?

Netværk

I det følgende bruger jeg kun IPv4, fordi det er simplere. Men vores resultater vil osse gælde IPv6.

Netværk har to dele, en netværksadresse og en netværksmaske. Det ligner umiddelbart to IP adresser, fordi det er to bitstrenge af længde 32.

10.20.30.128  255.255.192.0

Den anden bitstreng, netværksmasken, starter altid med en række 1er, hvorefter resten er 0er. Skrevet med bits ser eksemplet sådan ud:

00001010.00010100.00011110.10000000  11111111.11111111.11000000.00000000

Da masken altid har dette mønster, skriver mange bare netværket med det antal 1er der er i masken, sådan her:

10.20.30.128/18

Det kaldes CIDR notation.

Lad os nu for sjov forestille os at vi gerne vil spare noget memory.

Læg mærke til at masken kun består af 32 bits, så den kan kun tage 33 forskellige værdier. Vi behøver helt sikkert ikke 32 bits for at skrive de værdier. 6 bits kan gøre det. Så vores eksempel kunne se sådan ud:

00001010.00010100.00011110.10000000  010010

Men det kan gøres bedre endnu. Læg mærke til at netværksadressen slutter med 0er på samme måde som 32 bit masken gør det. Så vi må kunne spare noget her. Det er dog ikke så ligetil, for antallet af 0er afhænger af masken, så det er variabelt. Desuden kan netværksadressen være gyldig for mere end én maske. I det mindste for alle mindre masker. Så hvad gør vi?

Jo, som du har gættet fra overskriften, så kan masken effektivt set reduceres til én bit. Det gøres sådan her:

Tag kun den del af netværksadressen hvor 32 bit masken er 1. Notér hvad sidste bit er i den. Vedhæft så den modsatte bit indtil længden er n+1.

I vores eksempel vil resultatet se sådan ud:

00001010.00010100.00011110.10111111  1

Kan vi spare mere memory end det? Nej. Alle /32 netværk svarer til alle IP adresser, og det tager som bekendt 32 bits at repræsentere dem. Så har vi kun 32 bits, er der ikke plads til netværk større end /32.

0.0.0.0/0

Når 32 bit masken kun består af 0er, altså når netværket er 0.0.0.0/0, så bryder vores én bit netværksmaske metode sammen. Der er ikke nogen bits i netværksadressen, som vi kan starte med. Vi ved ikke om vi skal fylde de 33 bits med 0er eller 1er.

Jeg har valgt at sige der skal bruges 0er.

Hvis man begynder at lave aritmetik med bitstrenge finder man ud af at bitstrengen der kun har 1er i sig, opfører sig mærkeligt. Derfor bliver den ofte kaldt for "weird". Det er grunden til at jeg har valgt det osse er den der skal være weird når det gælder én bit netværksmaskerne.

Men hvor mange?

Det er nemt at vende "komprimeringen", som jeg lige viste dig, om. Det eneste man skal gøre er at tage skridtene baglæns.

Bemærk nu to interessante egenskaber. 1: Uanset hvilken bitstreng af længde 33 vi får, kan den "dekomprimeres" til et netværk. 2: To forskellige ikke-weird strenge vil altid "dekomprimere" til to forskellige netværk...

Det vi har er bedre end komprimering og dekomprimering. Vi har en en-til-en korrespondance mellem netværk og ikke-weird bitstrenge af længde 33.

Det gør det nemt at svare på spørgsmålet fra starten af artiklen... Hvor mange netværk er der?

    8.5899e9   IPv4 netværk
    6.8056e38  IPv6 netværk*

Som er henholdsvis 233-1 og 2129-1.

*) Dette er et teoretisk tal. I IPv6 bør alle subnets være /64, hvilket giver os et antal på 265-1 ≈ 3.6893e19 IPv6 netværk. Men det tal kommer med sine egne forbehold, da netværk mindre end /64 bruges regelmæssigt i en række tilfælde.

I praksis

Grunden til at IPv4 netværk repræsenteres med netværksadresse og maske, er at de er utroligt effektive at beregne på. Med den repræsentation kan de fleste beregninger klares med bitvis logiske oparationer, som er i enhver hæderlig processors instruktionssæt. Beregninger bliver ikke meget hurtigere end det.

Det kan være du osse har lagt mærke til at processorerne er grunden til størrelsen af bitstrengene, da 32 bits var word size for de stærke processorer dengang IPv4 blev designet.

Algoritmerne for, og lagringen af IPv6 netværk er mere komplicerede. Men deres repræsentation er osse stærkt påvirket af processorer og performance.

Faktisk gennemsyrer hardwareorienterede formater alle dele af netværk. Netværksformater er nok det tætteste som dataformater kommer på assembler.

Generelt

Hvis vi glemmer netværk et øjeblik, så er det vi i virkeligheden har når vi har et "netværk", en bitstreng med længde mindre end eller lig med 32. Lad os osse glemme tallet 32, så er det vi har en bitstreng med længde mindre end eller lig med n. Vores korrespondance gælder helt generelt mellem disse bitstrenge og ikke-weird bitstrenge af fast længde n+1.

Funktionerne er meget simple. En er den andens invers, og omvendt. Her er de i pseudokode:

function to_fixed( b , n )
// b: Bitstreng af længde ≤ n.
// n: Positivt heltal.
// Afbild b til en bitstreng af længde n+1.
    hvis b er tom
        sæt lastbit til 1
    ellers
        sæt lastbit lig med den sidste bit i b
    vedhæft (not lastbit) til b sålænge dens længde er ≤ n
    returnér b
function from_fixed( b )
// b: Ikke-weird bitstreng af længde n+1.
// Afbild b til en bitstreng af længde ≤ n.
    sæt lastbit lig med den sidste bit i b
    fjern den sidste bit i b sålænge den er lig med lastbit
    returnér b

Disse funktioner kan osse udnytte lav-niveau instruktioner. Men da de indeholder løkker, kan de aldrig blive lige så effektive som adresse+maske funktionerne.