Formato del NSS
El Número de Seguridad Social se constituye por:
Los códigos de Subdelegaciones del IMSS están listados en el Manual para Integración del NSS . Si bien algunos (pocos) números no son válidos, podrían serlo en el futuro, por lo que no podemos validar por ese campo. Además, en los casos especiales cuando no se posee un registro de fecha de nacimiento, se utiliza el código 97
.
Cuando se posee una fecha de nacimiento, logicamente debe ser menor al año de alta del trabajador.
El dígito verificador es asignado utilizando el algoritmo de Luhn, lo cual nos permitirá realizar la validación del NSS.
Expresión regular
Sólo se validará que sean 11 dígitos, pero usaremos la expresión para capturar los primeros 3 campos por separado:
/^(\d{2})(\d{2})(\d{2})\d{5}$/
Validación Completa
Publico el código en JavaScript para poder ejecutarlo acá, pero es muy sencillo de llevar a cualquier otro lenguaje.
// Devuelve un booleano si es un NSS válido
// (deben ser 11 dígitos sin otro caracter en el medio)
function nssValido(nss) {
const re = /^(\d{2})(\d{2})(\d{2})\d{5}$/,
validado = nss.match(re);
if (!validado) // 11 dígitos y subdelegación válida?
return false;
const subDeleg = parseInt(validado[1],10),
anno = new Date().getFullYear() % 100;
var annoAlta = parseInt(validado[2],10),
annoNac = parseInt(validado[3],10);
//Comparar años (excepto que no tenga año de nacimiento)
if (subDeleg != 97) {
if (annoAlta <= anno) annoAlta += 100;
if (annoNac <= anno) annoNac += 100;
if (annoNac > annoAlta)
return false; // Err: se dio de alta antes de nacer!
}
return luhn(nss);
}
// Algoritmo de Luhn
// https://es.wikipedia.org/wiki/Algoritmo_de_Luhn
function luhn(nss) {
var suma = 0,
par = false,
digito;
for (var i = nss.length - 1; i >= 0; i--) {
var digito = parseInt(nss.charAt(i),10);
if (par)
if ((digito *= 2) > 9)
digito -= 9;
par = !par;
suma += digito;
}
return (suma % 10) == 0;
}
//Handler para el evento cuando cambia el input
//Elimina cualquier caracter no numérico y comprueba validez
function validarInput(input) {
var nss = input.value.replace(/\D+/g,""),
resultado = document.getElementById("resultado"),
valido;
if (nssValido(nss)) { // ⬅️ Acá se comprueba
valido = "Válido";
resultado.classList.add("ok");
} else {
valido = "No válido";
resultado.classList.remove("ok");
}
resultado.innerText = "NSS: " + nss + "\nFormato: " + valido;
}
#resultado {
background-color: red;
color: white;
font-weight: bold;
}
#resultado.ok {
background-color: green;
}
<label>NSS:</label>
<input type="text" id="nss_input" style="width:100%;"
oninput="validarInput(this)"
placeholder="Ingrese su NSS">
<pre id="resultado"></pre>
Descripción
Luego de validar que son 11 dígitos y haber separado los 3 primeros campos, se compara que el año de nacimiento sea previo al de inscripción. Como sólo contamos con los últimos dígitos del año, se agrega 100 al número si es menor al año actual (así '05 será mayor a '99 por ejemplo).
if (subDeleg != 97) { // Si tiene año de nacimiento
if (annoAlta <= anno) annoAlta += 100;
if (annoNac <= anno) annoNac += 100;
if (annoNac > annoAlta)
return false; // Err: se dio de alta antes de nacer!
}
Sin embargo, la principal validación es por el algoritmo de Luhn, que consta en tomar los dígitos en posiciones impares, y los dígitos en posiciones pares multiplicados por 2. Se suman todos los dígitos (si alguno de estos fuese mayor o igual a 10 se toma la suma de cada dígito).
var digito = parseInt(nss.charAt(i),10);
if (par)
if ((digito *= 2) > 9)
digito -= 9;
Un NSS es válido si el último dígito de esa suma da 0
.
return (suma % 10) == 0;