最近开发一款网络安全检测工具, 有一个需求是生成两个IP段之间的所有合法IP地址, 当然方法有两种,一种就是利用纯数学原理, 比如 192.168.1.1-192.168.254.254 之间的地址,可以利用split 将IP地址分离成4个数字,然后4层循环实现, 这是最低级的方法, 当然也有高级方法, 利用二进制位运算,可以计算出两个IP段之间的所有IP地址, 网络上有一个流传版本, 但是有错误, 我在这里修正一下。
代码如下:
public static List<string> GetIpDistance(string StartIp,string EndIp)
{
uint IStartIp = IpInt(StartIp);
uint IEndIp = IpInt(EndIp);
List<string> IpListInfo = new List<string>();
if (IEndIp >= IStartIp)
{
for (uint ip = IStartIp; ip <= IEndIp; ip++)
{
IpListInfo.Add(IntIp(ip));
}
}
return IpListInfo;
}
public static uint IpInt(string ipStr)
{
string[] ip = ipStr.Split('.');
uint ipcode = 0xFFFFFF00 | byte.Parse(ip[3]);
ipcode = ipcode & 0xFFFF00FF | (uint.Parse(ip[2]) << 0x08);
ipcode = ipcode & 0xFF00FFFF | (uint.Parse(ip[1]) << 0xF);
ipcode = ipcode & 0x00FFFFFF | (uint.Parse(ip[0]) << 0x18);
return ipcode;
}
public static string IntIp(uint ipcode)
{
byte addr1 = (byte)((ipcode & 0xFF000000) >> 0x18);
byte addr2 = (byte)((ipcode & 0x00FF0000) >> 0xF);
byte addr3 = (byte)((ipcode & 0x0000FF00) >> 0x08);
byte addr4 = (byte)(ipcode & 0x000000FF);
return string.Format("{0}.{1}.{2}.{3}", addr1, addr2, addr3, addr4);
}
通过 List<string> IpList = GetIpDistance("192.168.2.1","192.168.10.254"); 调用,
但是调用以后发现,获取的IP段,总是少了一个C段
获得的IP地址起始段应该 从192.168.2.1 开始,上面代码执行结果却从192.168.1.1 开始。
这么明显的错误,网络千篇一律都是这个方法,难道就没有人发现?
正确的方法: << 0xF 改为 0x10 , 也就是10进制的15改为16.
修改后的方法:
public static List<string> GetIpDistance(string StartIp,string EndIp)
{
uint IStartIp = IpInt(StartIp);
uint IEndIp = IpInt(EndIp);
List<string> IpListInfo = new List<string>();
if (IEndIp >= IStartIp)
{
for (uint ip = IStartIp; ip <= IEndIp; ip++)
{
IpListInfo.Add(IntIp(ip));
}
}
return IpListInfo;
}
public static uint IpInt(string ipStr)
{
string[] ip = ipStr.Split('.');
uint ipcode = 0xFFFFFF00 | byte.Parse(ip[3]);
ipcode = ipcode & 0xFFFF00FF | (uint.Parse(ip[2]) << 0x08);
ipcode = ipcode & 0xFF00FFFF | (uint.Parse(ip[1]) << 0x10);
ipcode = ipcode & 0x00FFFFFF | (uint.Parse(ip[0]) << 0x18);
return ipcode;
}
public static string IntIp(uint ipcode)
{
byte addr1 = (byte)((ipcode & 0xFF000000) >> 0x18);
byte addr2 = (byte)((ipcode & 0x00FF0000) >> 0x10);
byte addr3 = (byte)((ipcode & 0x0000FF00) >> 0x08);
byte addr4 = (byte)(ipcode & 0x000000FF);
return string.Format("{0}.{1}.{2}.{3}", addr1, addr2, addr3, addr4);
}
总是要在实践中检验真理。