Thursday, December 31, 2009

Five best things I didn't get for Christmas


I'm posting this here so that I can find it again. This is Life Hacker's most popular Hive Five Topics of 2009.

I hadn't seen this before I bought my Netbook but it turns out that the one I bought was an update to the most voted Netbook on their Five Best Netbooks posting.

Wednesday, December 23, 2009

Managing IP addresses as integers

I was recently involved in a discussion about IP addresses and discovered that not everyone understands an IP address. I was told that an IP address is not an integer. Well, it is an integer, a 32-bit integer, but it is rarely represented as such. It is usually represented as four octets joined together with periods.

This is what most people know as an IP address: 127.0.0.1 and if I showed you the value 2130706433 you probably wouldn't recognize it as the same IP address.

I blogged some extension methods in Converting a string IP to and int and back that will help you if you need to convert an IP between the two formats using C#. The code is fairly obvious and easily ported to other languages.

The question often asked is why do you need to convert it?

The answer is speed and space.

Most often, when you receive an IP address it is in the string notation. Storing it in this notation inefficient because it takes between 7 (0.0.0.0) and 15 (255.255.255.255) bytes to store each address. Compare this to storing it as an Int32 which takes 4 bytes each time. A space saving of between 42% and 73%.

My advice is to convert it into an Int32 as soon as you receive it and then work with it as such from there onwards. Working with an IP as an Int32 will be faster because sorting and comparing Int32's will outstrip the same when using strings. Setting up an index against an Int32 column in a database will also be faster and smaller than doing the same against a varchar column.

When you need to show an integer IP to a user you'll need to convert it back to its string notation. This is easily done with the extension methods linked above.

The only draw back to using this approach for managing IP addresses is when you list IP's directly from your database. If they were stored as strings they'd be easy to recognize but listed as integers they're pretty useless.

Converting a string IP to an int and back

I often need to convert a string IP to an Int32 and then back again. To facilitate converting an Int32 to its string representation I have added this extension method to my IntExtensions class in C#:

public static class IntExtensions
{
    /// <summary>
    /// Converts an integer that represents an IPv4 to the string equivalent
    /// Source: http://guyellisrocks.com/coding/converting-a-string-ip-to-an-int-and-back/
    /// </summary>
    /// <param name="solidIP">The integer representation of an IPv4</param>
    /// <returns>A string of the format x.x.x.x representing an IPv4</returns>
    public static string ToIPv4(this int solidIP)
    {
        byte ip1 = (byte)(solidIP >> 24);
        byte ip2 = (byte)(solidIP >> 16);
        byte ip3 = (byte)(solidIP >> 8);
        byte ip4 = (byte)(solidIP);
        return ip1 + "." + ip2 + "." + ip3 + "." + ip4;
    }
}

And to convert the string representation of an IP to an Int32 I have added this extension method to my StringExtensions class:

public static class StringExtensions
{
    /// <summary>
    /// Converts a string that holds an IPv4 address with the pattern x.x.x.x
    /// to the integer equivalent. If the string cannot be split into 4 parts
    /// using a . or if the 4 parts cannot by parsed
    /// into bytes then 0 will be returned.
    /// Source: http://guyellisrocks.com/coding/converting-a-string-ip-to-an-int-and-back/
    /// </summary>
    /// <param name="IP">A string representing an IPv4 address</param>
    /// <returns>An integer representing an IPv4 address or zero if failure</returns>
    public static int ToIPv4(this string IP)
    {
        try
        {
            string[] fourIP = IP.Split('.');

            Int32 ip =
                (Byte.Parse(fourIP[0]) << 24) +
                (Byte.Parse(fourIP[1]) << 16) +
                (Byte.Parse(fourIP[2]) << 8) +
                Byte.Parse(fourIP[3]);

            return ip;
        }
        catch
        {
            return 0;
        }
    }
}

 

Monday, December 21, 2009

Vertical Wireless Router


