module.exports = function(fi, country) { if (fi == null) return true; if (typeof fi != 'string') return false; fi = fi.toUpperCase(); country = country ? country.toLowerCase() : 'es'; let len = fi.length; let validators = { es: { regExp: /^[A-Z0-9]\d{7}[A-Z0-9]$/, validate: () => { let isCif = /[A-W]/.test(fi.charAt(0)); let lastDigit = fi.charAt(len - 1); let computedDigit; if (isCif) { let numbers = fi.substring(1, 8) .split('') .map(x => parseInt(x)); let pairSum = numbers .filter((_, i) => i % 2 != 0) .reduce((a, x) => a + x); let oddSum = numbers .filter((_, i) => i % 2 == 0) .map(x => x * 2) .join('') .split('') .map(x => parseInt(x)) .reduce((a, x) => a + x); let sum = (pairSum + oddSum).toString(); let units = parseInt(sum.charAt(sum.length - 1)); let control = units == 0 ? 0 : 10 - units; let index = 'JABCDEFGHI'.indexOf(lastDigit); computedDigit = index == -1 ? control.toString() : index; } else { // Foreign NIF let index = 'XYZ'.indexOf(fi.charAt(0)); let nif = index == -1 ? fi : index.toString() + fi.substring(1); let rest = parseInt(nif.substring(0, 8)) % 23; computedDigit = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(rest); } return computedDigit == lastDigit; } }, fr: { regExp: /^[A-Z0-9]{2}\d{9}$/ }, it: { regExp: /^\d{11}$/ }, pt: { regExp: /^\d{9}$/ } }; let validator = validators[country]; if (!validator) return false; return validator.regExp.test(fi) && (!validator.validate || validator.validate()); };