2013-07-26 27 views
12

Nasıl IPv6'dan uzun ve tam tersi dönüştürme yapmalıyım?Dönüştürme IPv6, uzun ve uzun IPv6 için

Şimdiye kadar var:

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); 

    } 

doğru çözüm mü yoksa birşey kaçırdım mı?

cevap

8

IPv6 adresleri tarif here olarak 128 bitlik bir sayıdır

(çözelti IPv4 ve IPv6 hem çalıştı mükemmel olurdu). Java'da uzun bir süre 64 bit olarak temsil edilir, bu yüzden bir IPv6 adresini saklamak için BigDecimal veya iki longs (iki longs dizisi içeren bir kap veya basitçe bir dizi iki long) gibi başka bir yapıya ihtiyacınız vardır. Aşağıda

(sadece size bir fikir sağlamak için) bir örnek:

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)); 
} 

}

+0

Tamam IPv4 hem de IPv6 ile çalışır java.net.InetAddress
kullanabilirsiniz, bunu yapacağız. Dönüşümden ne haber? Bu doğru mu? – Testeross

+0

Bunu test etmek oldukça kolay: longToIP (IPToLong ("122.122.122.124")) komutunu çalıştırın ve bir şey doğru olmadığı anlamına gelen "122.122.122.124" yerine "34.34.34.36" değerini alacaksınız. –

+0

Haklısınız. Neyin yanlış olduğu hakkında bir fikrin var mı? – Testeross

6

bir IPv6 adresi uzun saklanabilir olamaz. BigInteger yerine uzun kullanabilirsiniz.

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; 
} 
10

Ayrıca O (bütün biçimleri)

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

Bu, IP aralığının üst yarısı için negatif sayılar verecektir. Eğer imzasız olmasını istiyorsanız, olumlu değerlerini muhafaza etmek için (yeni BigInteger (1, bayt)) işaret tabelasını geçmeniz gerekir. – OTrain

+0

@OTrain Yorum için teşekkür ederiz. Yanıt güncellendi. – Guigoz