While I was researching the buying of a new wireless router I read a customer review comment on a router that said something about a particular router/model that would overheat if left in the horizontal position which would cause connections to be dropped. This intrigued me because my router/modem/wireless access point has always lived in the horizontal position and is prone to rebooting when a wireless device connects to it. So my theory is that more of this device is in use when a wireless device is connected to it so it might get hotter.
Could this be the problem with the flaky wireless that I have?
Well after reading that I tried standing the router vertically and have been aggressivley using the wireless and so far (a couple of days) we have had no disconnects. The evidence points to the overheating in the horizontal position, so far. The jury is still out on this one though because I know as well as anyone else that this could be a fluke and we may return to flakiness in the near future. I'll update this post in a couple of months with more info.

Saturday, December 19, 2009

Belkin N+ Wireless Router

The ASUS Netbook that I mentioned in this post arrived yesterday and I've started playing with it. So far it's good and a bit faster than I was expecting. The only two changes that I was going to make to it before buying it were to replace the 250GB drive with a 128GB SSD (Solid State Drive) and upgrade the RAM from 1GB to 2GB. However, it's a lot nippier than expected so will not worry about that yet. It arrived with Windows 7 Starter. I stuck in a thumb drive and immediately installed Windows 7 Ultimate. It was really tricky getting it to boot from the thumb drive because the hot key that you had to hit to get to the BIOS and then to pick the "boot from USB option" was difficult to time. You basically had to hit the escape key twice immediately after it was powered on.

It supports the new (yet to be finished) higher speed network standard of 802.11 N. My current wireless access point goes up to G and is flaky (update on why it might be flaky) often knocking the modem offline if a wireless device is connected to it. As such I've just been doing a whole ton of research to see what I can add to my network that will give me that best quality wireless and hopefully last several years. I hate shopping for stuff like this that I'm not expert in as I never know if I'm going to get a good deal or not. I'm also suspicious of the specs published by many of the comparison sites and even the manufacturer as they are sometimes inaccurate and I never know if the customer reviews are written by the company trying to boost their product or by a competitor trying to discredit their product.

Anyway I had to make a decision and finally went with the BELKIN N+ Wireless Router. I was comparing this to the BELKIN N Wireless Router and the only difference that I could find was that the N+ has gigabit ports while the N has 10/100MBS ports. Considering that I'm all about speed and constantly wanting to saturate my network I selected the former. I'll report back when it's installed.

Tuesday, December 15, 2009

Windows Powershell v2

For whatever reason it just seems impossible for any search engine to provide the correct link to download PowerShell 2 so I'm making a note of it here on my blog so that I can easily find it again:

http://connect.microsoft.com/windowsmanagement/Downloads

 

ASUS Eee PC Seashell 1005HA

I'm in the process of buying:

ASUS Eee PC Seashell 1005HA-PU17-BU Royal Blue 10.1" WSVGA Netbook

from NewEgg. I will post more details here once I get the product.

I tried to customize the HP Mini 311 from the HP web site but it wouldn't let me order one with 3GB of RAM and Windows XP. Insisted that I order Windows 7 at an extra $50 if I wanted 3GB of RAM. According to the sales rep and the web site Windows XP does not support 3GB of RAM. Tell that to the millions of users with 3GB of RAM and Windows XP.

If you're thinking about buying one of these then wait a couple of days until after I've bought it. The price usually plummets as soon as I've bought something like this.

Update:

12/18/2009: First impressions of the ASUS Netbook.

Monday, December 14, 2009

XMarks Bookmark Synchronization

Last week I installed XMarks Bookmark Synchronizer and I am impressed. I use 4 browsers (sometimes 6 if you include IE6 and IE7) and keeping my bookmarks in sync on all the browsers and across all machines is a real problem. I regularly use about 5 different machines so with my 4 regular browsers that makes 20 browsers that I would like to keep in-sync. XMarks makes this a breeze.

XMarks supports IE8 (probably IE6 and IE7 but haven't installed on these so don't know), Firefox, and Chrome. I don't believe that it supports Opera or at least I haven't found something that will work with Opera and XMarks yet.

When you install it do so on your browser that has your definitive or most comprehensive set of bookmarks and when walking through the wizard select the option to synchronize your bookmarks. On subsequent browsers you want to select the option to blow away your local bookmarks and use the ones on the server.

