0

I have a list of user IP addresses like following:

user 1:

192.168.1.1
192.168.1.2
192.168.1.3


user 2: 

192.168.1.1
192.168.1.2
192.168.1.3
172.0.0.1
172.0.0.5
174.5.5.15

Now what I'd like to do here is to filter out all the IP's that are obviously from the same subnet/coming from the same PC/City.

I'm only using local IP's as an example here.

After filtering I would be left with the following:

For user 1 it is enough for me to have only 1 IP from each subnet like following:

192.168.1.1 => all other IP's would be removed, only one would be left 
   from that specific subnet

For user 2:

192.168.1.1
172.0.0.1
174.5.5.15

For the user 2 I'm left with 3 IP's since 192.168.. and 172.0.. had multiple ip's from that range.

Now my idea is to use a criteria for the first two numbers of the IP to be compared. For example:

192.168.0.1
192.168.0.2
192.168.0.6

These 3 have same first two numbers (192.168), thus I can consider them as duplicates and they should be removed. Which ever 1 of the IP's is left here from these is irrelevant, what matters is is that only 1 is left.

This would result in 1 ip to be left, for example:

192.168.0.1 (again doesn't matter which one is left, just that 1 is left!)

Now onto the part with code. I have a class structure like following:

public class SortedUser
{
    public string Email { get; set; }

    public List<IpInfo> IPAndCountries = new List<IpInfo>();

}

And IPInfo class looks like this:

   public class IpInfo
    {

        public string Ip { get; set; }

    }

Can someone help me out with this now? How can I do it in most easiest way?

User987
  • 3,663
  • 15
  • 54
  • 115
  • When you say remove all from the same subnet, you need to consider the subnet mask you are applying. See http://www.subnet-calculator.com - Can you add notes to say what subnets you would like removed? – Kami Aug 08 '18 at 08:21
  • 1
    Possible duplicate of [How to calculate the IP range when the IP address and the netmask is given?](https://stackoverflow.com/questions/1470792/how-to-calculate-the-ip-range-when-the-ip-address-and-the-netmask-is-given) – Kami Aug 08 '18 at 08:22
  • @Kami Sry maybe I've expressed myself wrong... Let's just say that all ip's that have same first two numbers should be removed, and only 1 of those would be left. Ignoring subnets and all that... – User987 Aug 08 '18 at 08:22
  • @Kami no no it's not a duplicate... I just wanna delete same ip's from my list that have same first two numbers, if this is easier way to say it .... – User987 Aug 08 '18 at 08:23

1 Answers1

1

If you are looking for only the first two bytes in the list of addresses, you can run a string comparison like so (not tested):

SortedUser user = new SortedUser()
{
    Email = "Foo@bar.com",
    IPAndCountries = new List<IpInfo>()
    {
        new IpInfo() {Ip = "192.168.0.1"},
        new IpInfo() {Ip = "192.168.1.2"},
        new IpInfo() {Ip = "193.168.3.2"},
        new IpInfo() {Ip = "8.2.4.5"}
    }
};

// Using ToArray to avoid collection modified errors
foreach (IpInfo item in user.IPAndCountries.ToArray())
{

    string[] ipSplit = item.Ip.Split('.');

    string prefix = $"{ipSplit[0]}.{ipSplit[1]}";
    user.IPAndCountries.RemoveAll(info => info.Ip.StartsWith(prefix) && info.Ip != item.Ip);
}
Kami
  • 19,134
  • 4
  • 51
  • 63
  • Hey Kami, it says on the remove part: Remove(p=>p.StartsWith(prefix) && p != ipToSearchFor) following : cannot convert lambda expression to type "IpInfo" because it is not a delegatE? – User987 Aug 08 '18 at 08:35
  • @User987 Corrected - in the earlier code I was comparing the object itself against string, rather than the Ip property. – Kami Aug 08 '18 at 08:38
  • for some reason it still displays the same error =/ – User987 Aug 08 '18 at 08:40
  • or maybe : var Range = IpAndCountries.where(p=>p.Ip.StartsWith(prefix) && p.Ip != ipToSearchFor).ToList() and then IpAndCountries.RemoveRange(Range); ? – User987 Aug 08 '18 at 08:41
  • @User987 I do not have access to VS atm, but you should be able to adapt this to your needs. – Kami Aug 08 '18 at 08:41
  • The only thing that I'm uncertain of is that part with "ip to search for" ... The IP that I wouldn normally filter won't be just 192.168.. that was just an example =( – User987 Aug 08 '18 at 08:45
  • The updated example will work now as expected. We are iterating over list of values assigned to the SortedUser object. – Kami Aug 08 '18 at 09:01