Sunday, October 16, 2005

Validaciones con modulo 11 y más

En el desarrollo de sistemas se utilizan los llamados "Digitos de autoverificación" este se calcula aplicando una fórmula. En nuestro caso es para la Cédula y el RNC, los cuales son campos importantes en las bases de datos y deben ser verificados antes de aceptar esos datos como válidos.

Las fórmulas son la de Módulo 10 y Módulo 11, respectivamente. Hay otro datos como el de la tarjeta de créditos que se utiliza una formula llamada algoritmo de LUHN, que es utilizado para verificar si el número de una tarjeta dada es válido. (Eso no quiere decir que no sea robada :-)

También es utilizado en verificacián de cádigo de barras y otras aplicaciones más.

Este es el código que utilizo, todavia no tengo el algoritmo para la tarjeta de crédito pero pronto se lo agregaré.


/**
* Clase de utilirias para la validacion de datos, como cedula y RNC, etc.
*
* @version 1.1v
* @author vns
*
*/
public class Validation {

/**
* Este método valida si la cedula de la República Dominicana es válida,
* utilizando el algoritmo modulo 10. No se pasan guiones en el
* argumento.

*
* @since 1.1v
* @param cedula es un arreglo de char numérico
* @return true si la cedula es válida.
*/
static public boolean validarCedula(char[] cedula){
int suma = 0;
int division = 0;
final char[] peso = {'1','2','1','2','1','2','1','2','1','2'};

if (cedula.length != 11)
return false;
else
{
for (int i = 0; i < 10 ; i++ ){
int a = Character.getNumericValue( cedula[i] );
int b = Character.getNumericValue( peso[i] );
char[] mult = Integer.toString(a * b).toCharArray();
//TODO mover de aqui, más arriba
//para verificar si es un dígito o no
if (!Character.isDigit(cedula[i]))
return false;

if (mult.length > 1){
a = Character.getNumericValue( mult[0] );
b = Character.getNumericValue( mult[1] );
}else{
a = 0;
b = Character.getNumericValue( mult[0] );
}
suma = suma + a + b;
}

division = (suma / 10) * 10;

if ( division < suma )
division += 10;

int digito = division - suma;

if (digito != Character.getNumericValue(cedula[10]) )
return false;
}
return true;
}

/**
* Este método valida si el RNC de la República Dominicana es válida,
* utilizando el algoritmo modulo 11. No se pasan guiones en el
* argumento.

*
* @since 1.1v
* @param rnc es un arreglo de char numérico
* @return true si el rnc es válido
*/
static public boolean validarRNC(char[] rnc){
final char[] peso = {'7','9','8','6','5','4','3','2'};
int suma = 0;
int division = 0;

if (rnc.length != 9)
return false;
else
{
for (int i = 0; i < 8; i++) {
//para verificar si es un dígito o no
if (!Character.isDigit(rnc[i]))
return false;

suma = suma + (Character.getNumericValue(rnc[i]) * Character.getNumericValue(peso[i]) );
}

division = suma / 11;
int resto = suma - (division * 11);
int digito = 0;

if (resto == 0 )
digito = 2;
else if (resto == 1)
digito = 1;
else
digito = 11 - resto;

if (digito != Character.getNumericValue(rnc[8]) )
return false;
}

return true;
}
}

7 comments:

Unknown said...

Hola, esta es mi version de tu codigo.

public static boolean validarCedula(String ced) {
if (ced == null || ced.length() != 11) return false;
int suma = 0;
int division = 0;
String peso = "1212121212";
for(int i = 0; i < 10; i++) {
int mul = (ced.charAt(i)-'0') * (peso.charAt(i)-'0');
while(mul > 0) {
suma += mul%10;
mul /= 10;
}
}
division = (suma / 10) * 10;
if (division < suma) division += 10;
int digito = division - suma;
if (digito != ced.charAt(10) - '0') return false;
return true;
}

Unknown said...

Otro codigo (de un amigo):

public static boolean validarCedula(String ced) {
if (ced == null || ced.length() != 11) return false;
int suma = 0;
for(int i = 0; i < 10; i++) {
int mul = (ced.charAt(i)-'0') * (i % 2 + 1);
while(mul > 0) {
suma += mul%10;
mul /= 10;
}
}
int division = (suma + 9) / 10 * 10;
int digito = division - suma;
return digito == ced.charAt(10) - '0';
}