After that, any book mark you add, delete or modify on any browser will then be synchronized with all other browsers and across multiple machines.

Very impressed with this free utility.

Wednesday, December 9, 2009

NTLM Active Directory Integration in Firefox

At work we use Active Directory to authenticate our internal websites. This is great if you're using Internet Explorer because it will pass through to the application without requiring further authentication. However, on Firefox you're required to make some changes to get this to work.

Open Firefox and go to about:config

Filter on "auth"

Set all booleans to true

Set network.automatic-ntlm-auth.trusted-uris to a comma separated list of domains that you want AD to do pass through authentication on.

That last instruction never used to work for me. I used to put in the full domain name but for some reason it didn't like it. I've now learned that you only need to put in the trailing part of the domain (TLD/Top Level Domain) and it will authenticate all domains and sub-domains for you.

Say you work for IBM and your internal domains follow a pattern of something.internal.ibm - all you need to do is add ".internal.ibm" to the trusted-uris setting and it will work for you. In fact, all you need to add is ".ibm".

Another thing I often need to do is connect to a site by IP. This will also work by dropping in the last octet of the IP into this list. e.g. ".164" (Obviously you could cover all IP addresses by dropping in all possible 256 octets.)

Here is how to generate all the octets using PowerShell:

$numbers = 0..255 | %{".{0}" -f $_}
$octets = [string]::join(",", $numbers)
$octets

Monday, December 7, 2009

The proxy server is refusing connections in Firefox

If you're a developer and you're using Firefox and you suddenly get this message:

The proxy server is refusing connections

It could be because you closed Fiddler but still have Firefox set to send traffic to Fiddler. Just click on the Fiddler link in your status bar and switch it off or restart Fiddler.

ASP.NET MVC GetTypeHashCode() no suitable method found to override

I was getting this error when running a page from an ASP.NET MVC site and it was driving me batty:

Error Message: c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files!!!!!oot\296bde83\3fd88bdf\App_Web_create.aspx.1486a709.vkhqok-s.0.cs(291): error CS0115: 'ASP.views_mycontroller_create_aspx.GetTypeHashCode()': no suitable method found to override

I fixed it by deleting the old view and creating a new one and then just pasting in the bits I'd already done testing it after each paste to see what it was. This showed nothing.

I then compared the old view with the new one and discovered that the only difference was in the @page directive:

Old View: Inherits="System.Web.Mvc.ViewUserControl<Model.EditorViewModel>"

New View: Inherits="System.Web.Mvc.ViewPage<Model.EditorViewModel>"

Not sure how I ended up with ViewUserControl in the old view instead of ViewPage but this was my error and fixed the problem.

Thursday, December 3, 2009

Changing Graffiti to use Google Analytics Async

Google have just released an asynchronous version of their Google Analytics site tracking code. The main advantage of this is that you can have the code start executing and collecting stats as soon as the page has started loading (because you can put it higher up in the HTML) and it won't interfere with your load times because it's asynchronous.
This blog is running on Graffiti CMS and I was pleasantly surprised at how easy it was to change to the asynchronous version of analytics.
When logged in to your Graffiti CMS site as an admin click on the Control Panel link and then on Site Options. From Site Options click on the Settings box.




At the bottom of the "Your Site Options" page you will see two text areas. If you are already using Google Analytics then you will probably have your code in the first box labeled Web Statistics. Putting your original analytics code in this box is good because this puts the analytics code at the bottom of your page just before the </body> tag.
However, now that we have an asynchronous version of analytics we should put the new code in the second box, the Header box, because this will put the analytics JavaScript in the <head> tag and it will load earlier and also ensure that your page loads faster. (Positioning it in the header won't make your page load faster but the fact that it's asynchronous will.) This is what these two boxes will look like when you've finished editing.



Before you delete your old analytics code from the Web Statistics text area you need to save your site's UA code. This is the only part of your old code that you'll need.
Then you will want to paste the following into the Header part of this page:
<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-X']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>
and replace the UA-XXXXX-X part with your value.
It really is as easy as that. I suddenly have new found respect for Graffiti CMS.