Buscar

martes, 24 de junio de 2008

Digito de verificacion DIAN (Colombia)

Hace poco un amigo mió necesitaba calcular el digito
de verificación de la DIAN
(Colombia), así que me puse la tarea de buscar el código ya que
yo en cierto momento también lo necesité y es algo muy normal en
las empresas de hoy, así que aquí esta.

public string CalcularDigitoVerificacion(string Nit)
{
string
Temp;
int
Contador;
int
Residuo;
int
Acumulador;
int[] Vector = new int
[15];

Vector[0] = 3;
Vector[1] = 7;
Vector[2] = 13;
Vector[3] = 17;
Vector[4] = 19;
Vector[5] = 23;
Vector[6] = 29;
Vector[7] = 37;
Vector[8] = 41;
Vector[9] = 43;
Vector[10] = 47;
Vector[11] = 53;
Vector[12] = 59;
Vector[13] = 67;
Vector[14] = 71;

Acumulador = 0;

Residuo = 0;

for
(Contador = 0; Contador < Nit.Length; Contador++)
{
Temp = Nit[(Nit.Length - 1) - Contador].ToString();
Acumulador = Acumulador + (
Convert.ToInt32
(Temp) * Vector[Contador]);
}

Residuo = Acumulador % 11;

if
(Residuo > 1)
return Convert.ToString
(11 - Residuo);

return
Residuo.ToString();
}

