Checking for a Valid SIN Number


Project 4 - Option 1

Introduction

This project is one of two options you can select for project 4. Do either this project (Project 4 - Option 1) or do Option 2. Do not do both.

Carefully checking text data entered into a form and providing good error messages is an important part of creating a useful form. Users may enter characters such as hypens, commas, or spaces to separate segments of a number or may inadvertantly add a space character while editing data at the beginning of a text field. From a script writer's perspective this can add a great deal of scripting complexity in order to correctly handle all the possibilities. Consider the Canadian Social Insurance number. It is a nine digit number that is usually written in three segments of three digits. How will a user enter this number in a form? HTML forms do not provide very sophisticated text entry fields with configurable templates. If an HTML text field is used, what data should a script accept as valid? Which one of the examples in this list seem reasonable?

From a scripter's perspective the first format is the easiest to check for. It is a nine digit number with no nondecimal number characters. To help the user realise what is needed an HTML input tag with the MaxLength attribute set to 9 might help. For example:

<INPUT Type="Text" Name="SIN" Size="10" MaxLength="9">

On the other hand, from a user's perspective this restriction is a little annoying. When someone tries to type in a number in the wrong format they will not be able to enter the last two digits and will have to go back and edit out the space or hyphens they have used. Even though technically it may not take much more than deleting a couple of characters this may be enough to make someone give up. In fact, while we could arbitrarily decide that only one of the first three formats is correct this is needlessley restrictive and is being done for the scripters convenience when we should really be worrying about the user's convenience.

A more friendly approach might be to use three input text fields this way:

Enter Your Social Insurance Number: - -

Since each field only accepts 3 characters all you have to do is check that each one contains only the characters: 0123456789. This solution is simple, easy to implement, and presents a clear picture to the user of what is required of them. From the user's perspective, its only real disadvantage is that is takes an extra two clicks or tabs to fill in two extra fields.

Validation Procedure

Fortunately, the Canadian Government provides social insurance numbers that can be checked using a fairly straight forward method. Here is an excerpt from document T4127(E), Payroll Deductions Formulas for Computer Programs (71st Edition Effective January 1, 2000) published by Revenue Canada that describes it:

 

Validation of the Social Insurance Number (SIN)

Human Resources Development Canada uses the SIN and employee information we provide them to maintain accurate records of employee contributions and earnings. To minimize the enquiries you receive, we recommend that you include a SIN validity check as part of your payroll program.

A SIN has nine digits. The first eight digits are the basic number while the ninth digit is a check digit. You can check whether or not a SIN is valid by using the following verification method.

Example

The employee provides Social Insurance Number 193-456-787. You can check the validity of the number by calculating the check digit as follows:

 
Basic number (first eight digits) Check digit

193 456 78

7

Make a number from each alternate position to the left
beginning at the second digit


9


4


6


8

Add the number to itself

9

4

6

8

Sum

18

8

12

16

Cross-add the digits in the sum (1 + 8 + 8 + 1 + 2 + 1 + 6) =

27

Add each alternate digit beginning at the first digit (1 + 3 + 5 + 7) =

16

Total

43

If the total is a multiple of 10, the check digit should be 0; otherwise, subtract
the total calculated (43) from the next highest number ending in zero (50)


50

The check digit is (50 - 43)

7 =

7

Social Insurance Numbers that do not pass the validation check

If the SIN provided by an individual does not pass the verification check, the preparer should confirm the SIN with the employer who received the original number. If you are unable to obtain the correct number for the employee, please do NOT leave the SIN field on the information slip blank. Instead, report the SIN that was provided, even if it is not a valid number. Frequently, even an incorrect number will enable us to find a match so that we can correct the record and ensure the employee receives proper credit for the deductions.

 

Instead of worrying about how the user formats the SIN number we can simply extract the nine digits they provide and check that it is a proper SIN number using the method described above.

Project Description

  1. Create a form with a single field and button labelled "SIN Number Validation" that contains the following elements:
    1. A single text prompt: "Enter your SIN number here:";
    2. A single text input field named "SIN" with no initial value;
    3. A JavaScript button with the value "Check your SIN Number" that calls (use the onClick handler) a function named checkSIN(str) and that passes it a reference to the current value of the SIN text field.
  2. Implement the checkSIN(str) function, str is the variable name you should use to pass the string containing the SIN number into the function, so that it:
    1. implements the validation method described above;
    2. reports in an alert box if the SIN number is valid or not.

Hints

With any problem - even one as small/large (depends on your experience) as this - it is useful to take a few minutes and work through some of the problems you know you will encounter before trying to code a solution. After looking at the problems you will be in a better position to design a solution and then implement it. Here are some questions you might be asking yourself about how to do this and some answers to help you on your way. The answers obviously incomplete, are provided as hints and are not the only way to solve the problem. Please use them to make this project easier - don't feel compelled to invent different ways unless you feel like it.

