diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv6Util.java b/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv6Util.java index 4dc3ff144..c2bc4563c 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv6Util.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv6Util.java @@ -60,10 +60,30 @@ public class Ipv6Util { * @return IPv6字符串, 如发生异常返回 null */ public static String bigIntegerToIPv6(final BigInteger bigInteger) { + // 确保 BigInteger 在 IPv6 地址范围内 + if (bigInteger.compareTo(BigInteger.ZERO) < 0 || bigInteger.compareTo(new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)) > 0) { + throw new IllegalArgumentException("BigInteger value is out of IPv6 range"); + } + + // 将 BigInteger 转换为 16 字节的字节数组 + byte[] bytes = bigInteger.toByteArray(); + if (bytes.length > 16) { + // 如果字节数组长度大于 16,去掉前导零 + final int offset = bytes[0] == 0 ? 1 : 0; + final byte[] newBytes = new byte[16]; + System.arraycopy(bytes, offset, newBytes, 0, 16); + bytes = newBytes; + } else if (bytes.length < 16) { + // 如果字节数组长度小于 16,前面补零 + final byte[] paddedBytes = new byte[16]; + System.arraycopy(bytes, 0, paddedBytes, 16 - bytes.length, bytes.length); + bytes = paddedBytes; + } + + // 将字节数组转换为 IPv6 地址字符串 try { - return InetAddress.getByAddress( - bigInteger.toByteArray()).toString().substring(1); - } catch (final UnknownHostException ignore) { + return Inet6Address.getByAddress(bytes).getHostAddress(); + } catch (final UnknownHostException e) { return null; } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/net/Ipv6UtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/net/Ipv6UtilTest.java new file mode 100644 index 000000000..3849c3877 --- /dev/null +++ b/hutool-core/src/test/java/org/dromara/hutool/core/net/Ipv6UtilTest.java @@ -0,0 +1,15 @@ +package org.dromara.hutool.core.net; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.math.BigInteger; + +public class Ipv6UtilTest { + @Test + void bigIntegerToIPv6Test() { + final BigInteger bigInteger = new BigInteger("21987654321098765432109876543210", 10); + final String ipv6Address = Ipv6Util.bigIntegerToIPv6(bigInteger); + Assertions.assertEquals("0:115:85f1:5eb3:c74d:a870:11c6:7eea", ipv6Address); + } +}