RB-Technical-Test/IP-Filtering/Program.cs

80 lines
3.5 KiB
C#
Raw Normal View History

2020-06-26 12:56:07 +00:00
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<string> StringDataContext = new List<string>{
"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;
}
}
}