Collecting the Nine Digits

Question: How do I collect the nine digits the user enters if they also enter spaces, hyphens etc?

An Answer: Create an empty string variable and loop through the str string character by character. Append only the characters that are decimal digits to the new string. Use the new string - with only digits in it - to test for a valid SIN. Don't forget to check that there are exactly nine digits! If chr is a variable containing a single character string and newStr is the string it is to be appended to then:

newStr = newStr + chr

will append the character in chr on the end of the newStr string. Or, you can do exactly the same thing this way using the += operator:

newStr += chr

Even or Odd positioned Characters

Question: How do I "make a number from each alternate position to the left beginning at the second digit?"

An Answer: Basically, you are being asked to extract the even numbered digits from the string. You could loop through the string testing to see if each digit is evenly divisible by 2 but be careful, remember that JavaScript strings starts with character number 0 but that in the example above the first character is numbered as number 1 so what is even in the example is odd in a JavaScript string:

for (i = 0; i < newStr.length - 1; i++){
   if (i % 2 != 0){ 
      // do something here with even positioned character newStr.charAt(i)
   }
}

Note: the loop only goes to newStr.length - 1 because the last digit is the check digit.

Another Answer: If you just want the even numbered characters you could also:

for (i = 1; i < newStr.length - 1; i += 2){
   // do something here with newStr.charAt(i)
}

Note: i += 2 adds two to i so that we skip over the odd numbered positions.

Yet Another Answer: You may choose to loop through the string once and get the even numbered digits and the odd numbered digits in one pass:

for (i = 0; i < newStr.length - 1; i++){
   if (i % 2 != 0){ 
      // do something here with even positioned newStr.charAt(i)
   }
   else{
      // do something here with odd positioned newStr.charAt(i)
   }
}

Converting between Strings and Numbers

Question: OK, I've got an even positioned character, how do I add it to itself?

An Answer: You could multiply by two. If the character is in a variable named chr, then

chr * 2

will force the JavaScript interpreter to convert chr to a number if it can because the * operator requires two numbers.

Another Answer: You could use the parseInt() function to convert a character to a number and then add it to itself:

n = parseInt(chr)
n = n + n

Adding Digits

Question: How do I "cross-add" the digits in a sum?

Answer: Some how you have to add up the digits and not just the numbers. For example doubling the number nine gave the number 18, but now you are supposed to add 1 + 8. One way to do this is to convert the numbers into strings again and then extract each character, convert it into a number and add its numeric value to a variable that holds the sum of all the numbers. Converting a number to a string can be done this way:

chr = "" + n

The + operator concatentates a string and a number so adding an empty string and the number will convert the number to a string.

Another Answer: Any number greater than 9 will have a second digit. To get the same result as adding the two digits together subtract nine from the number. For example:

if (n > 9){
   n = n - 9
}

Make sure this works by trying it out!

Question: How do you get the sum of a group of numbers?

An Answer: Here is a loop that takes a string variable, extracts each character, and assuming it contains a decimal digit adds it to a variable named sum. When the loop is complete the variable sum will hold the result of adding all the digits together.

tempStr = "9468"  //for illustration purposes a string with some decimal digits in it
sum = 0           //important to set it to zero before we start.
for (i = 0; i < tempStr.length; i++){
   sum += parseInt(tempStr.charAt(i))
}

Here is some code that does the same thing but does not use parseInt() or the += operator.

tempStr = "9468"  //for illustration purposes a string with some decimal digits in it
sum = 0           //important to set it to zero before we start.
for (i = 0; i < tempStr.length; i++){
   sum = sum + tempStr.charAt(i) * 1
}

Simplifying Your Code

You may feel you are ready to start writing code. Take a moment to make sure you understand each step in the SIN validation method and think about how you are going to implement it. Then try to build a function that does this one step at a time. As you progress where are you going to keep your interim results? In what variable? What should they be called? As you work use alert() statements to check that you are really getting correct interim results. Are you getting every number digit the user enters? Are you getting only the even numbers, only the odd numbers? Are you doubling the even numbers correctly? Are you adding all the numbers together correctly. Use alert() statements to test as you go!

When you have everything working, see if you can simplify your code. Can you do this with fewer steps? Can you replace many statements with a single loop?

Keep it Readable

Since you may not solve this problem all at once, you should try to keep you code well formatted and readable. Use variable names that explain what is to be stored in each variable. Format it nicely and comment it for when you come back to it, so you remember what you were trying to do.

Test it!

Make sure you use the number provided above to test your function. Create some numbers that are not valid SIN numbers according to the validation test described above and make sure your function rejects them. For example, in the example provided above the final digit, or check digit is seven. Since the entire point of the test is to derive from the first eight digits a number equal to the last digit we know that if you change the last number in 193-456-787 to anything other than seven, the number is not a valid SIN number.