(JS) Validate Swedish personnummer and organisationsnummer


JavaScript functions for validating Swedish personal identity numbers (personnummer), and organisation numbers (organisationsnummer). The functions for personal identity number will also validate co-ordination number (samordningsnummer).

/**
 * Validate a 10 digit swedish personnummer
 * @param pnr
 * @returns {boolean|boolean}
 */
function validatePersonnummer(pnr) {
    let personummer = cleanDigitString(pnr);
    if (personummer.length > 10) {
        return false;
    }

    return isValidLuhn(personummer) && isPersonnummerDate(personummer);
}

function validateOrganisationNumber(orgnr) {
    let orgnumber = cleanDigitString(orgnr);

    if (orgnumber.length < 10 || orgnumber.length > 12 || orgnumber.length === 11) {
        console.log(orgnumber.length);
    }

    return isValidLuhn(orgnumber);
}

/**
 * Remove any non digit characters
 * @param digitString
 * @returns {*}
 */
function cleanDigitString(digitString) {
    return digitString.replace(/\D/g, '');
}

/**
 * Check if date is valid for personnummer
 * @param pnr
 * @returns {boolean}
 */
function isPersonnummerDate(pnr) {
    let year = parseInt(pnr.substring(0, 2));
    let month = parseInt(pnr.substring(2, 4));
    let day = parseInt(pnr.substring(4, 6));

    // Check year and month values
    if (year < 0 || year > 99 || month < 0 || month > 12) {
        return false;
    }

    let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    // Adjust for leap years
    if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
        daysInMonth[1] = 29;
    }

    // Check that day is within range
    let dayIsValid = day > 0 && day <= daysInMonth[month - 1];

    // If day is outside range, check if it's +60 for samordningsnummer
    if (!dayIsValid) {
        dayIsValid = day > 60 && day <= daysInMonth[month - 1] + 60;
    }

    return dayIsValid;
}

/**
 * Check if last digit of number is vald Luhn control digit
 * @param pnr
 * @returns {boolean}
 */
function isValidLuhn(pnr) {
    let number;
    let checksum = 0;
    for (let i = pnr.length - 1; i >= 0; i--) {
        number = parseInt(pnr.charAt(i));
        if (i % 2 === 1) {
            checksum += number;
        } else {
            checksum += (number * 2) > 9 ? (number * 2) - 9 : number * 2;
        }
    }

    return checksum % 10 === 0;
}
JavaScript

2 responses

  1. Johannes Kjellberg Avatar
    Johannes Kjellberg

    Thank you so much for this! 🙂

    1. Inga problem. Hojta till om du märker några konstigheter i scriptet.

Leave a Reply

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