spain-id
Version:
Spanish id documents validator (NIF, CIF, NIE)
116 lines (115 loc) • 3.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validCIF = exports.validNIE = exports.validDNI = exports.spainIdType = exports.validateSpanishId = void 0;
const DNI_REGEX = /^(\d{8})([A-Z])$/;
const CIF_REGEX = /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/;
const NIE_REGEX = /^[XYZ]\d{7,8}[A-Z]$/;
const sanitize = function (str) {
// Ensure uppercase and remove whitespace ang hyphens
return str.toUpperCase().replace(/\s/g, '').replace(/-/g, '');
};
const validateSpanishId = (str) => {
str = sanitize(str);
let valid = false;
const type = exports.spainIdType(str);
switch (type) {
case 'dni':
valid = exports.validDNI(str);
break;
case 'nie':
valid = exports.validNIE(str);
break;
case 'cif':
valid = exports.validCIF(str);
break;
}
return valid;
};
exports.validateSpanishId = validateSpanishId;
const spainIdType = (str) => {
str = sanitize(str);
if (str.match(DNI_REGEX)) {
return 'dni';
}
if (str.match(CIF_REGEX)) {
return 'cif';
}
if (str.match(NIE_REGEX)) {
return 'nie';
}
};
exports.spainIdType = spainIdType;
const validDNI = (str) => {
str = sanitize(str);
const dniLetters = 'TRWAGMYFPDXBNJZSQVHLCKE';
const letter = dniLetters.charAt(parseInt(str, 10) % 23);
return letter === str.charAt(8);
};
exports.validDNI = validDNI;
const validNIE = (str) => {
str = sanitize(str);
// Change the initial letter for the corresponding number and validate as DNI
let niePrefix = str.charAt(0);
switch (niePrefix) {
case 'X':
niePrefix = '0';
break;
case 'Y':
niePrefix = '1';
break;
case 'Z':
niePrefix = '2';
break;
default:
return false;
}
return exports.validDNI(niePrefix + str.substr(1));
};
exports.validNIE = validNIE;
const validCIF = (str) => {
str = sanitize(str);
if (!str || str.length !== 9) {
return false;
}
const letters = ['J', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
const digits = str.substr(1, str.length - 2);
const letter = str.substr(0, 1);
const control = str.substr(str.length - 1);
let sum = 0;
let i;
let digit;
if (!letter.match(/[A-Z]/)) {
return false;
}
for (i = 0; i < digits.length; ++i) {
digit = parseInt(digits[i]);
if (isNaN(digit)) {
return false;
}
if (i % 2 === 0) {
digit *= 2;
if (digit > 9) {
digit = Math.floor(digit / 10) + (digit % 10);
}
sum += digit;
}
else {
sum += digit;
}
}
sum %= 10;
if (sum !== 0) {
digit = 10 - sum;
}
else {
digit = sum;
}
if (letter.match(/[ABEH]/)) {
return String(digit) === control;
}
if (letter.match(/[NPQRSW]/)) {
return letters[digit] === control;
}
return String(digit) === control || letters[digit] === control;
};
exports.validCIF = validCIF;