Plage d'adresses IP
On souhaite créer une classe Reseau qui donne les caractéristiques d'un réseau logique auquel appartient une machine à l'adresse IP donnée.
Adresse IP et masque
Une adresse IP identifie à la fois un réseau ET l'adresse d'une machine dans ce réseau.
Un masque de sous réseau est un séparateur qui permet de distinguer les parties réseau et machine d'une adresse IP.
On considère que le cas est simple quand les octets du masque ont pour valeur soit \(0\), soit \(255\).
Par exemple, si j'associe l'adresse IP et le masque suivants : \(192.168.0.1 - 255.255.255.0\)
Les trois premiers octets du masque sont à la valeur \(255\) : on peut alors dire que les trois premiers octets de l'adresse représentent la partie réseau de l'adresse.
La partie réseau de l'adresse est donc \(192.168.0\) et la partie machine de l'adresse au sein de ce réseau est donc représentée par le quatrième octet \(1\)
On considère que le cas est compliqué quand le premier octet significatif du masque est différent de \(255\).
Par exemple, si j'associe l'adresse IP et le masque suivants : \(192.168.0.1 - 255.255.224.0\)
Dans ce cas, il faut obligatoirement revenir en binaire pour savoir où se fait la séparation : \(255.224.0.0 = 11111111.11100000.00000000.00000000\) (elle se fait au milieu de l'octet)
On écrit également l'adresse IP en binaire. 192.168.0.1 = 11000000.10101000.00000000.00000001 et on effectue une opération ET binaire entre l'adresse et le masque, ce qui donne comme partie adresse : 11111111.10101000.000
la classe AdresseIP
On donne une classe AdresseIP gérant une adresse IPv4 et son masque de sous-réseau.
L'adresse et le masque sont codés sur \(4\) octets, écrits en décimal, séparés par des points comme ceci : \(192.168.0.1 / 255.255.255.0\)
Notre objet AdresseIP comportera deux attributs :
adressela liste des \(4\) entiers correspondants à l'adressemasquela liste des \(4\) entiers correspondants au masque
Exemple
>>> adr = AdresseIP('192.168.0.1', '255.224.0.0')
>>> adr.adresse
[192, 168, 0, 1]
>>> adr.masque
[255, 224, 0, 0]
Indication
On pourra utiliser split pour découper une chaine de caractères :
>>> "192.168.10.5".split('.')
["192", "168", "10", "5"]
Nous allons définir la méthode plage_adresses qui calcule la première et la dernière adresses IP valides associées à une adresse IP donnée (avec son masque de sous-réseau).
Nombre magique
La technique utilisée ici est celle du nombre magique, qui permet d'éviter toute conversion en binaire.
Le nombre magique est simplement un calcul fait à partir de l'octet significatif du masque.
Il est égal à \(256 - octet significatif\).
Exemple
Dans notre exemple précédent, le masque était \(255.224.0.0\). On voit vite que l'octet significatif (celui où la séparation a lieu) est 224.
Notre nombre magique vaut donc \(256 - 224 = 32\)
Pour cela il nous faut :
pos: la position de l'octet significatif du masque c'est-à-dire le 1er octet non nul en partant de la droitemagic: le nombre magique qui vaut \(256 -\) l'octet significatifadr_debutqui coïncide avec l'adresse pour les positions 0 àposexclue, qui vaut \(0\) pour les positionsposexclue jusqu'à la fin et qui vaut \(m\) le plus grand multiple demagicinférieur à la valeur de l'adresse à la positionposadr_finqui coïncide avec l'adresse pour les positions 0 àposexclue, qui vaut \(255\) pour les positionsposexclue jusqu'à la fin et qui vaut \(M = m +\mathit{magic} - 1\) à la positionpos
Le schéma ci-dessous résume les règles :
Exemple
Avec l'adresse \(192.168.0.1\) et le masque \(255.224.0.0\), on a :
posqui vaut \(1\)magic: \(256 - 224 = 32\)adr_debutcommence comme l'adresse et la fin est constituée de 0, seule la position 1 est à calculer : \(192.m.0.0\) et \(m\) est le plus grand multiple de \(32\) inférieur à \(168\) soit \(160\) ;adr_debutvaut donc \(192.160.0.0\)adr_finest de la forme \(192.M.255.255\) avec \(M\) valant \(160 + 32 - 1\) ce qui nous donne \(192.191.255.255\)
Compléter la définition de la classe AdresseIP, y compris la méthode plage_adresses :
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)