it-swarm.com.de

Konvertierung von IPv6 nach Long und Long nach IPv6

Wie soll ich eine Konvertierung von IPv6 nach Long und umgekehrt durchführen?

Bisher habe ich:

    public static long IPToLong(String addr) {
            String[] addrArray = addr.split("\\.");
            long num = 0;
            for (int i = 0; i < addrArray.length; i++) {
                    int power = 3 - i;

                    num += ((Integer.parseInt(addrArray[i], 16) % 256 * Math.pow(256, power)));
            }
            return num;
    }

    public static String longToIP(long ip) {
            return ((ip >> 24) & 0xFF) + "."
                    + ((ip >> 16) & 0xFF) + "."
                    + ((ip >> 8) & 0xFF) + "."
                    + (ip & 0xFF);

    }

Ist es die richtige Lösung oder habe ich etwas verpasst?

(Es wäre perfekt, wenn die Lösung sowohl für ipv4 als auch für ipv6 funktionieren würde.)

15
Testeross

Eine IPv6-Adresse ist eine 128-Bit-Nummer wie beschrieben hier . Ein Long in Java wird mit 64 Bit dargestellt, daher benötigen Sie eine andere Struktur, z. B. ein BigDecimal oder zwei Longs (ein Container mit einem Array von zwei Longs oder einfach einem Array von zwei Longs), um eine IPv6-Adresse zu speichern.

Unten ist ein Beispiel (nur um Ihnen eine Idee zu geben):

public class Asd {

public static long[] IPToLong(String addr) {
    String[] addrArray = addr.split(":");//a IPv6 adress is of form 2607:f0d0:1002:0051:0000:0000:0000:0004
    long[] num = new long[addrArray.length];

    for (int i=0; i<addrArray.length; i++) {
        num[i] = Long.parseLong(addrArray[i], 16);
    }
    long long1 = num[0];
    for (int i=1;i<4;i++) {
        long1 = (long1<<16) + num[i];
    }
    long long2 = num[4];
    for (int i=5;i<8;i++) {
        long2 = (long2<<16) + num[i];
    }

    long[] longs = {long2, long1};
    return longs;
}


public static String longToIP(long[] ip) {
    String ipString = "";
    for (long crtLong : ip) {//for every long: it should be two of them

        for (int i=0; i<4; i++) {//we display in total 4 parts for every long
            ipString = Long.toHexString(crtLong & 0xFFFF) + ":" + ipString;
            crtLong = crtLong >> 16;
        }
    }
    return ipString;

}

static public void main(String[] args) {
    String ipString = "2607:f0d0:1002:0051:0000:0000:0000:0004";
    long[] asd = IPToLong(ipString);

    System.out.println(longToIP(asd));
}

}

9
Andrei I

Sie können auch Java.net.InetAddress verwenden
Es funktioniert sowohl mit ipv4 als auch mit ipv6 (alle Formate)

public static BigInteger ipToBigInteger(String addr) {
    InetAddress a = InetAddress.getByName(addr)
    byte[] bytes = a.getAddress()
    return new BigInteger(1, bytes)
}
14
Guigoz

Eine IPv6-Adresse kann nicht lange gespeichert werden. Sie können BigInteger anstelle von long verwenden.

public static BigInteger ipv6ToNumber(String addr) {
    int startIndex=addr.indexOf("::");

    if(startIndex!=-1){


        String firstStr=addr.substring(0,startIndex);
        String secondStr=addr.substring(startIndex+2, addr.length());


        BigInteger first=ipv6ToNumber(firstStr);

        int x=countChar(addr, ':');

        first=first.shiftLeft(16*(7-x)).add(ipv6ToNumber(secondStr));

        return first;
    }


    String[] strArr = addr.split(":");

    BigInteger retValue = BigInteger.valueOf(0);
    for (int i=0;i<strArr.length;i++) {
        BigInteger bi=new BigInteger(strArr[i], 16);
        retValue = retValue.shiftLeft(16).add(bi);
    }
    return retValue;
}


public static String numberToIPv6(BigInteger ipNumber) {
    String ipString ="";
    BigInteger a=new BigInteger("FFFF", 16);

        for (int i=0; i<8; i++) {
            ipString=ipNumber.and(a).toString(16)+":"+ipString;

            ipNumber = ipNumber.shiftRight(16);
        }

    return ipString.substring(0, ipString.length()-1);

}

public static int countChar(String str, char reg){
    char[] ch=str.toCharArray();
    int count=0;
    for(int i=0; i<ch.length; ++i){
        if(ch[i]==reg){
            if(ch[i+1]==reg){
                ++i;
                continue;
            }
            ++count;
        }
    }
    return count;
}
7
Vinod

Vinods Antwort ist richtig. Es gibt jedoch noch einige Dinge, die verbessert werden können. (Entschuldigung, ich kann unter Vinods Antwort keinen Kommentar einfügen, da ich neu hier bin.)

Zunächst sollte in der Methode 'countChar' 'continue' durch 'break' ersetzt werden.

Und zweitens müssen einige Randbedingungen berücksichtigt werden.

public static BigInteger ipv6ToNumber(String addr) {
    int startIndex = addr.indexOf("::");
    if (startIndex != -1) {
        String firstStr = addr.substring(0, startIndex);
        String secondStr = addr.substring(startIndex + 2, addr.length());
        BigInteger first = new BigInteger("0");
        BigInteger second = new BigInteger("0");
        if (!firstStr.equals("")) {
            int x = countChar(addr, ':');
            first = ipv6ToNumber(firstStr).shiftLeft(16 * (7 - x));
        }
        if (!secondStr.equals("")) {
            second = ipv6ToNumber(secondStr);
        }
        first = first.add(second);
        return first;
    }

    String[] strArr = addr.split(":");
    BigInteger retValue = BigInteger.valueOf(0);
    for (int i = 0; i < strArr.length; i++) {
        BigInteger bi = new BigInteger(strArr[i], 16);
        retValue = retValue.shiftLeft(16).add(bi);
    }
    return retValue;
}

public static int countChar(String str, char reg){
    char[] ch=str.toCharArray();
    int count=0;
    for(int i=0; i<ch.length; ++i){
        if(ch[i]==reg){
            if(ch[i+1]==reg){
                ++i;
                break;
            }
            ++count;
        }
    }
    return count;
}
1
gaofc