我正在重构我的代码,并希望使用IPAddress.TryParse方法来验证字符串是否为有效的IPv4地址,而不是使用正则表达式:
public static bool IsIPv4(string value)
{
IPAddress address;
if (IPAddress.TryParse(value, out address))
{
if (address.AddressFamily == AddressFamily.InterNetwork)
{
return true;
}
}
return false;
}我的单元测试现在失败了,因为这些输入值返回true并被解析为以下IPAddress对象:
value = "0.0.0.0" -> address = {0.0.0.0}
value = "255.255.255" -> address = {255.255.0.255}
value = "65536" -> address = {0.1.0.0}这有意义吗?我可以看出,从技术上讲,0.0.0.0是一个有效的IPv4地址,即使用户输入这个地址没有任何意义。那另外两个呢?为什么它们以这种方式转换,我应该将它们视为有效的,即使这对用户可能不是透明的,他们可能只是忘记输入句点(65536而不是6.5.5.36)。
任何帮助都是非常感谢的。
发布于 2011-02-24 04:46:17
看起来,IPAddress.Parse的文档通过指出输入较少的部分可以方便地输入A类和B类地址,对这种行为进行了合理的解释。如果您想强制使用由四部分组成的地址,我想在将其提供给IPAddress.TryParse之前,您可能只需要检查地址中是否有三个句号。
下面是一些代码供您参考:
// verify that IP consists of 4 parts
if (value.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Length == 4)
{
IPAddress ipAddr;
if (IPAddress.TryParse(value, out ipAddr))
{
// IP is valid
}
else
// invalid IP
}
else
// invalid IP发布于 2011-02-24 05:48:40
IPAddress.TryParse()的任务不是检查字符串是否为有效的IP地址,而是检查字符串的内容是否可以解析(即转换)为有效的IP地址。
测试用例中的所有选项实际上都可以解析为表示和IP。归根结底,你的测试用例是有效的。问题是测试用例的数据是无效的,或者您没有在测试用例中使用正确的工具来获得预期的结果。
如果你专门测试一个有效的IPv4,有4个四边形(每个是0-255之间的整数),并且想要避免正则表达式,那么你可以拆分,然后解析和验证。
public static bool IsIPv4(string value)
{
var octets = value.Split('.');
// if we do not have 4 octets, return false
if (octets.Length!=4) return false;
// for each octet
foreach(var octet in octets)
{
int q;
// if parse fails
// or length of parsed int != length of octet string (i.e.; '1' vs '001')
// or parsed int < 0
// or parsed int > 255
// return false
if (!Int32.TryParse(octet, out q)
|| !q.ToString().Length.Equals(octet.Length)
|| q < 0
|| q > 255) { return false; }
}
return true;
}发布于 2011-02-24 04:48:24
如果您希望对输入非常严格,那么可以比较解析后的IPAddress的ToString()版本,如果它们不同,则拒绝输入。
全零地址和其他类似的东西必须作为特殊情况处理。
https://stackoverflow.com/questions/5096780
复制相似问题