Validate Irish PPS Number with JavaScript and jQuery 14

I’ve been quite busy the last few weeks since I started a new role but they have been very interesting since I am working on a project that allows me to get in touch with a few cutting-edge technologies that I had no professional experience with, namely .NET Framework 4.5, Entity Framework 5, ASP.NET MVC 4 and jQuery. I will say upfront that I am fortunate enough to have had the help of a close friend who is acting as my mentor in this new technologies, kudos to Mr. Bruno Bernardo.

So, last week, I had to implement something that would validate the Irish Personal Public Service Number (PPSN) in both format and check sum. It had to be validated in both client and server side and I the fact that I found the solution so simple and there seems to be no information on the web about this validation algorithm, that I felt it was worth to blog about it so others could implement it easier and faster.

My main source of information was this nice article from Wikipedia, containing pretty good information about what is the Irish Personal Public Service Number (PPSN), what his format should be and how to calculate the check digit.

Having all the information I need, on to the code. First, we would need to validate the format of the PPSN entered and that is the easy part because we will simply use a regular expression to check it. You can find more information about Regular Expressions here. According to the source article:

The format of the PPS number is seven digits plus a check character. A second character may be used. If so it is always a ‘W’.
With effect from 1 st January 2013 the Department will be introducing a new range of PPS numbers by including an additional alphabetic character, other than “W”, in position 9 (e.g. 1234567TA).

The regular expression to capture this would be /^(\d{7})([A-Z]{1,2})$/i. Just to explain a little bit for those not so familiar with regular expressions, we have a group of 7 digits ((\d{7})), plus one OR two alphabetical character(s) ((A-Z])). Note that the ReGex has an “i” at the end and that means it is case insensitive.

After sorting that out, we will use the following JavaScript code to validate the PPSN format on our HTML page:

function ValidatePPS(value) {
var formatRegex = /^(\d{7})([A-Z]{1,2})$/i;

if (!formatRegex.test(value)) {
return "The format of the provided PPSN is invalid"; }

The above code will test the received value against the Regular Expression and it will return a message saying the PPSN format doesn’t meet the requirements. After this, we need to validate the check character, to see if it is valid. Again, according to the information provided here and here:

In reverse order, each digit is multiplied by a weight, 2, 3, and so on until the first digit is multiplied by 8. Add up each result. Divide by 23 and the remainder (modulus 23) will indicate the character position on the alphabet.

Thus the PPS number 1234567 will be calculated as the sum of 7*2, 6*3, 5*4, 4*5, 3*6, 2*7 and 1*8. This 112 when divided by 23 leaves a remainder of 20. The twentieth letter of the English alphabet is ‘T’. The correct PPS number is therefore 1234567T. Where the remainder is zero, the check letter is W.

A weighting of 9 will be assigned to the numeric equivalent of the alphabetic character in position 9.

Accordingly the check character for the “old” number 1234567 is “T”, whereas the check character for the “new” number 1234567_A will be “F”.

So, since our input takes in the full number, the first thing we must do is split the numeric part from the non-numeric part. Gladly, Regular Expressions are very handy for this. Our code will look something like this:

var numericPart = RegExp.$1;
var checksumCharacter = RegExp.$2;

var multiplyingFactor = 8;
var sum = 0;

for (var i = 0; i < numericPart.length; i++) {
sum += numericPart[i] * multiplyingFactor--;

if (RegExp.$2[1]) {
sum += (RegExp.$2[1].toUpperCase().charCodeAt(0) - 64) * 9;

var checksum = sum % 23;
if (checksum + 64 === checksumCharacter.toUpperCase().charCodeAt(0)) {
return "The provided PPSN is valid!";
} else {
return "The provided PPSN is invalid! The check character should be " + String.fromCharCode(checksum + 64);

So, initially we split the numeric from the non-numeric part of our input. Then, using the fixed multiplying factor of 8, we do a cycle to calculate the sum of the multiplications. We then check if we have a second character in the alphabetic part and if we do, we multiply it by 9, adding it to the sum. When we get this sum, we divide it by 23 and obtain the character position on the English alphabet.

And here, we do a slight “trick”. We add 64 to the checksum to make it match the ASCII table, since it is cheaper to check and ASCII is a standard, hence it will be safer to check a character this way. As an example, we can say that, given the PPSN 1234567T, the checksumCharacter would be T and the checksum value would be 20. If we add 64 to 20, we get 84 which represents the character ‘T’ in the ASCII table, making this result valid. For any other checksumCharacter other than T and the PPSNumber 1234567, it would return invalid. Note I converted the char to UpperCase so I always match the characters in ASCII table starting by “A”, whose code is 65, and not “a”, whose code is 97.

Attached is a zip file with the HTML page I built for this small example. I hope it can be of assistance to someone and feel free to use the Contact Me section of this website to get in touch if you have any questions.


Click here to download the zip file: ValidatePPS

EDIT: I modified the post and the code because the validation method changed in January 2013. Basically they added an extra character with the weight of 9 in the ninth position and this has to be included in the sum as well. Check this post and this post for more information.

Leave a comment

Your email address will not be published. Required fields are marked *

14 thoughts on “Validate Irish PPS Number with JavaScript and jQuery

  • Pingback: 9000mah行動電源

  • Pingback: Raisa Sadhra

  • Pingback: Mike Cacinni

  • Pingback: Jake Sunderland

  • Pingback: jordank

  • Pingback: mmorg

  • Pingback: James D.

  • Pingback: Terry Robinson

  • Pingback: michael krs

  • Pingback: lvl22

  • Pingback: mcm

  • Pingback: cfo

  • Pingback: oakley