是否有一个函数可以将ipAddress作为字符串并告诉我它是否是一个不可路由的IP地址?

我试图确定IP地址是否可路由。 例如,如果我收到127.0.0.1,我知道这是环回(即:localhost)。 我无法在.NET或任何其他语言中找到这个函数,所以我开始编写自己的函数,这远远不够完整。

在我花大量时间编写此函数之前,有没有人知道是否存在确定ip地址是否不可路由的函数? 我更喜欢.NET解决方案,但是求助者不能选择,我很乐意转换任何解决方案。

编辑:用function回答我的问题。

我已经通过创建一个函数来回答我自己的问题,该函数检查ip地址(ipv4或ipv6)是否是不可路由的ip地址。 我参考了McKaypost中的wiki文章,找到了很多保留的ip地址( http://en.wikipedia.org/wiki/Reserved_IP_addresses

解:

///  /// ///  ///  /// A null or empty string passed as the ipAddress will return true. An invalid ipAddress will be returned as true.  ///  public static bool IsNonRoutableIpAddress(string ipAddress) { //Reference: http://en.wikipedia.org/wiki/Reserved_IP_addresses //if the ip address string is empty or null string, we consider it to be non-routable if (String.IsNullOrEmpty(ipAddress)) { return true; } //if we cannot parse the Ipaddress, then we consider it non-routable IPAddress tempIpAddress = null; if (!IPAddress.TryParse(ipAddress, out tempIpAddress)) { return true; } byte[] ipAddressBytes = tempIpAddress.GetAddressBytes(); //if ipAddress is IPv4 if (tempIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { if (IsIpAddressInRange(ipAddressBytes, "10.0.0.0/8")) //Class A Private network check { return true; } else if (IsIpAddressInRange(ipAddressBytes, "172.16.0.0/12")) //Class B private network check { return true; } else if (IsIpAddressInRange(ipAddressBytes, "192.168.0.0/16")) //Class C private network check { return true; } else if (IsIpAddressInRange(ipAddressBytes, "127.0.0.0/8")) //Loopback { return true; } else if (IsIpAddressInRange(ipAddressBytes, "0.0.0.0/8")) //reserved for broadcast messages { return true; } //its routable if its ipv4 and meets none of the criteria return false; } //if ipAddress is IPv6 else if (tempIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { //incomplete if (IsIpAddressInRange(ipAddressBytes, "::/128")) //Unspecified address { return true; } else if (IsIpAddressInRange(ipAddressBytes, "::1/128")) //lookback address for localhost { return true; } else if (IsIpAddressInRange(ipAddressBytes, "2001:db8::/32")) //Addresses used in documentation { return true; } return false; } else { //we default to non-routable if its not Ipv4 or Ipv6 return true; } } ///  /// ///  ///  ///  ///  private static bool IsIpAddressInRange(byte[] ipAddressBytes, string reservedIpAddress) { if (String.IsNullOrEmpty(reservedIpAddress)) { return false; } if (ipAddressBytes == null) { return false; } //Split the reserved ip address into a bitmask and ip address string[] ipAddressSplit = reservedIpAddress.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (ipAddressSplit.Length != 2) { return false; } string ipAddressRange = ipAddressSplit[0]; IPAddress ipAddress = null; if (!IPAddress.TryParse(ipAddressRange, out ipAddress)) { return false; } // Convert the IP address to bytes. byte[] ipBytes = ipAddress.GetAddressBytes(); //parse the bits int bits = 0; if (!int.TryParse(ipAddressSplit[1], out bits)) { bits = 0; } // BitConverter gives bytes in opposite order to GetAddressBytes(). byte[] maskBytes = null; if (ipAddress.AddressFamily == AddressFamily.InterNetwork) { uint mask = ~(uint.MaxValue >> bits); maskBytes = BitConverter.GetBytes(mask).Reverse().ToArray(); } else if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { //128 places BitArray bitArray = new BitArray(128, false); //shift  times to the right ShiftRight(bitArray, bits, true); //turn into byte array maskBytes = ConvertToByteArray(bitArray).Reverse().ToArray(); } bool result = true; //Calculate for (int i = 0; i < ipBytes.Length; i++) { result &= (byte)(ipAddressBytes[i] & maskBytes[i]) == ipBytes[i]; } return result; } ///  /// ///  ///  ///  ///  private static void ShiftRight(BitArray bitArray, int shiftN, bool fillValue) { for (int i = shiftN; i < bitArray.Count; i++) { bitArray[i - shiftN] = bitArray[i]; } //fill the shifted bits as false for (int index = bitArray.Count - shiftN; index < bitArray.Count; index++) { bitArray[index] = fillValue; } } ///  /// ///  ///  ///  private static byte[] ConvertToByteArray(BitArray bitArray) { // pack (in this case, using the first bool as the lsb - if you want // the first bool as the msb, reverse things ;-p) int bytes = (bitArray.Length + 7) / 8; byte[] arr2 = new byte[bytes]; int bitIndex = 0; int byteIndex = 0; for (int i = 0; i < bitArray.Length; i++) { if (bitArray[i]) { arr2[byteIndex] |= (byte)(1 << bitIndex); } bitIndex++; if (bitIndex == 8) { bitIndex = 0; byteIndex++; } } return arr2; } 

我找不到其他解决办法,但你基本上已经把它弄下来了:最好检查字节(把IP作为一个字节[4])而不是字符串,但是它还有更多。 记住B级是172.16.0.0/12; 再次,用字节值检查这个更容易,因为你可以在第二个字节的前四位使用位掩码。

某些东西是否“可路由”将基于本地实施。 在某些情况下(例如基于当前子网掩码),某些地址是可路由的,而其他地址则不可路由。

首先,我建议使用System.Net.IPAddress类:

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx

另外,请查看维基百科中的保留IP文章。

http://en.wikipedia.org/wiki/Reserved_IP_addresses