tisdag 26 juni 2012

Validera personnummer med javascript

Idag skulle jag skriva ett enkelt javascript för att validera svenska personnummer med javascript.

Googlade lite men hittade inget jag gillade. Ett oläsligt script i sourcen på http://www.personnummer.nu/ och ett annat som inte webbläsaren köpte på http://0x539.se/validera-personnummer-med-jquery-validation/

Därför skrev jag mitt eget bidrag, som tolererar personnummer i följande format:

ååmmddxxxx 
ååmmdd-xxxx
ååååmmddxxxx
ååååmmdd-xxxx

samt kollar checksum på sista siffran mha. Luhn.



var validatePersonalNumber = function(input) {
    // Check valid length & form
    if (!input) return false;

    if (input.indexOf('-') == -1) {
        if (input.length === 10) {
            input = input.slice(0, 6) + "-" + input.slice(6);
        } else {
            input = input.slice(0, 8) + "-" + input.slice(8);
        }
    }
    if (!input.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})|(\d{4})(\d{2})(\d{2})\-(\d{4})$/)) return false;

    // Clean input
    input = input.replace('-', '');
    if (input.length == 12) {
        input = input.substring(2);
    }

    // Declare variables
    var d = new Date(((!!RegExp.$1) ? RegExp.$1 : RegExp.$5), (((!!RegExp.$2) ? RegExp.$2 : RegExp.$6)-1), ((!!RegExp.$3) ? RegExp.$3 : RegExp.$7)),
            sum = 0,
            numdigits = input.length,
            parity = numdigits % 2,
            i,
            digit;

    // Check valid date
    if (Object.prototype.toString.call(d) !== "[object Date]" || isNaN(d.getTime())) return false;

    // Check luhn algorithm
    for (i = 0; i < numdigits; i = i + 1) {
        digit = parseInt(input.charAt(i))
        if (i % 2 == parity) digit *= 2;
        if (digit > 9) digit -= 9;
        sum += digit;
    }
    return (sum % 10) == 0;
};


Edit 2012-10-24: Redigerat raden var d = new Date(...) som inte gillades av IE (tack till Raita som uppmärksammade detta).

Hoppas någon annan har nytta av det! :)



3 kommentarer:

  1. Fungerar ej i IE7.

    SvaraRadera
  2. (Its the line:
    if (Object.prototype.toString.call(d) !== "[object Date]" || isNaN(d.getTime())) return false;

    that doesn't work.)

    SvaraRadera
  3. Tjena! Tack för input, återskapade felet med IE 8. Det visar sig att IE har problem med att tolka datumsträngar i konstruktorn för new Date (http://stackoverflow.com/questions/163563/javascript-date-constructor-doesnt-work). Har uppdaterat inlägget med en annan konstruktor!

    SvaraRadera