package util;
/**
* Syntax analyser for network addresses
* This class is constructed with a String to analyse
* If this string is a valid network address some informations are provided:<br>
* - type of address (IPv4, IPv6, Bluetooth, IEEE)<br>
* - address in a extended form (all parts filled with 0)<br>
* - address in a reduced form (all parts without zeros)<br>
* - address in a normalized form
* (it is difficult to say is a normalized form for an address because different OS use different representations)<br>
* This class can also be used to compare two addresses (method equals)<br>
*
* The accepted syntax are the following:<br>
* - For Bluetooth: a maximum of 12 hexadecimal digits or 6 parts of 1 to 2 hexadecimal digits separated by :<br>
* - For IEEE: 4 part of 4 hexadecimal digits separated by .<br>
* - For IPv4: 4 part of 1 to 3 decimal digits (each part representing an integer from 0 to 255) separated by .<br>
* - For IPv6: 8 part of 1 to 2 hexadecimal digits separated by :<br>
* only one part can by empty (replaced by 0)<br>
* a zone indice can terminate the string: it starts with % and holds only decimal digits<br>
*
* @author Dalmau
*/
public class NetworkAddress {
// Constantes correspondant aux types d'adresses connus
/**
* Constant used to qualify an IPv4 address
*/
public static final int TYPE_IPV4 = 4;
/**
* Constant used to qualify an IPv6 address
*/
public static final int TYPE_IPV6 = 6;
/**
* Constant used to qualify an IEEE (Zigbee) address
*/
public static final int TYPE_IEEE = 3;
/**
* Constant used to qualify a bluetooth address
*/
public static final int TYPE_BLUETOOTH = 2;
/**
* Constant used to qualify an unknown type address
*/
public static final int TYPE_UNKNOWN = -1;
// Constantes utilisisees pour decouper les adresses
private static final int TAILLE_IPV4 = 4; // IPV4 = 4 parties decimales separees par des .
private static final int TAILLE_IPV6 = 8; // IPV8 = 8 parties separees par des :
private static final int TAILLE_IEEE = 4; // IEEE = 4 parties hexadecimales de taiile 4 separees par des .
private static final int TAILLE_BLUETOOTH = 12; // Bluetooth = 12 chiffres hexadecimaux au maximum
private static final int GROUPES_BLUETOOTH = 6; // Bluetooth = 6 parties hexadecimales de 2 separes par des :
private static final char separateurIPv4 = '.'; // separation des groupes en IPv4
private static final char separateurIPv6 = ':'; // separation des groupes en IPv6
private static final char separateurIEEE = '.'; // separation des groupes en IEEE
private static final char separateurZoneIPv6 = '%'; // separation de l'indice de zone en IPv6
// Proprietes liees a une addresse apres analyse
private int type; // type d'adresse = l'une des constantes definies ci-dessus
private String reducedAddress; // adresse sans 0 au debut des champs (sauf pour IEEE)
private String extendedAddress; // adresse avec chaque champ complete avec des 0
private String indiceDeZone; // indice de zone uniquement en IPv6 voir RFC4007 paragraphe 6
// Methodes publiques
/**
* Creates a network address from a string
* @param adresse the string containing the address
*/
public NetworkAddress(String adresse) { // construction d'une adresse a partir d'une chaine
type = addressType(adresse);
reducedAddress = reduitAdresse(type, adresse);
extendedAddress = etendAdresse(type, adresse);
if (type == TYPE_IPV6) {
int pos = adresse.indexOf("%");
if (pos != -1) indiceDeZone = adresse.substring(pos);
else indiceDeZone = "";
}
else indiceDeZone = "";
}
/**
* Returns the type of address (IPv4, IPv6 ...)
* @return the type of address (IPv4, IPv6 ...)
*/
public int getType() { return type; } // renvoie le type de l'adresse
/**
* Returns a string containing the address without leading zeros
* The indice zone part is removed for IPv6 (see getZoneIndice())
* @return a string containing the address without leading zeros
*/
public String getReducedAddress() { return reducedAddress; } // renvoie l'adresse sans 0 en debit de champ (sauf pour IEEE)
/**
* Returns a string containing the address with all parts completed to full size by zeros
* The indice zone part is removed for IPv6 (see getZoneIndice())
* @return a string containing the address with all parts completed to full size by zeros
*/
public String getExtendedAddress() { return extendedAddress; } // renvoie l'adresse avec les champs completes a leur taille max
/**
* Return a string containing the address in a format usable on network
* The indice zone part is removed for IPv6 (see getZoneIndice())
* @return a string containing the address in a format usable on network
*/
public String getNormalizedAddress() {
switch(type) {
case TYPE_IPV4 : return reducedAddress;
case TYPE_IPV6 : return extendedAddress;
case TYPE_IEEE : return extendedAddress;
case TYPE_BLUETOOTH : return extendedAddress;
default : return extendedAddress; }
}
/**
* Returns the zone indice of an IPv6 address or an empty string for non IPv6 addresses
* @return the zone indice of an IPv6 address or an empty string for non IPv6 addresses
*/
public String getZoneIndice() { return indiceDeZone; } // renvoie l'indice de zone (valable uniquement pour IPv6)
/**
* Compares two network addresses
* For IPv6 addresses the zone indice part is not compared
* @param autre the network address to compare
* @return true if same address false otherwise
*/
public boolean equals(NetworkAddress autre) { // compare 2 adresses
if (autre == null) return false;
if (type != autre.getType()) return false;
else {
return extendedAddress.equals(autre.getExtendedAddress());
}
}
/**
* Compare the type of two addresses
* @param autre the network address to compare
* @return true if same typa (IPv4, IPv6 ...) false otherwise
*/
public boolean isSameType(NetworkAddress autre) {
return (type == autre.getType());
}
/**
* Return true if the address is of an unknown type
* @return true if the address is of an unknown type false otherwise
*/
public boolean isUnknown() {
return (type == TYPE_UNKNOWN);
}
/**
* Return true if the address is of a known type false otherwise
* @return true if the address is of a known type false otherwise
*/
public boolean isKnown() {
return (type != TYPE_UNKNOWN);
}
/**
* Returns true if the address is IPv4 false otherwise
* @return true if the address is IPv4 false otherwise
*/
public boolean isIPv4() {
return (type == TYPE_IPV4);
}
/**
* Returns true if the address is IPv6 false otherwise
* @return true if the address is IPv6 false otherwise
*/
public boolean isIPv6() {
return (type == TYPE_IPV6);
}
/**
* Returns true if the address is IEEE (Zigbee) false otherwise
* @return true if the address is IEEE (Zigbee) false otherwise
*/
public boolean isIEEE() {
return (type == TYPE_IEEE);
}
/**
* Returns true if the address is bluetooth false otherwise
* @return true if the address is bluetooth false otherwise
*/
public boolean isBluetooth() {
return (type == TYPE_BLUETOOTH);
}
// Methodes privees
// Enleve les 0 de debut de champ d'une adresse quelconque
private String reduitAdresse(int typ, String adresse) {
switch (typ) {
case TYPE_IPV4:
return reduitIPv4(adresse);
case TYPE_IPV6:
return reduitIPv6(adresse);
case TYPE_BLUETOOTH:
return reduitBluetooth(adresse);
case TYPE_IEEE:
return adresse;
default :
return adresse;
}
}
// Complete les champs d'une adresse quelconque a leur taille maximale
private String etendAdresse(int typ, String adresse) {
switch (typ) {
case TYPE_IPV4:
return etendIPv4(adresse);
case TYPE_IPV6:
return etendIPv6(adresse);
case TYPE_BLUETOOTH:
return etendBluetooth(adresse);
case TYPE_IEEE:
return adresse;
default :
return adresse;
}
}
// Analyse une adresse pour en determiner le type
private int addressType(String adresse) {
int etat = 0; // etat de l'automate d'analyse de l'adresse (en sortie de boucle c'est l'etat final)
int compteV4 =0; // compte des champs decouverts en IPv4
int compteV6 =0; // compte des champs decouverts en IPv6
int compteIEEE =0; // compte des champs decouverts en IEEE
int etatAtteint = TYPE_UNKNOWN; // dernier etat de l'automate dans lequel un type d'adresse a ete reconnu
String partieIPV4 = ""; // champs en IPv4 pour verifier que la valeur soit entre 0 et 255
int compteVide = 0; // compte des champs vides en IPv6 (un seul est autorise dans une adresse)
int i = 0; // indice de parcours de la chaine
boolean erreur = false; // sortie de l'automate en cas d'erreur de syntaxe de la chaine
while ((i<adresse.length()) && (!erreur)) { // jusqu'a la fin de la chaine ou erreur
char c = adresse.charAt(i); // caractere courant
switch (etat) { // automate selon l'etat actuel
case 0: // etat initial
if (isDecimal(c)) { // lecture d'un decimal
partieIPV4 = partieIPV4+c;
etat = 1;
}
else {
if (isHexadecimal(c)) etat = 4; // lecture d'un hexadecimal
else {
if (c==separateurIPv6) { // lecture d'un champ vide
etat = 16; // a priori on a reconnu du IPV6
compteVide++;
}
else {
if ((c==separateurZoneIPv6) && (etatAtteint == 16) && (compteV6 == TAILLE_IPV6-1)) etat = 8; // indice de zone
else erreur = true;
}
}
}
break;
case 1: // etat apres lecture d'1 chiffre decimal
if (isDecimal(c)) { // lecture d'un decimal
etat = 2;
partieIPV4 = partieIPV4+c;
}
else {
if (isHexadecimal(c)) etat = 5; // lecture d'un hexadecimal
else {
if (c==separateurIPv4) etat = 14; // fin de champ par . a priori on a reconnu du IPV4
else {
if (c==separateurIPv6) etat = 16; // fin de champ par : a priori on a reconnu du IPV6
else {
if ((c==separateurZoneIPv6) && (etatAtteint == 16) && (compteV6 == TAILLE_IPV6-1)) etat = 8; // indice de zone
else erreur = true;
}
}
}
}
break;
case 2: // etat apres lecture de 2 chiffres decimaux
if (isDecimal(c)) { // lecture d'un decimal
etat = 3;
partieIPV4 = partieIPV4+c;
}
else {
if (isHexadecimal(c)) etat = 6; // lecture d'un hexadecimal
else {
if (c==separateurIPv4) etat = 14; // fin de champ par . a priori on a reconnu du IPV4
else {
if (c==separateurIPv6) etat = 16; // fin de champ par : a priori on a reconnu du IPV6
else {
if ((c==separateurZoneIPv6) && (etatAtteint == 16) && (compteV6 == TAILLE_IPV6-1)) etat = 8; // indice de zone
else erreur = true;
}
}
}
}
break;
case 3: // etat apres lecture de 3 chiffres decimaux
if (c==separateurIPv4) etat = 14; // fin de champ par . a priori on a reconnu du IPV4
else {
if (isHexadecimal(c)) etat = 7; // lecture d'un hexadecimal
else erreur = true;
}
break;
case 4: // etat apres lecture d'1 chiffre hexadecimal
if (isHexadecimal(c)) etat = 5; // lecture d'un hexadecimal
else {
if (c==separateurIPv6) etat = 16; // fin de champ par : a priori on a reconnu du IPV6
else {
if ((c==separateurZoneIPv6) && (etatAtteint == 16) && (compteV6 == TAILLE_IPV6-1)) etat = 8; // indice de zone
else erreur = true;
}
}
break;
case 5: // etat apres lecture de 2 chiffres hexadecimaux
if (isHexadecimal(c)) etat = 6; // lecture d'un hexadecimal
else {
if (c==separateurIPv6) etat = 16; // fin de champ par : a priori on a reconnu du IPV6
else {
if ((c==separateurZoneIPv6) && (etatAtteint == 16) && (compteV6 == TAILLE_IPV6-1)) etat = 8; // indice de zone
else erreur = true;
}
}
break;
case 6: // etat apres lecture de 3 chiffres hexadecimaux
if (isHexadecimal(c)) etat = 7; // lecture d'un hexadecimal
else erreur = true;
break;
case 7: // etat apres lecture de 4 chiffres hexadecimaux
if (isHexadecimal(c)) { // lecture d'un hexadecimal
etat = 11; // a priori on a reconnu du Bluetooth
if ((etatAtteint == TYPE_UNKNOWN) || (etatAtteint == etat)) etatAtteint = etat;
else erreur = true; // on ne peut pas changer de type
}
else {
if (c==separateurIEEE) etat = 12; // fin de champ par . a priori on a reconnu du IEEE
else erreur = true;
}
break;
case 8 : // etat correspondant a la lecture de l'indice de zone en IPv6
if (!isDecimal(c)) erreur = true; // on n'accepte que des decimaux en indice de zone
break;
}
switch (etat) {
case 14: // etat apres decouverte d'au moins un champ IPv4
if ((etatAtteint == TYPE_UNKNOWN) || (etatAtteint == etat)) { // on n'avait pas reconnu autre chose avant
etatAtteint = etat;
compteV4++; // compter un champ IPv4 de plus
if (compteV4 == TAILLE_IPV4) erreur = true; // trop de champs
else {
if (testePartieIPV4(partieIPV4)) { // le champ est bien entre 0 et 2555
partieIPV4=""; // pour tester le champ suivant
etat = 0;
}
else erreur = true; // champ incorrect (hors de 0...255)
}
}
else erreur = true; // on ne peut pas changer de type
break;
case 16: // etat apres decouverte d'au moins un champ IPv6
if ((etatAtteint == TYPE_UNKNOWN) || (etatAtteint == etat)) { // on n'avait pas reconnu autre chose avant
etatAtteint = etat;
compteV6++; // compter un champ IPv6 de plus
if (compteV6 == TAILLE_IPV6) erreur = true; // trop de champs
else etat = 0;
}
else erreur = true; // on ne peut pas changer de type
break;
case 12: // etat apres decouverte d'au moins un champ IEEE
if ((etatAtteint == TYPE_UNKNOWN) || (etatAtteint == etat)) { // on n'avait pas reconnu autre chose avant
etatAtteint = etat;
compteIEEE++; // compter un champ IEEE de plus
if (compteIEEE == TAILLE_IEEE) erreur = true; // trop de champs
else etat = 0;
}
else erreur = true; // on ne peut pas changer de type
break;
case 11: // etat apres decouverte d'une chaine pouvant correspondre a du bluetooth
if (!isHexadecimal(c)) erreur = true; // on n'accepte que de l'hexadecimal
break;
}
if (!erreur) i++; // s'il n'y a pas eu d'erreur continuer l'analyse de la chaine
}
// la boucle d'analyse de la chaine est terminee
if (erreur) return TYPE_UNKNOWN; // s'il y a eu une erreur l'automate n'a rien reconnu
else { // l'automate a reconnu un type mais il peut etre de format incorrect
switch (etatAtteint) { // terminer l'analyse en fonction du type que l'on pense avoir reconnu
case 11 : // probablement du bluetooth => verifier la taille
if (adresse.length() <= TAILLE_BLUETOOTH) return TYPE_BLUETOOTH;
else return TYPE_UNKNOWN;
case 12 : // probablement du IEEE => verifier l'etat final de l'automate et le nombre de champs
if ((compteIEEE == TAILLE_IEEE-1) && (etat == 7)) return TYPE_IEEE;
else return TYPE_UNKNOWN;
case 14 : // probablement du IPv4 => verifier le nombre de champs et la validite (0 a 255) du dernier
if ((compteV4 == TAILLE_IPV4-1) && ((etat == 1) || (etat == 2) || (etat == 3))) {
if (testePartieIPV4(partieIPV4)) return TYPE_IPV4;
else return TYPE_UNKNOWN;
}
else return TYPE_UNKNOWN;
case 16 : // probablement du IPv6 => verifier l'etat final de l'automate, le nombre de champs et le nombre de champs vides
if ((compteV6 == TAILLE_IPV6-1) && (compteVide <=1) && ((etat == 1) || (etat == 2) || (etat == 4) || (etat == 5) || (etat == 8))) return TYPE_IPV6;
else if ((compteV6 == GROUPES_BLUETOOTH-1) && (compteVide ==0) && ((etat == 1) || (etat == 2) || (etat == 4) || (etat == 5))) return TYPE_BLUETOOTH;
else return TYPE_UNKNOWN;
default :
if (((etat == 1) || (etat == 2) || (etat == 3) || (etat == 4) || (etat == 5) || (etat == 7)) && (adresse.length() <= TAILLE_BLUETOOTH)) {
return TYPE_BLUETOOTH;
}
else return TYPE_UNKNOWN;
}
}
}
// teste les chiffres decimaux
private boolean isDecimal(char c) {
if ((c=='0')||(c=='1')||(c=='2')||(c=='3')||(c=='4')||(c=='5')||(c=='6')||(c=='7')||(c=='8')||(c=='9')) return true;
else return false;
}
// teste les caracteres hexadecimaux
private boolean isHexadecimal(char c) {
if (isDecimal(c)) return true;
else {
if ((c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F')||(c=='a')||(c=='b')||(c=='c')||(c=='d')||(c=='e')||(c=='f')) return true;
else return false;
}
}
// teste qu'un champ IPv4 soit bien entre 0 et 255
private boolean testePartieIPV4(String partie) {
int x = -1;
try { x = Integer.parseInt(partie); }
catch (NumberFormatException nfe) { return false; }
if ((x>=0) && (x<256)) return true;
else return false;
}
// enleve les 0 de debut de champs en IPv4
private String reduitIPv4(String adr) {
if (adr == null) return null;
int pos1, pos2=-1, pos3=-1;
pos1 = adr.indexOf(separateurIPv4);
if (pos1 != -1) pos2 = adr.indexOf(separateurIPv4,pos1+1);
if (pos2 != -1) pos3 = adr.indexOf(separateurIPv4,pos2+1);
String p1 = adr.substring(0,pos1);
String p2 = adr.substring(pos1+1,pos2);
String p3 = adr.substring(pos2+1,pos3);
String p4 = adr.substring(pos3+1);
return (enleveZeros(p1)+"."+enleveZeros(p2)+"."+enleveZeros(p3)+"."+enleveZeros(p4));
}
// enleve les 0 de debut de champs en IPv6
private String reduitIPv6(String adr) {
if (adr == null) return null;
int pos1, pos2=-1, pos3=-1, pos4=-1, pos5=-1, pos6=-1, pos7=-1, pos8 = -1;
pos1 = adr.indexOf(separateurIPv6);
if (pos1 != -1) pos2 = adr.indexOf(separateurIPv6,pos1+1);
if (pos2 != -1) pos3 = adr.indexOf(separateurIPv6,pos2+1);
if (pos3 != -1) pos4 = adr.indexOf(separateurIPv6,pos3+1);
if (pos4 != -1) pos5 = adr.indexOf(separateurIPv6,pos4+1);
if (pos5 != -1) pos6 = adr.indexOf(separateurIPv6,pos5+1);
if (pos6 != -1) pos7 = adr.indexOf(separateurIPv6,pos6+1);
if (pos7 != -1) pos8 = adr.indexOf(separateurZoneIPv6,pos7+1);
String p1 = adr.substring(0,pos1);
String p2 = adr.substring(pos1+1,pos2);
String p3 = adr.substring(pos2+1,pos3);
String p4 = adr.substring(pos3+1, pos4);
String p5 = adr.substring(pos4+1, pos5);
String p6 = adr.substring(pos5+1, pos6);
String p7 = adr.substring(pos6+1, pos7);
String p8;
if (pos8==-1) p8 = adr.substring(pos7+1);
else p8 = adr.substring(pos7+1, pos8);
String resultat = (enleveZeros(p1)+":"+enleveZeros(p2)+":"+enleveZeros(p3)+":"+enleveZeros(p4)+":"+enleveZeros(p5)+":"+enleveZeros(p6)+":"+enleveZeros(p7)+":"+enleveZeros(p8));
return resultat;
}
// enleve les 0 de debut en bluetooth
private String reduitBluetooth(String adr) {
String resultat = "";
if (!adr.contains(":")) { // adresse bluetooth sans :
boolean fini = false;
for (int i = 0; i<adr.length(); i++) {
char c = adr.charAt(i);
if (fini) resultat = resultat+c;
else {
if (adr.charAt(i) != '0') {
resultat = resultat+c;
fini = true;
}
}
}
if (resultat.length() == 0) resultat = "0";
}
else { // adresse bluetooth avec :
int pos1, pos2=-1, pos3=-1, pos4=-1, pos5=-1, pos6=-1, pos7=-1, pos8 = -1;
pos1 = adr.indexOf(separateurIPv6);
if (pos1 != -1) pos2 = adr.indexOf(separateurIPv6,pos1+1);
if (pos2 != -1) pos3 = adr.indexOf(separateurIPv6,pos2+1);
if (pos3 != -1) pos4 = adr.indexOf(separateurIPv6,pos3+1);
if (pos4 != -1) pos5 = adr.indexOf(separateurIPv6,pos4+1);
if (pos5 != -1) pos6 = adr.indexOf(separateurIPv6,pos5+1);
String p1 = adr.substring(0,pos1);
String p2 = adr.substring(pos1+1,pos2);
String p3 = adr.substring(pos2+1,pos3);
String p4 = adr.substring(pos3+1, pos4);
String p5 = adr.substring(pos4+1, pos5);
String p6 = adr.substring(pos5+1);
resultat = (enleveZeros(p1)+":"+enleveZeros(p2)+":"+enleveZeros(p3)+":"+enleveZeros(p4)+":"+enleveZeros(p5)+":"+enleveZeros(p6));
}
return resultat;
}
// met tous les champs a 3 chiffres en IPv4
private String etendIPv4(String adr) {
if (adr == null) return null;
int pos1, pos2=-1, pos3=-1;
pos1 = adr.indexOf(separateurIPv4);
if (pos1 != -1) pos2 = adr.indexOf(separateurIPv4,pos1+1);
if (pos2 != -1) pos3 = adr.indexOf(separateurIPv4,pos2+1);
String p1 = adr.substring(0,pos1);
String p2 = adr.substring(pos1+1,pos2);
String p3 = adr.substring(pos2+1,pos3);
String p4 = adr.substring(pos3+1);
return (etendATroisCaracteres(p1)+"."+etendATroisCaracteres(p2)+"."+etendATroisCaracteres(p3)+"."+etendATroisCaracteres(p4));
}
// met tous les champs a 2 chiffres en IPv6
private String etendIPv6(String adr) {
if (adr == null) return null;
int pos1, pos2=-1, pos3=-1, pos4=-1, pos5=-1, pos6=-1, pos7=-1, pos8 = -1;
pos1 = adr.indexOf(separateurIPv6);
if (pos1 != -1) pos2 = adr.indexOf(separateurIPv6,pos1+1);
if (pos2 != -1) pos3 = adr.indexOf(separateurIPv6,pos2+1);
if (pos3 != -1) pos4 = adr.indexOf(separateurIPv6,pos3+1);
if (pos4 != -1) pos5 = adr.indexOf(separateurIPv6,pos4+1);
if (pos5 != -1) pos6 = adr.indexOf(separateurIPv6,pos5+1);
if (pos6 != -1) pos7 = adr.indexOf(separateurIPv6,pos6+1);
if (pos7 != -1) pos8 = adr.indexOf(separateurZoneIPv6,pos7+1);
String p1 = adr.substring(0,pos1);
String p2 = adr.substring(pos1+1,pos2);
String p3 = adr.substring(pos2+1,pos3);
String p4 = adr.substring(pos3+1, pos4);
String p5 = adr.substring(pos4+1, pos5);
String p6 = adr.substring(pos5+1, pos6);
String p7 = adr.substring(pos6+1, pos7);
String p8;
if (pos8==-1) p8 = adr.substring(pos7+1);
else p8 = adr.substring(pos7+1, pos8);
String resultat = (etendADeuxCaracteres(p1)+":"+etendADeuxCaracteres(p2)+":"+etendADeuxCaracteres(p3)+":"+etendADeuxCaracteres(p4)+":"+etendADeuxCaracteres(p5)+":"+etendADeuxCaracteres(p6)+":"+etendADeuxCaracteres(p7)+":"+etendADeuxCaracteres(p8));
return resultat;
}
// met l'addresse sur 12 chiffrres en bluetooth
private String etendBluetooth(String adr) {
String resultat = "";
if (!adr.contains(":")) {
int lg = TAILLE_BLUETOOTH - adr.length();
for (int i=0; i<lg; i++) resultat = resultat+"0";
resultat=resultat+adr;
}
else {
int pos1, pos2=-1, pos3=-1, pos4=-1, pos5=-1, pos6=-1, pos7=-1, pos8 = -1;
pos1 = adr.indexOf(separateurIPv6);
if (pos1 != -1) pos2 = adr.indexOf(separateurIPv6,pos1+1);
if (pos2 != -1) pos3 = adr.indexOf(separateurIPv6,pos2+1);
if (pos3 != -1) pos4 = adr.indexOf(separateurIPv6,pos3+1);
if (pos4 != -1) pos5 = adr.indexOf(separateurIPv6,pos4+1);
if (pos5 != -1) pos6 = adr.indexOf(separateurIPv6,pos5+1);
String p1 = adr.substring(0,pos1);
String p2 = adr.substring(pos1+1,pos2);
String p3 = adr.substring(pos2+1,pos3);
String p4 = adr.substring(pos3+1, pos4);
String p5 = adr.substring(pos4+1, pos5);
String p6 = adr.substring(pos5+1);
resultat = (etendADeuxCaracteres(p1)+":"+etendADeuxCaracteres(p2)+":"+etendADeuxCaracteres(p3)+":"+etendADeuxCaracteres(p4)+":"+etendADeuxCaracteres(p5)+":"+etendADeuxCaracteres(p6));
}
return resultat;
}
// enleve les 0 de debut sur un champs IPv4
private String enleveZeros(String part) {
switch (part.length()) {
case 3:
if (part.charAt(0) == '0') {
if (part.charAt(1) == '0') return new String(part.substring(2));
else return new String(part.substring(1));
}
else return part;
case 2:
if (part.charAt(0) == '0') return new String(part.substring(1));
else return part;
case 1:
return part;
case 0:
return "0";
default:
return part;
}
}
// ramene un champ IPv4 a une longueur de 3
private String etendATroisCaracteres(String part) {
switch (part.length()) {
case 3:
return part;
case 2:
return "0"+part;
case 1:
return "00"+part;
case 0:
return "000";
default:
return part;
}
}
// ramene un champ IPv6 a une longueur de 2
private String etendADeuxCaracteres(String part) {
switch (part.length()) {
case 2:
return part;
case 1:
return "0"+part;
case 0:
return "00";
default:
return part;
}
}
}