Поделиться через


Detecting repeated parameter values across multiple method calls

So this was actually asked of me once in an "interview style" situation and it took me quite a while to twig that the use of a queue would be required. I can't fully remember the wording of the question but it was basically something like this: "For every thousand session requests recieved by your server, if the same IP address appears 3 times, then flag it as a possible problem/hacker address".

So as I mentioned the use of a queue is the key to this implementation, as controlling the queue size allows us to restrict ourselves to the most recently pased 1000 (or any other limit number) values. In real life I would probably use something more like this implementation for a fixed size queue but right now I've just knocked up something quick and dirty which is not thread safe etc... But it illustrates the general logic.

I'm using a generic queue of strings (in real life I could probably use the System.Net.IPAddress class) and to keep the count (up to 3) of times a address appears in each thousand I use a Dictionary implementation with the IP address strings as my keys. So the logic is:

  • For each IP address passed, add it to the queue
  • If the queue has more than 1000 items, remove the oldest one
  • Upon removal of an address from the queue, also decrement the "per thousand" count associated with it in the Dictionary (if this is 0 or less, ralso emove the dictionary entry)
  • Upon addition of an address to the queue, also increment the "per thousand" count associated with it in the Dictionary (if this is no entry, add it with a count value of 0)

 

and the code works out as: 

  private static bool IsSuspectIP(string address)
 {
 addressQueue.Enqueue(address);
 
 if (addressQueue.Count() > 999)
 {
 string oldAddr = addressQueue.Dequeue();
 DecrementCounter(oldAddr);
 }
 
 IncrementCounter(address);
 
 if (addressCounters[address] >= 2)
 {
 return true;
 }
 return false;
 }

 

  private static void IncrementCounter(string address)
 {
 if (addressCounters.ContainsKey(address))
 {
 addressCounters[address]++;
 }
 else
 {
 addressCounters.Add(address, 0);
 }
 }

  

  private static void DecrementCounter(string address)
 {
 if (addressCounters.ContainsKey(address))
 {
 if (addressCounters[address] < 0)
 {
 addressCounters.Remove(address);
 }
 else
 {
 addressCounters[address]--;
 }
 }
 }

 

Ok, that's end of the coding tests series for now. These were fun(ish) to write and also pretty quick to write (so they've really upped my posting frequency recently). But I do have an overdue requested update to add to my Windows 8 app, and have another app idea to work on, so I need to divert my spare time in that direction again now.