using System; using System.Collections.Generic; using System.Linq; namespace IP_Filtering { class Program { static void Main(string[] args) { Console.WriteLine(IsInStringContext("192.168.0.1")); //Should return true Console.WriteLine(IsInStringContext("192.168.0.2")); //Should return true Console.WriteLine(IsInStringContext("192.168.0.3")); //Should return false Console.WriteLine(IsInStringContext("192.168.1.133")); //Should return true (in range) Console.WriteLine(IsInStringContext("192.168.4.54")); //Should return true (in range) Console.WriteLine(IsInStringContext("192.168.4.53")); //Should return false (not in range) Console.WriteLine(IsInStringContext("192.168.2.34")); //Should return true (in CIDR range) Console.WriteLine(IsInStringContext("192.168.3.34")); //Should return false (not in CIDR range) Console.WriteLine(IsInStringContext("192.168.3.212")); //Should return true (in CIDR range) !! } private static readonly List StringDataContext = new List{ "192.168.0.1", "192.168.0.2", "192.168.1.0 - 192.168.1.255", "192.168.2.0/24", "192.168.3.128/25", "192.168.4.54 - 192.168.4.62" }; public static bool IsInStringContext(string ip) { //Check if it's explicitly in the data context if (StringDataContext.Exists(d => d == ip)) return true; var givenIPOctets = ip.Split('.'); //Next, check if it's in range //For this, I am going to assume IP ranges can only be a range of the last octet foreach (string address in StringDataContext.Where(sdc => sdc.Contains('-'))) { string[] addresses = address.Replace(" ", "").Split('-'); string[] firstAddressOctets = addresses[0].Split('.'); string[] secondAddressOctets = addresses[1].Split('.'); //Make sure first three octets are the same if (givenIPOctets[0] != firstAddressOctets[0] || givenIPOctets[1] != firstAddressOctets[1] || givenIPOctets[2] != firstAddressOctets[2]) { continue; } int ipAddressLastOctet = int.Parse(givenIPOctets[3]); int firstAddressLastOctet = int.Parse(firstAddressOctets[3]); int secondAddressLastOctet = int.Parse(secondAddressOctets[3]); if (ipAddressLastOctet >= firstAddressLastOctet && ipAddressLastOctet <= secondAddressLastOctet) return true; } //Lastly, check if it's in CIDR range. //Again, I'm going to assume IP ranges can only be part of the last octet. foreach (string address in StringDataContext.Where(sdc => sdc.Contains('/'))) { string[] ipAddress = address.Split('/'); string[] octets = ipAddress[0].Split('.'); if (givenIPOctets[0] != octets[0] || givenIPOctets[1] != octets[1] || givenIPOctets[2] != octets[2]) { continue; } int maxOctet = (int)Math.Pow(2, 32 - int.Parse(ipAddress[1])) + int.Parse(octets[3]); if (int.Parse(givenIPOctets[3]) >= int.Parse(octets[3]) && int.Parse(givenIPOctets[3]) <= maxOctet) return true; } return false; } } }