Saturday, April 25, 2009

Social Insurance Numbers

Here in Canada, our equivalent of the Social Security Number is called Social Insurance Number. It serves the same purpose and has the same demands for privacy surrounding it.

Once again, I won't be posting the full source code on the blog, only on Snipplr, but I will discuss briefly how it works. It consists of three groups of three digits, and is validated using the Luhn algorithm. I also do a quick regular expression validation to check for numbers which invalidly begin with an eight: ^([1-79]{3})[\-\s]?(\d{3})[\-\s]?(\d{3})$.

Saturday, April 18, 2009

Social Security Numbers

Assuming that you have a legitimate need to capture social security numbers (human resources app?), you may want to validate and format them consistently. The actual code for both languages combined is a little bit too long to post, so I'll just talk about the algorithm.

A social security number is a nine-digit number and can be matched with the following regular expression: ^\d{3}\-?\d{2}\-?\d{4}$. If it can't pass this test, it's not a valid social security number. However, passing this simple test doesn't guarantee validity, so we need to keep checking.

  • No digit group can consist of only zeros, and the first group cannot be 666. We check for these errors with the following regular expression: ((000|666)\-?\d{2}\-?\d{4}|\d{3}\-?00\-?\d{4}|\d{3}\-?\d{2}\-?0000.

  • Numbers from 987-65-4320 to 987-65-4329 are reserved for use in advertisements, and other previously legitimate numbers have been invalidated because of use in advertisments. We check for these errors with the following regular expression: 987\-?65\-?432\d{1}|042\-?10\-?3580|062\-?36\-?0749|078\-?05\-?1120|095\-?07\-?3645|128\-?03\-?6045|135\-?01\-?6629|141\-?18\-?6941|165\-?(16|18|20|22|24)\-?7999|189\-?09\-?2294|212\-?09\-?(7694|9999|219\-?09\-?9999|306\-?30\-?2348|308\-?12\-?5070|468\-?28\-?8779|549\-?24\-?1889)

  • Last but not least, the first three numbers are never higher than 772 (well, not yet; this could change in the future). For this I used a simple string conversion and numeric comparison.

The complete, commented source code is available on Snipplr:

Next week we'll head north of the border to my country and see what the Canadian equivalent of the Social Security Number is, and how we can validate them.

Saturday, April 11, 2009

Homeland Security Advisory System

Back in 2002, a bunch of bureaucrats decided that the United States needed an advisory system so that all federal departments and agencies could communicate what the current threat condition was using the same definitions. Sounds like a good idea to me.

The average citizen can see what the current threat condition is by visiting certain government web sites. The web site for the Department of Homeland Security is a good example.

The Department of Homeland Security also provides a little-known web service which returns the threat condition in XML format so that you can do what you want with it. Let's write a function to retrieve and parse this information down to just the threat condition itself.


  1. function getThreatLevel()

  2.     dim regEx

  3.     set regEx = new RegExp

  4.     with regEx

  5.         .Pattern = ".*\n.*CONDITION=""(.*)"" />"

  6.         .IgnoreCase = true

  7.         .Global = true

  8.     end with

  9.     dim xmlhttp

  10.     set xmlhttp = Server.CreateObject("Msxml2.ServerXMLHTTP")

  11. "GET", "", "False"

  12.     xmlhttp.send

  13.     getThreatLevel = regEx.replace(xmlhttp.responseText, "$1")

  14.     set xmlhttp = nothing

  15.     set regEx = nothing

  16. end function

As is often the case, the PHP version requires a significantly less amount of code.


  1. function getThreatLevel()

  2. {

  3.     return eregi_replace('.*CONDITION="(.*)" />', '\1', file_get_contents(""));

  4. }

So now we have a string that contains just the word "ELEVATED" (or whatever the current threat level is at the moment; it's been at elevated for several years at the time of this writing). What can you do with it? Feed it into a switch statement and display an image is one possibility.

Saturday, April 4, 2009


SQL contains a number of aggregate functions that can do things like select the largest or smallest number from a set of values. This could be handy in the programming language itself.


  1. function max(arrNumbers)
  2.     dim result
  3.     result = arrNumbers(0)
  4.     for each i in arrNumbers
  5.         if i > result then
  6.             result = i
  7.         end if
  8.     next
  9.     max = result
  10. end function
  11. function min(arrNumbers)
  12.     dim result
  13.     result = arrNumbers(0)
  14.     for each i in arrNumbers
  15.         if i < result then
  16.             result = i
  17.         end if
  18.     next
  19.     min = result
  20. end function

View ASP implementation on Snipplr