martes, 12 de febrero de 2008

Validar el NIT con Modulo 11


Por cuestiones de trabajo, investigue como validar el NIT utilizando el algoritmo de Modulo 11 que utiliza la SAT en Guatemala pero buscando en google solo encontre un medio codigo en VBScript y uno en C# pero como lo queria en Javascript encontre una manera fácil de hacerlo.

El algoritmo consiste en lo siguiente, tenemos el siguiente NIT:

42932-5

Entonces multiplicamos:

4 * 6 = 24
2 * 5 = 10
9 * 4 = 36
3 * 3 = 9
2 * 2 = 4

En pocas palabras multiplicamos cada letra en su posicion. Lo que no multiplicamos es la ultima posicion que nos va a servir mas adelante.

El resultado nos da 83 aplicamos el modulo 11 de la siguiente manera:

83 mod 11 = 6

Seguidamente el resultado es el siguiente:

11 - 6 = 5

Este resultado debe ser identico al ultimo digito despues del guion que se le llama digito verificador y asi nos damos cuenta si un NIT es valido.

A continuación les pongo el algoritmo hecho en JavaScript:


var validarNITMod11 = function(nit) {
    var pos = nit.indexOf("-");
    var correlativo = nit.substring(0, pos);
    var digitoVerificador = nit.substring(pos + 1, nit.length);
    var factor = correlativo.length + 1;
    var valor = 0;
    for (i = 0; i < pos; i++) {
        valor += parseInt(correlativo[i]) * factor;
        factor -= 1;
    }
    var residuo = valor % 11;
    var resultado = 11 - residuo;

    if (resultado >= 11) {
        residuo = resultado % 11;
        resultado = residuo;
    }

    if (resultado == 10) {
        if (digitoVerificador.toUpperCase() == "K") {
            alert("El NIT es valido");
            return true;
        }

    } else if (digitoVerificador == resultado) {
        return true;
    }
    return false;
};

20 comentarios:

Anónimo dijo...

¡Oh! No tenía la más mímina idea de que así se realiza la validación.

Anónimo dijo...

Ta mas facil con expresiones regulares :)

Anónimo dijo...

Bueno... ahora averiguate porque la letra "k" si el resultado es 10. ¿Porque no escogieron la ñ? o ¿porque no escogieron otra letra? Talvez...¿la que se invento el algoritmo se llamaba Karla? Y..¿será que Karla estaba buena? Y si estaba buena...¿Cuál es su número?

Anónimo dijo...

Dicen que si uno llama a la SAT te pueden mandar esta función hecha en Java.

Anónimo dijo...

Huy, hay un error en el método que explican aquí.

Yo sé que existe el NIT 1510972-0. Aplicando el método aquí explicado, multiplico y sumo
2 * 2 = 4
7 * 3 = 21
9 * 4 = 36
0 * 5 = 0
1 * 6 = 6
5 * 7 = 35
1 * 8 = 8

Eso me da 110.

Al aplicar 110 % 11 me da 0, y al hacer 11 - 0 = 11. ¿Ven que no funciona?

Lo que falta es que al resultado de la resta hay que aplicarle de nuevo el módulo de 11, de esta forma 11 % 11 sí me da el cero de este NIT.

Mario Batres dijo...

Gracias por la aclaración muy buena tu observación

has dijo...

muchas gracias fue de gran ayuda, por si les interesa envio esta misma funcion el PL
FUNCTION FValidationNit(
iNit IN VARCHAR2
) RETURN VARCHAR2 IS

wNumberOne NUMBER;
wSum NUMBER := 0;
wDV NUMBER;
wLength NUMBER;
BEGIN

wLength := LENGTH(iNit);

FOR i IN 2..LENGTH(iNit) LOOP
wNumberOne := SUBSTR(iNit,i-1,1) * wLength;
wSum := wSum + wNumberOne ;
wLength := wLength - 1;
END LOOP; /*i IN 2..LENGTH(iNit) LOOP*/

wDV := (11-(wSum MOD 11)) MOD 11;

IF (((wDV = 10) AND (UPPER(SUBSTR(iNit,LENGTH(iNit), 1)) = 'K')))
OR (wDV = SUBSTR(iNit,LENGTH(iNit))) THEN
RETURN('T');
ELSE
RETURN('F');
END IF; /*(((wDV = 10) AND (SUBSTR(iNit,LENGTH(iNit), 1) = 'K')))*/
END;

Luis O. Gonzalez dijo...

por si les sirve, si alguien lo mejora alli se pasa copia.

Public Function ValidarNIT(ByVal Nit As String) As Boolean
Dim pos As Integer = Nit.IndexOf("-")
Dim Correlativo As String = Nit.Substring(0, pos)
Dim DigitoVerificador As String = Nit.Substring(pos + 1)
Dim Factor As Integer = Correlativo.Length + 1
Dim Suma As Integer = 0
Dim Valor As Integer = 0

For x As Integer = 0 To Nit.IndexOf("-") - 1
Valor = CInt(Nit.Substring(x, 1))
Suma = Suma + (Valor * Factor)
Factor = Factor - 1
Next

