Ipv6 D-如何验证IP地址是否有效
我正在编写一个HTTP解析库(因为我在纯D中找不到一个好的解析库),我需要能够验证IP地址(对于URI字段),所以我编写了两个函数来验证IP地址: 对于IPv4:Ipv6 D-如何验证IP地址是否有效,ipv6,ipv4,d,phobos,Ipv6,Ipv4,D,Phobos,我正在编写一个HTTP解析库(因为我在纯D中找不到一个好的解析库),我需要能够验证IP地址(对于URI字段),所以我编写了两个函数来验证IP地址: 对于IPv4: bool isIPv4(string addr) { int parts; ulong idx; foreach (i, c; addr) { if (c == '.') { if (i == 0) { return false;
bool isIPv4(string addr) {
int parts;
ulong idx;
foreach (i, c; addr) {
if (c == '.') {
if (i == 0) {
return false;
}
if (to!int(addr[idx..i]) > 255) {
return false;
}
parts++;
if (parts > 3) {
return false;
}
idx = i + 1;
} else if (!isDigit(c)) {
return false;
}
}
if (to!int(addr[idx..addr.length]) > 255) {
return false;
}
if (parts != 3) {
return false;
}
return true;
}
对于IPv6:
bool isIPv6(string addr) {
bool isColon, hasSeparator, hasIPv4;
int leftChunks, rightChunks, digits;
foreach (i, c; addr) {
if (isHexDigit(c)) {
digits = isColon ? 1 : digits + 1;
isColon = false;
if (digits == 1) {
if (hasSeparator) {
rightChunks++;
} else {
leftChunks++;
}
} else if (digits > 4) {
return false;
}
} else if (c == ':') {
if (isColon) {
// multiple :: separators not allowed
// as is :::
if (hasSeparator) {
return false;
}
hasSeparator = true;
} else {
isColon = true;
}
} else if (c == '.') {
if (hasSeparator) {
rightChunks--;
} else {
leftChunks--;
}
if (!isIPv4(addr[i - digits .. addr.length])) {
return false;
}
hasIPv4 = true;
break;
}
}
if (hasIPv4) {
if (hasSeparator) {
if (rightChunks + leftChunks > 5) {
return false;
}
} else if (leftChunks != 6) {
return false;
}
} else if (digits > 0) {
if (hasSeparator) {
if (rightChunks + leftChunks > 7) {
return false;
}
} else if (leftChunks != 8) {
return false;
}
}
return true;
}
我最初试图为IPv6设计一个正则表达式,但这很痛苦,特别是因为有太多特殊情况(代码:),我想我遇到了一个正则表达式编译错误,因为它太长了。显然,我想使用一些标准函数来完成这项工作
FWIW,我使用std.arrays.split实现了IPv4验证程序,然后我决定这样做,因为否则我必须检测或捕获std.conv.to的异常!内部的
非常感谢
注意
最后,我想尝试将我编写的一些代码写入Phobos,因此我希望代码尽可能可靠。您可以使用操作系统提供的inet\u pton()函数。它将解析一个地址,并告诉您地址是否错误。看
它将解析IPv4和IPv6地址,并且可以使用inet_ntop()将解析后的地址转换回其规范符号。@tjameson:很久以前,我就入侵了自己的
uri
模块。以下是代码:。我一直想回到那个模块,改进它,并在GitHub提交一个拉请求,但从来没有时间去做。。。URI RFC还有一个正则表达式,用于解析URI中的IPv6地址,这肯定是我在这段代码中要用到的内容。怎么样?试试:
IPv4
IPv6
(使用ECMAscript语法)
发件人:
有没有跨平台的方式来称呼这一点?它会出现在std.linux和std.windows中吗?
inet\u pton
仅在以windows Vista开始的windows版本上可用。我知道它在标准C库中(准确地说是单UNIX规范v3,2001),因此它可能被移植到许多平台和语言。但我对D的了解还不够,无法为您指出正确的库。很抱歉遗憾的是,只有Win Vista支持它,但这是合乎逻辑的,因为较旧的Windows版本有一个完全不同的IP堆栈,IPv6只是在之后添加的。正则表达式的优点很好。我想我会重温正则表达式路线。我试图制作一个覆盖IPv6所有边缘情况的文件,但结果太长了(当我试图静态编译它时,D的正则表达式引擎吐了)。您知道IPv6有九种不同的形式吗?一旦您使用regexp从dl.net.uri
获取主机,那么您只需调用std.socket.parseUri(主机)
:)你知道它是否有任何DNS请求吗?对某些请求来说似乎是这样的,我想避免这种情况。由于我正在编写一个HTTP解析器,我只想知道它是什么类型的地址,IPv4、IPv6还是域名。好吧,你可以在这里亲眼看到:)文档上说:“不尝试名称解析。”它能得到多清晰?CyberShadow,如果文档的示例没有尝试使用address.toHostNameString()解析主机名,可能会更清楚。或者,如果解析失败时它没有抛出SocketException,而是抛出InvalidAddressException或类似的东西。谢谢!我一定错过了。我在那里看到了getAddressInfo注释,我没有看到任何地方没有尝试DNS解析。太谢谢你了!
/^(((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?!$)|$)){4}$
/^((?=(?=(.*?::))\2(?!.+::))(::)?([\dA-F]{1,4}:(:|(?!$))|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:(?!$)|$))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?!$)|$)){4})$/i