Como Validar el DNI o el RUC de Perú en C#

En estos días me ha tocado trabajar en un proyecto que, como tantos otros hoy día, está pensado para un entorno empresarial globalizado.

Parte de las reglas de negocio del proyecto exige, como también es común en tantos otros proyectos, validar el documento de identidad correspondiente al cliente para el país al cual éste pertenece. Para el caso de países como España o Brasil existe amplia documentación y recursos referentes al algoritmo empleado para validar sus respectivos documentos de identidad.

Pero lamentablemente para Perú, uno de los países que tengo que gestionar, la cantidad y la calidad de la información disponible es decepcionante.

DNI Electrónico Peruano

Por otro lado, al hablar de documentos de identidad en Perú, debemos distinguir entre el DNI (Documento Único de Identidad) y el RUC (Registro Único de Contribuyente). El primero aplica a los ciudadanos en general y cuenta con un identificador conocido como CUI (Cédula Única de Identidad), mientras que el segundo aplica a empresas y comercios.

El siguiente algoritmo permite validar documentos de identidad peruanos (tanto DNI como RUC). Para el caso del DNI, es independiente que el CUI tenga como término de verificación un número o una letra.

public static bool ValidateIdentificationDocumentPeru(string identificationDocument)
{
    if (!string.IsNullOrEmpty(identificationDocument))
    {
        int addition = 0;
        int[] hash = { 5, 4, 3, 2, 7, 6, 5, 4, 3, 2 };
        int identificationDocumentLength = identificationDocument.Length;

        string identificationComponent = identificationDocument.Substring(0, identificationDocumentLength - 1);

        int identificationComponentLength = identificationComponent.Length;

        int diff = hash.Length - identificationComponentLength;

        for (int i = identificationComponentLength - 1; i >= 0; i--)
        {
            addition += (identificationComponent[i] - '0') * hash[i + diff];
        }

        addition = 11 - (addition % 11);

        if (addition == 11)
        {
            addition = 0;
        }

        char last = char.ToUpperInvariant(identificationDocument[identificationDocumentLength - 1]);

        if (identificationDocumentLength == 11)
        {
            // The identification document corresponds to a RUC.
            return addition.Equals(last - '0');
        }
        else if (char.IsDigit(last))
        {
            // The identification document corresponds to a DNI with a number as verification digit.
            char[] hashNumbers = { '6', '7', '8', '9', '0', '1', '1', '2', '3', '4', '5' };
            return last.Equals(hashNumbers[addition]);
        }
        else if (char.IsLetter(last))
        {
            // The identification document corresponds to a DNI with a letter as verification digit.
            char[] hashLetters = { 'K', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
            return last.Equals(hashLetters[addition]);
        }
    }

    return false;
}

Finalmente, el gobierno de Perú pone a disposición la siguiente herramienta para verificar documentos de identidad; y esta otra herramienta para validar RUC.

Espero que les sea de utilidad.

Anuncios
Entrada siguiente
Deja un comentario

24 comentarios

  1. Alvaro

     /  enero 30, 2013

    if (addition == 11)
    {
    addition = 0;
    }
    else if (addition == 10)
    {
    addition =1
    }

    Responder
    • Marcel

       /  agosto 8, 2014

      Hola Álvaro, Rodrigo. No me queda claro por qué el artificio del “else if” teniendo en cuenta que los arrays con los dígitos de control tienen 11 elementos ambos. Agregando dicha condición nunca saldrá el último ítem de los arrays,
      Saludos.

      Responder
  2. Carlos

     /  julio 24, 2013

    Gracias, pero me devuelve falso cuando ingreso algunos DNI verdaderos. Donde puedo verificar la lógica?

    Responder
    • Hola Carlos,

      Toda la lógica que tengo es la que está en el post, plus una corrección que muy amablemente suministró Alvaro.

      ¿Probaste modificar el algoritmo con su corrección?

      Si pudieras pasarme algunos de esos DNI para probar sería algo que te agradecería mucho.

      Un saludo…

      Responder
      • Carlos

         /  agosto 6, 2013

        Rodrigo,

        Gracias por responder. Por ejemplo 70025425 que es el número de la imagen de tu post no se valida si es que no se agrega el 8 final. Pero ese ultimo dato mayormente no lo tenemos o no lo usamos, solo se brindan los 8 primero números como DNI.

        Si, efectivamente probé la corrección y me percaté que solo funciona si es que ingresamos los 8 dígitos mas el ultimo que esta después del guión, pero como te digo acá usamos solo 8.

        Espero me puedas ayudar.

        Saludos

      • Hola Carlos,

        Disculpa la demora con la respuesta. Estuve conversando con gente que sabe del tema (sobre todo el aspecto legal) y es que el último dígito es el que permite la efectiva validación del DNI. Sin él, el número es simplemente una secuencia no verificable de valores. Basicamente, el último dígito es un checksum producto de los primeros 8 números.

      • Zeu

         /  agosto 26, 2013

        Hola Rodrigo puedes mandarme fotos del programa y donde colocar el algoritmo ya que no soy programador pero me interesa utilizar tu programa de verificación, mi correo es djzeu@hotmail.com

      • Hola Zeu,

        Perdona la demora. No estaba disponible en estos días. ¿A qué te refieres con una foto?

        El algoritmo como tal lo tengo definido como un método que es invocado por aquellos consumidores que necesitan validar el número de DNI.

  3. Javier

     /  enero 15, 2014

    Rodrigo que tal , llegue justo a tu espacio , estoy tratando de encontrar el ultimo digito despues de la “-” ejem : 08272766-9-C osea el “9” .. sabes como sacarlo? estaba probando sumar , multiplicar pero no tengo resultados a favor..

    Responder
    • Hola Javier,

      Te dejo el siguiente código. Si te fijas, utilizo la primera parte del documento de identidad (“08272566”) y el mismo me retorna el valor ‘9’ ó ‘C’ correspondientes al número o caracter de control.

          class Program
          {
              private static char[] hashNumbers = { '6', '7', '8', '9', '0', '1', '1', '2', '3', '4', '5' };
      
              private static char[] hashLetters = { 'K', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
      
              static void Main(string[] args)
              {
                  int control = ValidateIdentificationDocumentPeru("8272766");
                  Console.WriteLine("Número de control: " + hashNumbers[control]);
                  Console.WriteLine("Caracter de control: " + hashLetters[control]);
                  Console.WriteLine("Pulse cualquier tecla para salir...");
                  Console.Read();
              }
      
              private static int ValidateIdentificationDocumentPeru(string identificationDocument)
              {
                  if (!string.IsNullOrEmpty(identificationDocument))
                  {
                      int addition = 0;
                      int[] hash = { 5, 4, 3, 2, 7, 6, 5, 4, 3, 2 };
      
                      int identificationComponentLength = identificationDocument.Length;
      
                      int diff = hash.Length - identificationComponentLength;
      
                      for (int i = identificationComponentLength - 1; i >= 0; i--)
                      {
                          addition += (identificationDocument[i] - '0') * hash[i + diff];
                      }
      
                      addition = 11 - (addition % 11);
      
                      if (addition == 11)
                      {
                          addition = 0;
                      }
                      else if (addition == 10)
                      {
                          addition = 1;
                      }
      
                      return addition;
                  }
      
                  throw new ArgumentException("The identification number must not be empty or null.", "identificationDocument");
              }
          }
      

      Del código seguro podrás extrapolar como se realiza dicho cálculo.

      Responder
  4. Ludwig

     /  marzo 28, 2014

    Hola Rodrigo no soy programador como puedo aplicar tu código, puedes enviármelo cuales serian las operaciones básica? que se realizan

    Responder
  5. Es necesario efectuar esta operacion identificationDocument[i] – ‘0’ ,?,ya que el valor que sea([0-9]) – ‘0’ sera el primero.

    Responder
    • Me equivoque..pensaba que era javascript…probe tu codigo corregido con 4198 de los cuales,3781 no fueron aprobados.

      Responder
      • Hola Juan. Es raro lo que comentas, ya que he empleado este código en un aplicativo .NET y hasta ahora no me han sido reportadas incidencias de fallos en las validaciones de los documentos de identidad.

  6. tania

     /  marzo 22, 2015

    ayudenme porfavor
    7804252M2207076PER>>>>>>>>>>>6
    Mi pregunta es: por mas que realizo y realizo la operacio el ultimo codigo que es 6, no me sale.
    Podrian decirme como llego a eso???

    Responder
    • lweb20

       /  abril 14, 2015

      qué es ese código que mandas “7804252M2207076PER>>>>>>>>>>>6” eso no es ni RUC ni mucho menos DNI :/

      Responder
  7. Buenos días, muchas gracias por el algoritmo para la validación del DNI. Lo estoy usando en mi aplicación, solo que no consigue que funcione para DNI’s que terminen en el dígito ‘5’. Los devuelve como incorrectos, cuando no lo son. ¿Les pasa lo mismo a ustedes? Gracias

    Responder
  8. Cshion

     /  septiembre 30, 2015

    Gracias por el aporte , solo una duda , segun otro post en otro sitio ,http://www.excelnegocios.com/validacion-de-rucs-sunat-peru-sin-internet-algoritmo/ , el ultimo calculo en la condiicional el algoritmo dice que si es mayor a 10 retorna el ultimo digito ( si es 10 => 0 , 11 => 1 ) , esto varia segun tu codigo , hay algun paso que me he perdido ?

    Responder
    • Cshion

       /  octubre 1, 2015

      Bueno , la curiosidad no me dejo , asi que me puse a buscar por todos lados , y que mejor manera que buscar desde el mismo fondo , me puse a inspeccionar la pagina de la sunat(consulta sunat ) y me encontre con este este script ,una pequenha validacion que hacen ,casi los mismo calculos , pero fijese que lo usan tanto para validar DNI(8 digitos osea sin digito de control) como RUC , uno mismo puede ver dandole inspeccionar elemento al boton “Buscar ” y fijandose que se ejecuta la funcion “evalSearch()”;

      function valruc(valor){
      valor = trim(valor)
      if ( esnumero( valor ) ) {
      if ( valor.length == 8 ){
      suma = 0
      for (i=0; i<valor.length-1;i++){
      digito = valor.charAt(i) – '0';
      if ( i==0 ) suma += (digito*2)
      else suma += (digito*(valor.length-i))
      }
      resto = suma % 11;
      if ( resto == 1) resto = 11;
      if ( resto + ( valor.charAt( valor.length-1 ) – '0' ) == 11 ){
      return true
      }
      } else if ( valor.length == 11 ){
      suma = 0
      x = 6
      for (i=0; i= 10) resto = resto – 10;
      if ( resto == valor.charAt( valor.length-1 ) – ‘0’ ){
      return true
      }
      }
      }
      return false
      }

      Espero le sirva a alguien.

      Responder
  9. markvision3d

     /  diciembre 6, 2015

    hola cumpita, disculpen ,. alguien me podria decir a partir de que se generan los d numeros de DNI

    Responder
  10. Inka Jhon

     /  abril 27, 2016

    Hola,
    Aquí tengo un algoritmo en C++ con parámetros en la línea de comandos, pueden probarlo, funciona con todos los DNI y es muy rápido. Cualquier contribución será apreciada: https://github.com/inkacoder/pirhua/blob/master/dni.cpp

    Saludos,
    Inka Jhon

    Responder
  11. PHIERA

     /  junio 6, 2017

    PUEDE HABER DNI CON LOS MISMOS NÚMEROS…ES DECIR 11111111 EXISTE?

    Responder
  12. Rodrigo, lo siento por el español medio equivocado, me gustaría saber si usted tiene algo en javascript para esa validación, he intentado transferir su código para que pueda utilizar en mi aplicación y no obtuve éxito. ¿Puede ayudarme, por favor?

    Responder
  13. 200.107.155.105/externo/reniec
    Hice un algoritmo que valida el DNI

    Responder

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s