Enel Almonte said...

''' Autor : Lic. Enel R. Almonte P.
'''
''' Determina si una cedula es valida a patir de su algoritmo de creacion
''' String que sera validado como cedula
'''
Function ValidaCedula(ByVal sCedula As String) As Boolean
Dim iDigital, p, t, d, Resultado, i As Integer
Dim sCon As String

sCedula = sCedula.Replace("-", "")

If sCedula.Length < 11 Then
Return False
End If

iDigital = Right(sCedula, 1)
sCon = "1212121212"
p = 0
t = 0
d = 0
Resultado = 0
For i = 0 To 9
sCedula = Trim(sCedula)
p = CInt(sCedula.Substring(i, 1)) * CInt(sCon.Substring(i, 1))
If p > 9 Then
p = p - 10 + 1
End If
t = t + p
Next

d = (10 - (t Mod 10)) Mod 10
If iDigital <> d Then
Return False
Else
Return True
End If
End Function

''' Autor : Lic. Enel R. Almonte P.
'''
''' Determina si un RNC es valido a patir de su algoritmo de creacion
''' String que sera validado como RNC
'''
Function ValidaRNC(ByVal sRNC As String) As Boolean
Dim iDigital, p, t, d, r, Resultado, i As Integer
Dim sCon As String

sRNC = sRNC.Replace("-", "")

If sRNC.Length < 9 Then
Return False
End If

iDigital = Right(sRNC, 1)
sCon = "79865432"
p = 0
t = 0
r = 0
d = 0
Resultado = 0
For i = 0 To 7
p = CInt(sRNC.Substring(i, 1)) * CInt(sCon.Substring(i, 1))
t = t + p
Next

r = t Mod 11
d = 11 - r
Select Case r
Case 0
d = 2
Case 1
d = 1
End Select

If iDigital <> d Then
Return False
Else
Return True
End If
End Function

Unknown said...

hola y gracia estan muy bien los codigos andaba buscando esto desde ase par de dia gracias una sujerencia deverias actualisar el blog

Britoch said...

no usas la variable RESULTADO

Unknown said...

C#

public static bool EsValid(string cedula)
{

string ced = cedula.Replace("-", "");
if (!cedula.All(char.IsNumber))
{
return false;
}
int verificador = Convert.ToInt32(ced.Substring(ced.Length - 1, 1));
string cedulax = ced.Substring(0, ced.Length - 1);
int suma = 0;
bool cedulaValida = false;
int mod = 0;
if (ced.Length < 11)
{
return false;
}
for (int i = 0; i < cedulax.Length; i++)
{
if ((i % 2) == 0)
{
mod = 1;
}
else
{
mod = 2;
}
object res = Convert.ToInt32(ced.Substring(i, 1)) * mod;
if ((int)res > 9)
{
res = res.ToString();
int n1 = Convert.ToInt32(res.ToString().Substring(0, 1));
int n2 = Convert.ToInt32(res.ToString().Substring(1, 1));
res = n1 + n2;
}
suma += (int)res;
}
int numero = (10 - (suma % 10)) % 10;
if (numero == verificador)
{
cedulaValida = true;
}
else
{
cedulaValida = false;
}
return cedulaValida;

}

Unknown said...

C# RNC

public static bool IsValid(string valor)
{
//para verificar si es un dígito o no
if (!valor.All(char.IsDigit))
return false;

char[] peso = { '7', '9', '8', '6', '5', '4', '3', '2' };
int suma = 0;
int division = 0;

if (valor.Length != 9)
return false;
else
{

for (int i = 0; i < 8; i++)
{
string rw = valor.ElementAt(i).ToString();
suma = suma + Convert.ToInt32(valor.ElementAt(i).ToString()) * Convert.ToInt32(peso[i]);
}

division = suma / 11;
int resto = suma - (division * 11);
int digito = 0;

if (resto == 0)
digito = 2;
else if (resto == 1)
digito = 1;
else
digito = 11 - resto;

if (digito != Convert.ToInt32(valor.ElementAt(8).ToString()))
return false;
}

return true;
}