2010-09-21 26 views
5

tôi muốn biết, liệu có thư viện nào tôi có thể sử dụng để chuyển đổi một địa chỉ IPv6 dài hạn (như 2002: 9876: 57AB: 0000: 0000: 0000: 0000: 0001) vào biểu mẫu IPv6 nén (trong trường hợp này: 2002: 9876: 57AB :: 1).Thư viện Java để chuyển đổi địa chỉ IPv6 dài thành dạng nén

Tôi không thể tìm thấy thư viện như vậy. Thư viện này không nên sử dụng bất kỳ IP Api nào, kết nối mạng không được thực hiện.

Tôi đã cố gắng

return Inet6Address.getByName(longAdress).toString(); 

nhưng điều này chỉ thay thế 4 số không có 1 không (trong trường hợp này 2002: 9876: 57AB: 0: 0: 0: 0: 1).

bất kỳ đề xuất nào?

+0

Xem thêm http://stackoverflow.com/q/7043983/21499 –

Trả lời

2
public class Ipv6AddressCompressor { 
    public static String getCompressedAddress(String longAddress) throws UnknownHostException { 
     longAddress = Inet6Address.getByName(longAddress).getHostAddress(); 
     return longAddress.replaceFirst("(^|:)(0+(:|$)){2,8}", "::"); 
    } 
} 

này nên bảo vệ bạn chống lại các địa chỉ không hợp lệ (ném UnknownHostException), và đúng cách sẽ nén trailing địa chỉ ipv4 (tức là 0: 0: 0: 0: 0: 0: 255.255.255.255 -> :: FFFF: FFFF). Điều này cũng sẽ bảo vệ chống lại các địa chỉ đã được nén.

+2

Trừ nó không loại bỏ số không cần thiết, ví dụ như, ' 0000: 0000: 0001' phải là ':: 1' nhưng trở thành' :: 0001' - có thể sửa được bằng cách thực hiện một cái gì đó như 'replaceAll (" (: | ^) 0 + (\\ d) "," $ 1 $ 2 ")' trên kết quả, mặc dù. – gustafc

+0

Bắt tốt. Tuy nhiên, \\ d của bạn phải là [0-9A-Fa-F]. Sẽ cập nhật để khắc phục. –

+0

Thận trọng: Inet6Address.getByName có thể dẫn đến các truy vấn DNS nếu bạn cho ăn, ví dụ: một địa chỉ bị hỏng như ":: 1 ::" vào nó. Điều này có thể mất một vài giây trên một cuộc gọi duy nhất! –

0

Bạn có thể thử mã này. Nó có thể sẽ hoạt động tốt hơn so với tương đương regex (không phải là tôi đã đánh giá nó hay bất kỳ thứ gì). Nó cũng được kiểm tra khá tốt.

Lưu ý rằng bạn sẽ cần sử dụng biểu diễn dạng số (trong byte[]) của địa chỉ IP. Để có được nó, bạn có thể làm InetAddress.getByName(ip).getAddress() nếu bạn cần phân giải tên máy chủ hoặc sử dụng lớp tiện ích mặt trời IPAddressUtil.textToNumericFormatV6(ip) để phân tích cú pháp từ địa chỉ IP không có độ phân giải của máy chủ.

private static final char[] ipv6conseqZeroFiller = { ':', ':' }; 
private static final char ipv6hextetSeparator = ':'; 

/* 
* Convert numeric IPv6 to compressed format, where 
* the longest sequence of 0's (with 2 or more 0's) is replaced with "::" 
*/ 
public static String ipv6toCompressedForm(byte[] src) { 
    assert src.length == 16; 
    //Find the longest sequence of 0's 
    int cmprHextet = -1; //start of compressed region (hextet index) 
    int cmprSize = 0; //length of compressed region 
    for (int hextet = 0; hextet < 8;) { 
     int curByte = hextet * 2; 
     int size = 0; 
     while (curByte < src.length && src[curByte] == 0 
       && src[curByte + 1] == 0) { 
      curByte += 2; 
      size++; 
     } 
     if (size > cmprSize) { 
      cmprHextet = hextet; 
      cmprSize = size; 
     } 
     hextet = (curByte/2) + 1; 
    } 
    if (cmprHextet == -1 || cmprSize < 2) { 
     //No compression can be applied 
     return ipv6toStr(src); 
    } 
    StringBuilder sb = new StringBuilder(39); 
    ipv6toStr(sb, src, 0, cmprHextet); 
    sb.append(ipv6conseqZeroFiller); 
    ipv6toStr(sb, src, cmprHextet + cmprSize, 8); 
    return sb.toString(); 
} 

/* 
* Convert numeric IPv6 to standard (non-compressed) format. 
* 
* Borrowed from Inet6Address.java #numericToTextFormat(byte[]) 
* Changed StringBuffer -> StringBuilder and ":" -> ':' for performance. 
*/ 
public static String ipv6toStr(byte[] src) { 
    assert src.length == 16; 
    StringBuilder sb = new StringBuilder(39); 
    ipv6toStr(sb, src, 0, 8); 
    return sb.toString(); 
} 

private static final void ipv6toStr(StringBuilder sb, byte[] src, 
     int fromHextet, int toHextet) { 
    for (int i = fromHextet; i < toHextet; i++) { 
     sb.append(Integer.toHexString(((src[i << 1] << 8) & 0xff00) 
       | (src[(i << 1) + 1] & 0xff))); 
     if (i < toHextet - 1) { 
      sb.append(ipv6hextetSeparator); 
     } 
    } 
} 
5

java-ipv6 là thư viện rất phong phú về điều đó. Nó cũng xử lý các dải địa chỉ tốt.

1

The open-source IPAddress Java library có thể phân tích cú pháp địa chỉ ip và tạo nhiều chuỗi. Disclaimer: Tôi là người quản lý dự án của thư viện đó.

đang

Ví dụ:

String ipv6 = "2002:9876:57AB:0000:0000:0000:0000:0001"; 
    try { 
     IPAddressString str = new IPAddressString(ipv6); 
     IPAddress addr = str.toAddress(); 
     String compressed = addr.toCompressedString(); 
     System.out.println(compressed); // 
    } catch(IPAddressStringException e) { 
     //e.getMessage has validation error 
    } 

đầu ra:

2002:9876:57ab::1