18 comentarios:

  1. Hola, bueno no lo necesito pero es una fuente interesante gracias por compartirla

    ResponderEliminar
  2. Muy interesante. Falta documentación de soporte.

    ResponderEliminar
  3. Orden Administrativa # 4 del 27 de Octubre de 1989. Reglamenta el cálculo del Digito de Verificación (DV).

    ResponderEliminar
  4. Gracias por el fragmento.

    Solo una mejora de eficiencia. En lugar de convertir entre string e int, se puede siempre usar int:

    -- Codigo actual
    string Temp;
    ....
    Temp = Nit[(Nit.Length - 1) - Contador].ToString();
    Acumulador = Acumulador + (Convert.ToInt32(Temp) * Vector[Contador]);


    -- Mejorado


    int Temp;
    ....
    Temp = Nit[(Nit.Length - 1) - Contador];
    Acumulador = Acumulador + (Temp * Vector[Contador]);

    ResponderEliminar
  5. Muy Buen aporte, acá el código mas compacto.

    public string CalcularDigitoVerificacion(string nit)
    {
    int contador;
    var vector = new int[15];

    vector[0] = 3;
    vector[1] = 7;
    vector[2] = 13;
    vector[3] = 17;
    vector[4] = 19;
    vector[5] = 23;
    vector[6] = 29;
    vector[7] = 37;
    vector[8] = 41;
    vector[9] = 43;
    vector[10] = 47;
    vector[11] = 53;
    vector[12] = 59;
    vector[13] = 67;
    vector[14] = 71;

    int acumulador = 0;
    int residuo = 0;
    for (contador = 0; contador < nit.Length; contador++)
    {
    int temp = nit[(nit.Length - 1) - contador];
    acumulador = acumulador + (temp*vector[contador]);
    }
    residuo = acumulador % 11;
    return residuo > 1 ? Convert.ToString(11 - residuo) : residuo.ToString();
    }

    ResponderEliminar
    Respuestas
    1. Está mal, la posición del vector debe empezar en 1 no en cero, es decir vector[1] = 3; no a 7, y de ahí hacia abajo. Par aun total en vector[15] = 71;

      Eliminar
  6. no me sa.....si yo digito este nit 811007991 me sale el 3 y debería ser el 8!!!

    ResponderEliminar
    Respuestas
    1. Es por la posición del vector, este debe empezar en 1 no en cero, es decir vector[1] = 3; no a 7, y de ahí hacia abajo. Par aun total en vector[15] = 71;

      Eliminar
  7. Muy buen aporte, aquí algunas correcciones, y el método implementado en java. Pueden compactar más el código

    public static int calcularDigito(String nit) {
    int digito = 0, acum = 0, residuo = 0;
    char [] nit_array = nit.toCharArray();
    int [] primos = {3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 39, 67, 71};
    int max = nit_array.length;

    for (int i = 0; i < nit.length(); i++) {
    acum += Integer.parseInt(String.valueOf(nit_array[max - 1])) * primos[i];
    max--;
    }

    residuo = acum % 11;
    if (residuo > 1) {
    digito = 11 - residuo;
    } else {
    digito = residuo;
    }

    return digito;
    }

    ResponderEliminar
  8. Aca dejo el código para hacer este mismo calculo en vb.Net ya que acá está en C# y en Java

    '''
    ''' Función que calcula el Digito de verificación del documento en vb.Net
    '''
    '''
    Private Shared Function CalcularDigitoVerificacion(ByVal Documento As String) As String
    Dim res As Integer
    If (Integer.TryParse(Documento, res) = True) Then
    Dim Acumulador As Integer = 0
    Dim Vector As Integer() = {0, 3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71}
    Dim DocumentoArray As Char() = Documento.ToCharArray()
    Dim max As Integer = DocumentoArray.Length
    For Contador As Integer = 0 To Documento.Length - 1
    Dim Temp As Integer = Integer.Parse(Documento.Substring(Contador, 1))
    Acumulador += (Temp * Vector(Documento.Length - Contador))
    Next
    Dim Residuo As Integer = Acumulador Mod 11
    If (Residuo > 1) Then
    Return "" & 11 - Residuo
    Else
    Return Residuo.ToString()
    End If
    Else
    Return "0"
    End If
    End Function

    ResponderEliminar
  9. Código corregido.

    public static int ObtenerDigitoVerificacion(int nit)
    {
    var vector = new[] {3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71};
    var nitString = nit.ToString();
    int tamanioNit = nitString.Length;
    int acumulador = 0;

    for (short contador = 0; contador < tamanioNit; contador++)
    {
    int temp = Convert.ToInt16(nitString[(tamanioNit - 1) - contador].ToString());
    acumulador = acumulador + (temp * vector[contador]);
    }

    int residuo = acumulador % 11;
    return residuo > 1 ? 11 - residuo : residuo;
    }

    ResponderEliminar
  10. buen aporte, alguien tiene este mismo codigo en postgres sql ?

    ResponderEliminar
  11. Para generer función en SQL Server


    CREATE FUNCTION [dbo].[ObtenerDigitoVerificadorColombia]
    (
    @Nit NVARCHAR(20)
    )
    RETURNS VARCHAR(1)

    AS
    BEGIN
    DECLARE @dv INT
    DECLARE @Lenght INT
    DECLARE @SEQ NVARCHAR(30)
    DECLARE @Contador INT
    DECLARE @Multiplo INT
    DECLARE @Acumulador INT
    --Variables
    set @Lenght = Len(LTRIM (RTRIM ((@Nit))))
    set @SEQ = substring('716759534743413729231917130703', (31 - (@Lenght * 2)),31)
    set @Contador = 1
    set @dv = 0
    --Calculo sobre secuencia
    while (@Contador <= @Lenght)
    begin
    --Sumo y multiplico
    set @dv = @dv + (cast(substring(@SEQ,1,2) as INT)) * (cast(substring(@Nit, @Contador, 1) as INT))
    --Recorto secuencia y aumento indice
    set @SEQ = substring(@SEQ,3,31)
    set @Contador = @Contador + 1
    end
    --Obtengo digito de verificacion
    set @dv = 11 - (@dv - (floor(@dv / 11) * 11))

    RETURN @dv

    END

    GO

    ResponderEliminar
  12. Gracias colega, me sirvió

    ResponderEliminar