2 回答
TA贡献1796条经验 获得超4个赞
更新:在 ipv6 的情况下使用 BigInt 以响应下面的评论
请参阅此解决方案。
对于 IPv4 使用:
ipv4.split('.').reduce(function(int, value) { return int * 256 + +value })
对于 IPv6,您首先需要解析十六进制值,十六进制值代表 2 个字节:
ipv6.split(':').split(':').map(str => Number('0x'+str)).reduce(function(int, value) { return BigInt(int) * BigInt(65536) + BigInt(+value) })
我还在引用的要点中添加了 ipv6 解决方案。
TA贡献1765条经验 获得超5个赞
const IPv4ToInt = ipv4 => ipv4.split(".").reduce((a, b) => a << 8 | b) >>> 0;
和一个简单的 IPv6 实现:
const IPv6ToBigInt = ipv6 => BigInt("0x" + ipv6.toLowerCase().split(":").map(v => v.padStart(4, 0)).join(""));
或更广泛的
// normalizes several IPv6 formats to the long version
// in this format a string sort is equivalent to a numeric sort
const normalizeIPv6 = (ipv6) => {
// for embedded IPv4 in IPv6.
// like "::ffff:127.0.0.1"
ipv6 = ipv6.replace(/\d+\.\d+\.\d+\.\d+$/, ipv4 => {
const [a, b, c, d] = ipv4.split(".");
return (a << 8 | b).toString(16) + ":" + (c << 8 | d).toString(16)
});
// shortened IPs
// like "2001:db8::1428:57ab"
ipv6 = ipv6.replace("::", ":".repeat(10 - ipv6.split(":").length));
return ipv6.toLowerCase().split(":").map(v => v.padStart(4, 0)).join(":");
}
const IPv6ToBigInt = ipv6 => BigInt("0x" + normalizeIPv6(ipv6).replaceAll(":", ""));
// tests
[
"2001:0db8:85a3:08d3:1319:8a2e:0370:7344",
"2001:0db8:85a3:08d3:1319:8a2e:0370:7345", // check precision
"2001:db8:0:8d3:0:8a2e:70:7344",
"2001:db8:0:0:0:0:1428:57ab",
"2001:db8::1428:57ab",
"2001:0db8:0:0:8d3:0:0:0",
"2001:db8:0:0:8d3::",
"2001:db8::8d3:0:0:0",
"::ffff:127.0.0.1",
"::ffff:7f00:1"
].forEach(ip => console.log({
ip,
normalized: normalizeIPv6(ip),
bigInt: IPv6ToBigInt(ip).toString() // toString() or SO console doesn't print them.
}));
.as-console-wrapper{top:0;max-height:100%!important}
- 2 回答
- 0 关注
- 134 浏览
添加回答
举报