Управление IPv6-адресами в Java

1

Я знаю, что подобные вопросы были заданы раньше, но я не смог найти конкретный ответ, который, кажется, работает. Я в основном пытаюсь написать функцию, которая будет принимать IPv6-адрес и добавить или вычесть произвольное количество IP-адресов.

Я думаю, что у меня проблема с байтовым заказом, поскольку она работает для некоторых IPv6-адресов, но не для других. Тем не менее, мне нужна помощь в попытке решить проблему, поскольку я застрял.

Я представил SSCCE, ниже которого демонстрируется проблема - она в основном преобразуется из InetAddress в BigInteger и обратно - идея состоит в том, чтобы выполнить сложение или вычитание из BigInteger посередине:

import java.math.*;
import java.net.*;

public class SSCCE {
  public static void main(String[] args) {
    String sIPv6 = "::00D3:0:2F3B:02AA:00FF:0";

    try {
      BigInteger n = new BigInteger(InetAddress.getByName(sIPv6).getAddress());
      byte[] bytes = n.toByteArray();

      System.out.println("Original = " + sIPv6);
      System.out.println("New = " + InetAddress.getByAddress(bytes).getHostAddress());
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Когда я запускаю это, я получаю следующий вывод:

Original = ::00D3:0:2F3B:02AA:00FF:0
java.net.UnknownHostException: addr is of illegal length
        at java.net.InetAddress.getByAddress(Unknown Source)
        at java.net.InetAddress.getByAddress(Unknown Source)
        at SSCCE.main(SSCCE.java:12)

Однако, если я изменил адрес IPv6 на "2001 :: 00D3: 0: 2F3B: 02AA: 00FF: 0", тогда он отлично работает.

  • 0
    посмотрите, нравится ли вашей программе '2001: 0: d3: 0: 2f3b: 2aa: ff: 0'
Теги:
ip
ipv6

2 ответа

1
Лучший ответ

Проблема здесь

  BigInteger n = new BigInteger(InetAddress.getByName(sIPv6).getAddress());
  byte[] bytes = n.toByteArray();

Когда вы вызываете toByteArray() возвращаемый массив достаточно велик, чтобы содержать все значимые биты адреса. Поскольку ваш адрес начинается с 0:0:... возвращаемый массив байтов будет слишком коротким (14). Вы должны оставить его с двоичными нулями, чтобы сделать его длиной 128 бит (16 байт).

  • 0
    Да, вы правы. Если я проверю длину, то это 14 вместо 16. Есть ли простой способ дополнить ее до 16? - Я пытался использовать Arrays.copyOf(n, 16) но это дополняет его в конце. Я предполагаю, что мне нужно создать байтовый массив длиной 16 и скопировать в него? Есть указатели?
  • 0
    Я придумал следующее, но не уверен, есть ли более простой способ с использованием одной функции Java? byte [] pbytes = новый байт [16]; int offset = (16 - длина байта); for (int i = offset; i <16; i ++) {pbytes [i] = bytes [i - offset]; }
Показать ещё 1 комментарий
0

Вышеприведенный ответ правильный, но не полный. В дополнение к описанному левому дополнению вы также должны иногда удалять наивысший байт, когда у вас есть 17 байтов, которые могут встречаться для адресов с 8xxx в fxxx в самом высоком байте, как описано в этом ответе: IPv6 ip (fc00: :) addr имеет незаконную длину

Другими словами, вы должны либо расширять, либо сокращать до 16 байт.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню