Skip to content

Instantly share code, notes, and snippets.

@rodrigopolo
Last active August 15, 2023 13:43
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rodrigopolo/0807e96a5331eb17e819f485d9a3c891 to your computer and use it in GitHub Desktop.
Save rodrigopolo/0807e96a5331eb17e819f485d9a3c891 to your computer and use it in GitHub Desktop.
A simple function to validate guatemalan NIT using both, regex and math.
/*
* These functions validate whether a string corresponds to a Guatemalan tax
* identification number, also known as 'Numero de Identificación
* Tributaria' (NIT). They employ regular expressions for this purpose, utilizing
* the metacharacter shorthand '\d' instead of '[0-9]' to save space.
* The approach is highly optimized for bandwidth reduction; readability and
* maintenance are not prioritized over optimization. You can observe how this
* regular expression works through the following links:
* - https://regex101.com/r/d5YFJE/1
* - https://regexr.com/7ieic
*/
// New JS ES6 function with improved regex
function valNit(nit){
let nd, add=0;
if(nd = /^(\d+)\-?([\dkK])$/.exec(nit)){
nd[2] = (nd[2].toLowerCase()==='k')?10:parseInt(nd[2]);
for (let i = 0; i < nd[1].length; i++) {
add += ( (((i-nd[1].length)*-1)+1) * nd[1][i] );
}
return ((11 - (add % 11)) % 11) === nd[2];
}else{
return false;
}
}
// Old JS ES5 function with improved regex
function valNit(nit){
var nd, add=0;
if(nd = /^(\d+)\-?([\dkK])$/.exec(nit)){
nd[2] = (nd[2].toLowerCase()=='k')?10:parseInt(nd[2]);
for (var i = 0; i < nd[1].length; i++) {
add += ( (((i-nd[1].length)*-1)+1) * nd[1][i] );
}
return ((11 - (add % 11)) % 11) == nd[2];
}else{
return false;
}
}
console.log(validateTaxID('3602978-5')); // Outputs: true
console.log(validateTaxID('3602978-6')); // Outputs: false
console.log(validateTaxID('576937-K')); // Outputs: true
@israhes
Copy link

israhes commented Dec 7, 2017

Como siempre, gracias por compartir!

@izotejulio
Copy link

Gracias men :)

@rodrigopolo
Copy link
Author

A las órdenes.

@JPaulMora
Copy link

JPaulMora commented Aug 10, 2021

More readable Regexp and example witout dash (-):

var nitRegExp = new RegExp('^[0-9]+(-?[0-9kK])?$');
var noDashRegExp = new RegExp('^[0-9]+([0-9kK])?$');

@rodrigopolo
Copy link
Author

Muchas gracias, igual en sitios regex101.com se puede probar y ver lo que realiza cada Shorthand Character Classes, y como es un gist, tiene más como fin el copy/paste que la parte educativa. Me alegra que llamara tu atención, viniendo de alguien que es ideológicamente opuesto.

@biagnei240698
Copy link

Gracias muy util.

@jorge-gomez7
Copy link

excelente, muchas gracias por el aporte!

@rodrigopolo
Copy link
Author

A las órdenes @jorge-gomez7, tenía ratos de no ver la función, la actualicé un poco y arreglé un poco la expresión regular, y aprovecho para compartir la explicación de cómo se valida un NIT.

¿Cómo se Valida un NIT?

El NIT se compone de varios dígitos que puede estén seguidos de un guión - y un último número o letra K que simboliza 10, este último caracter recibe el nombre de dígito verificador, por ejemplo: 3602978-5 o 36029785 sin el guión. A continuación, el proceso de verificación.

  1. Se toman los números de izquierda a derecha antes del guión, y de no haber guión, todos los digitos excepto el último:
    3602978
  2. Se asignan posiciones de derecha a izquierda así el primer número a la derecha le corresponderá la posición 2 y así sucesivamente:
    8 = 2
    7 = 3
    9 = 4
    2 = 5
    0 = 6
    6 = 7
    3 = 8
    
  3. Se multiplica cada dígito por el número de la posición respectiva:
    8 * 2 = 16
    7 * 3 = 21
    9 * 4 = 36
    2 * 5 = 10
    0 * 6 = 0
    6 * 7 = 42
    3 * 8 = 24
    
  4. Se suman los resultados de esas multiplicaciones:
    16 + 21 + 36 + 10 + 0 +42 + 24 = 149
  5. El resultado es divido dentro de 11 y se toma el residuo que quede, es importante mencionar que en esta división se deja hasta donde el cociente es entero:
    149 / 11 = 13
    13 * 11 = 143
    149 – 143 = 6
    
  6. Al residuo resultante se le vuelve a dividir dentro de 11 nuevamente y se toma el residuo resultante:
    6 / 11 = 0
    0 * 11 = 0
    6 – 0 = 6
    
  7. Se resta el residuo anterior a 11:
    11 – 6 = 5

Tomando en cuenta que si el dígito verificador es K, este tiene un valor de 10, y que de lo contrario es sólo un dígito, si el resultado obtenido al final de la operación es igual al dígito verificador, significa que el NIT es válido, como en este caso en el que validamos el NIT 3602978-5 que tiene como dígito verificador el número 5 obtenido al final de las operaciones.

Fuente: http://ficoaex.blogspot.com/2012/10/como-se-valida-un-nit.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment