最近开发一款网络安全检测工具, 有一个需求是生成两个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); }
总是要在实践中检验真理。