Skip to content

Instantly share code, notes, and snippets.

@albciff
Forked from afgomez/validate_spanish_id.js
Last active October 18, 2018 07:35
Show Gist options
  • Save albciff/fe60808b7eb2249490b853bb0b2250c6 to your computer and use it in GitHub Desktop.
Save albciff/fe60808b7eb2249490b853bb0b2250c6 to your computer and use it in GitHub Desktop.
Spanish DNI, CIF, NIE validator
/**
* ValidateSpanishID. Returns the type of document and checks its validity.
*
* Usage:
* ValidateSpanishID( str );
*
* > ValidateSpanishID( '12345678Z' );
* // { type: 'dni', valid: true }
*
* > ValidateSpanishID( 'B83375575' );
* // { type: 'cif', valid: false }
*
* The algorithm is adapted from other solutions found at:
* - http://www.compartecodigo.com/javascript/validar-nif-cif-nie-segun-ley-vigente-31.html
* - http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
*
* - Adapted to new rules CIF (NIF persona jurídica) startsWith '[ABE]' could've digit or letter control.
* - There is no CIF that could start with 'L', however there is a valid NIF, for spaniards which live abroad, which starts with L.
*/
ValidateSpanishID = (function() {
'use strict';
var DNI_REGEX = /^(\d{8})([A-Z])$/;
var CIF_REGEX = /^([ABCDEFGHJKMNPQRSUVW])(\d{7})([0-9A-J])$/;
var NIE_REGEX = /^[LXYZ]\d{7,8}[A-Z]$/;
var ValidateSpanishID = {};
ValidateSpanishID.spainIdType = function( str ) {
if ( str.match( DNI_REGEX ) ) {
return 'dni';
}
if ( str.match( CIF_REGEX ) ) {
return 'cif';
}
if ( str.match( NIE_REGEX ) ) {
return 'nie';
}
};
ValidateSpanishID.validDNI = function( dni ) {
if(!dni.match(DNI_REGEX)){
return false;
}
var dni_letters = "TRWAGMYFPDXBNJZSQVHLCKE";
var letter = dni_letters.charAt( parseInt( dni, 10 ) % 23 );
return letter == dni.charAt(8);
};
ValidateSpanishID.validNIE = function( nie ) {
if(!nie.match(NIE_REGEX)){
return false;
}
// Change the initial letter for the corresponding number and validate as DNI
var nie_prefix = nie.charAt( 0 );
switch (nie_prefix) {
case 'X':
case 'L':
nie_prefix = 0; break;
case 'Y': nie_prefix = 1; break;
case 'Z': nie_prefix = 2; break;
}
return ValidateSpanishID.validDNI( nie_prefix + nie.substr(1) );
};
ValidateSpanishID.validCIF = function( cif ) {
var match = cif.match( CIF_REGEX );
if(match == null) return false;
var letter = match[1],
number = match[2],
control = match[3];
var even_sum = 0;
var odd_sum = 0;
var n;
for ( var i = 0; i < number.length; i++) {
n = parseInt( number[i], 10 );
// Odd positions (Even index equals to odd position. i=0 equals first position)
if ( i % 2 === 0 ) {
// Odd positions are multiplied first.
n *= 2;
// If the multiplication is bigger than 10 we need to adjust
odd_sum += n < 10 ? n : n - 9;
// Even positions
// Just sum them
} else {
even_sum += n;
}
}
var control_digit = (10 - (even_sum + odd_sum).toString().substr(-1) );
if (control_digit==10) { control_digit=0; }
var control_letter = 'JABCDEFGHI'.substr( control_digit, 1 );
// Control must be a digit
if ( letter.match( /[H]/ ) ) {
return control == control_digit;
// Control must be a letter
} else if ( letter.match( /[KPQS]/ ) ) {
return control == control_letter;
// Can be either
} else {
return control == control_digit || control == control_letter;
}
};
return ValidateSpanishID;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment