diff --git a/CHANGELOG.md b/CHANGELOG.md index 12a79a2a5..30275df37 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * 【core 】 优化NumberUtil.count(pr#3772@Github) * 【crypto 】 SM2.signHex改名为signHexFromHex,原名标记废弃,避免歧义(issue#IB0NVY@Gitee) * 【all 】 优化所调用的ObjectUtil#defaultIfNull避免重复创建(pr#1274@Gitee) +* 【core 】 NetUtil.bigIntegerToIPv6增加长度修正(issue#IB27HV@Gitee) ### 🐞Bug修复 * 【json 】 修复JSONConfig.setDateFormat设置后toBean无效问题(issue#3713@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java b/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java index 720e6bc3a..cc135fa2e 100755 --- a/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java @@ -108,9 +108,30 @@ public class NetUtil { * @since 5.5.7 */ public static String bigIntegerToIPv6(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,去掉前导零 + 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,前面补零 + 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 (UnknownHostException ignore) { + return Inet6Address.getByAddress(bytes).getHostAddress(); + } catch (UnknownHostException e) { return null; } } diff --git a/hutool-core/src/test/java/cn/hutool/core/net/NetUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/net/NetUtilTest.java index d64b567e5..803eeae92 100755 --- a/hutool-core/src/test/java/cn/hutool/core/net/NetUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/net/NetUtilTest.java @@ -3,15 +3,18 @@ package cn.hutool.core.net; import cn.hutool.core.lang.Console; import cn.hutool.core.lang.PatternPool; import cn.hutool.core.util.ReUtil; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.math.BigInteger; import java.net.HttpCookie; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.List; +import static org.junit.jupiter.api.Assertions.*; + /** * NetUtil单元测试 * @@ -126,4 +129,11 @@ public class NetUtilTest { final String ip = NetUtil.getMultistageReverseProxyIp(ips); assertEquals("12.34.56.78", ip); } + + @Test + void bigIntegerToIPv6Test() { + BigInteger bigInteger = new BigInteger("21987654321098765432109876543210", 10); + String ipv6Address = NetUtil.bigIntegerToIPv6(bigInteger); + Assertions.assertEquals("0:115:85f1:5eb3:c74d:a870:11c6:7eea", ipv6Address); + } }