This blog has, IMO, some great resources. Unfortunately, some of those resources are becoming less relevant. I'm still blogging, learning tech and helping others...please find me at my new home on http://www.jameschambers.com/.

Tuesday, May 5, 2009

Slightly Better Version

Last week I posted a function to convert an IP address to its decimal value using c#.

I have a mildly better approach, though by better, admittedly, I really just mean “I’m using some new stuff from the current version of c#”.

It occurred to me that in place of the anonymous delegate I could just as easily use a lambda expression, therefore we end up with this approach:

private static string IpToDecimal(string ipAddress)
{
// split up the IP into octets and prep our string builder
List<string> octets = new List<string>(ipAddress.Split('.'));
long decIP = 0;
int shift = 3;

// loop through the octets and compute the decimal version
octets.ForEach(octet => { decIP += long.Parse(octet) << (shift * 8); shift--; });
return decIP.ToString();
}



Now, if you wanted to, you could really use var instead of List<string> and you could likely inline the initialization, but that ends up unreadable.



HOWEVER if you are adamant about using new things, like LINQ, lambda expressions and the language features of c# to convert this bad boy over, you can do it!



I just wouldn’t likely throw this code at the rookie…



private static string IpToDecimal2(string ipAddress)
{
// need a shift counter
int shift = 3;

// split and loop through the octets
var octets = ipAddress.Split('.').Select(p => long.Parse(p));
return octets.Aggregate(0L, (total, octet) =>
(total + (octet << (shift-- * 8)))).ToString();
}



This is actually cool because it’s really only three lines of code.  A couple of things to note:




  1. Using LINQ we are able to parse out the string bits and convert the octets to longs with the Select method.


  2. I’m using the Aggregate method and passing in a seed of 0, which I type with L so that the compiler doesn’t see it as an int.


  3. total is used to keep the running track; octet is the parameter passed in from the octets collection.


  4. shift is decremented each pass as we walk across the octets.

2 comments:

  1. A little dense but you could collapse all the way to:

    _ipString
    .Split('.')
    .Select((q, index) =>
    (long) Math.Pow(256, 3 - index)*int.Parse(q))
    .Sum()
    .ToString();

    ReplyDelete
  2. heheh...i don't know if yours or mine is harder to read ;o)

    ReplyDelete