Dim xMOd11 As Double
xMOd11 = (11 - (Suma Mod 11)) Mod 11
Dim s As String = Str(xMOd11)
If (xMOd11 = 10 And DigitoVerificador = "K") Or (s.Trim = DigitoVerificador) Then
Return True
End If
Return False
End Function

Unknown dijo...
Este comentario ha sido eliminado por el autor.
Unknown dijo...

Excelente función, funciona perfectamente!!! gracias

Unknown dijo...

Excelente función, funciona perfectamente!!! gracias

Juan Manuel dijo...

¿Por que la K y no la ñ?
Porque la K es la undécima letra del alfabeto.

Unknown dijo...

aca les dejo la mejora para el NIT de Guatemala en JAVASCRIPT

// Archivo JScript
function ValidaNIT(txtN) {
alert("Entra: Function");
if (isNaN(txtN)){
return false;
}

txtN = txtN.toUpperCase();
if (txtN == "CF" || txtN == "C/F" || txtN == "") return true;
var nit = txtN;
var pos = nit.indexOf("-");

if (pos < 0)
{
var correlativo = txtN.substr(0, txtN.length - 1);
correlativo = correlativo + "-";

var pos2 = correlativo.length - 2;
var digito = txtN.substr(pos2 + 1);
nit = correlativo + digito;
pos = nit.indexOf("-");
txtN = nit;
}

var Correlativo = nit.substr(0, pos);
var DigitoVerificador = nit.substr(pos + 1);
var Factor = Correlativo.length + 1;
var Suma = 0;
var Valor = 0;
for (x = 0; x <= (pos - 1); x++) {
Valor = eval(nit.substr(x, 1));
var Multiplicacion = eval(Valor * Factor);
Suma = eval(Suma + Multiplicacion);
Factor = Factor - 1;
}
var xMOd11 = 0;
xMOd11 = (11 - (Suma % 11)) % 11;
var s = xMOd11;
if ((xMOd11 == 10 && DigitoVerificador == "K") || (s == DigitoVerificador)) {
return true;
}
else {
return false;
}

}

Anónimo dijo...

Useful information. Lucky me I found your website unintentionally, and I am stunned why this coincidence
didn't took place earlier! I bookmarked it.

My web page; raspberry ketones reviews

Anónimo dijo...

geotorelxzp loan consolidation
credit card companies

Anónimo dijo...

Para JAVA
public boolean ValidarNIT(String Nit) {
int longitudNit = Nit.length();
String DigitoVerificador = Nit
.substring(Nit.length() - 1, Nit.length());
int Suma = 0;
int Valor = 0;

int posCurrent = 0;
for (int x = longitudNit; x > 1; x--) {
Valor = Integer.parseInt(Nit.substring(posCurrent, posCurrent + 1));
Suma = Suma + (Valor * x);
posCurrent++;
}

int xMOd11 = 0;
xMOd11 = (11 - (Suma % 11)) % 11;
String s = String.valueOf(xMOd11);
if ((xMOd11 == 10 & DigitoVerificador.equals("K"))
|| (s.equals(DigitoVerificador))) {
System.out.println("Nit Válido");
return true;
}
System.out.println("Nit Inválido");
return false;
}

Anónimo dijo...

POR JHM 2013 se evalúa nit sin '-'
en el JAVA que subí hace unos segundos

Rodrigo Polo dijo...

Comparto aquí una versión en JavaScript que usa tanto Regex como el cálculo:
https://gist.github.com/rodrigopolo/0807e96a5331eb17e819f485d9a3c891

Unknown dijo...
Este comentario ha sido eliminado por el autor.
Anónimo dijo...

Un saludo, me sirvio mucho la informacion del post dejo el codigo que hice en C#:

public static bool ValidarNit(string _nit)
{
/*RemoveTo() Metodo de extension con sobre carga para string y string[] para los tipo string retorna un string despues
de hacer un regex para eliminar el carracter que recibe como parametro*/

//ToUpper() para poner en mayscula la K
string nit = _nit.RemoveTo(new string[] { "/", "-" , " " }).ToUpper();
//Valida que sea un numero y CF, CF cuenta como nit valido.
if (nit.ToUpper().Contains("CF"))
return true;
else if (!int.TryParse(nit.RemoveTo("K"), out int _))
return false;
//Obtener valor final para validar
int ValorFinal = nit.Contains("K") ? 10 : Convert.ToInt32(nit.Substring(nit.Length -1, 1)) ;
//Validar nit
int ValorTotal = 0;
int contador = nit.Length;
foreach(var numero in nit)
{
//Evita multiplicar el dato validador
if (contador == 1)
break;
ValorTotal += Convert.ToInt32(numero.ToString()) * contador;
contador--;
}
//Comprueba y retorna true si es el mismo valor
return ((11 - (ValorTotal % 11)) % 11) == ValorFinal;

}
espero le sirva a alguien, el metodo RemoveTo es un metodo de extencion de string que le hace un regex con los parametros