Páginas: [1]
Imprimir
Autor Tema: Cédula de Identidad Uruguaya  (Leído 2684 veces)
Julio
Newbie
*
Mensajes: 5


Ver Perfil
« : Marzo 18, 2009, 11:56:29 »

Buenas,

Hace poco programé una clase para verificar y dar formatos a cédulas uruguayas en PHP.
Todavía no está en producción y me gustaría postearla en el foro para que me dieran su opinión.
Sería bueno que una vez corregida/aprobada por la comunidad (y ya con más seguridad de que funciona bien) quede a disposición de quien quiera utilizarla.
Aquellos que ya tengan una clase (o funcion/es) que haga el trabajo podrían compartirla para poder llegar a la mejor solución Sonrisa

Saludos

PD: no se rian de mi código XD

Código:
<?php
/**
 * Maneja operaciones sobre los numeros de Cedula de Identidad Uruguaya
 *
 * Algunas funciones se basan en la informacion obtenida de wikipedia <http://es.wikipedia.org/wiki/DNI#Uruguay>
 * Concretamente en el extracto que indican como realizar el calculo del digito:
 * Se toman los 7 numeros de la cedula y se multiplican cada uno por 2987634 uno a uno
 * (el primer numero por el 2, el segundo por el 9 y asi sucesivamente, cuando cada resultado supera un digito,
 * se toma solo la unidad). Ej: C.I.: 1.234.567-x -> 2987634 -> 2, 8, 4, 8, 0, 8, 8
 * Se hace la sumatoria de los resultados, en el ejemplo seria 2+8+4+8+0+8+8=38
 * Se busca el primer numero mas grande que 38 que termina en 0 y se le resta: 40-38= 2
 *
 * @category   XXX
 * @package    XXXX
 * @subpackage XXXXX
 * @author Julio Viana <jrviana@gmail.com>
 */

class CedulaUruguaya
{
/**
 * Recibe la cedula SIN digito verificador
 * Retorna el digito verificador de la cedula
 *
 * @return int
 */
public function obtenerDigito($cedula)
{
// Si no es numero se retorna false
if(!preg_match('/^([0-9])+$/'$cedula) ){
return false;
}

// Si es mayor a 7 digitos se retorna false
if(strlen($cedula) > ){
return false;
}

// Se agregan ceros al inicio si son necesarios
$cedula sprintf("%07s"$cedula);

// Array base para realizar el calculo del digito
$base = array(2,9,8,7,6,3,4);

$minuendo 0;
$sustraendo 0;

 
// Se toman los 7 numeros de la cedula y se multiplican cada uno por 2987634 uno a uno
 
// (el primer numero por el 2, el segundo por el 9 y asi sucesivamente, cuando cada
 
// resultado supera un digito, se toma solo la unidad).
 
// Ej: C.I.: 1.234.567-x -> 2987634 -> 2, 8, 4, 8, 0, 8, 8
// Se hace la sumatoria de los resultados, en el ejemplo seria 2+8+4+8+0+8+8=38
for($i=0$i<=6$i++){
$mult strval($cedula{$i} * $base[$i]);
$sustraendo += $mult >= 10 $mult{1} : $mult{0};
}

// Copio el valor de sustraendo a minuendo para agregarle valores de a uno
// hasta llegar a la decena siguiente en el bloque while de abajo
$minuendo $sustraendo;

// Se busca el primer numero mas grande que 38 (resultado del ejemplo) que termina en 0
while($minuendo%10!=0){
$minuendo++;
}

// y se le resta: 40-38= 2
$digito $minuendo $sustraendo;

return $digito;
}

/**
 * Recibe una cedula CON digito verificador
 * Retorna true si es correcta, false si es incorrecta
 *
 * @return boolean
 */
public function esValida($cedula)
{
// Si no es numero se retorna false
if(!preg_match('/^([0-9])+$/'$cedula) ){
return false;
}

// Si es mayor a 8 digitos se retorna false
if(strlen($cedula) > ){
return false;
}

// Guardo el largo de la cedula
$largo strlen($cedula);

// Paso la variable $cedula como array
$cedula str_split($cedula);

// Verificacion que evita cedulas de tipo 000000000, 11111111, 22222222, etc
for($i=0$i<=9$i++){
$iguales = array();
for($h=0$h<$largo$h++){
$iguales[] = $i;
}
if($cedula == $iguales){
return false;
}
}

// Tomo el ultimo numero como $digito y lo quito del array $cedula
$digito array_pop($cedula);

// Paso el array $cedula (ya sin digito) a variable
$cedula implode(''$cedula);

// Calculo el digito
$control $this->obtenerDigito($cedula);

// Comparo los digitos y retorno true si son iguales (es valida)
if($control == $digito){
return true;
} else {
 return false;
}
}

/**
 * Da formato a un numero de cedula. Ej: 12345678 => 1.234.567-8
 *
 * @return string
 */
public function darFormato($cedula)
{
// Si no es numero se retorna retorna nuevamente el parametro
if(!preg_match('/^([0-9])+$/'$cedula) ){
return $cedula;
}

// Si es mayor a 8 digitos se retorna nuevamente el parametro
if(strlen($cedula) > ){
return $cedula;
}

// Si es menor a 7 digitos se retorna nuevamente el parametro
if(strlen($cedula) < 7){
return $cedula;
}

// Se agregan ceros al inicio si son necesarios
$cedula=sprintf("%08s"$cedula);

// Guardo cada valor de $cedula en el array $c
$c str_split($cedula);

// Vacio la variable $cedula para almacenar en ella el valor con formato
$cedula null;

// Si hay un entero positivo en la primera posicion se agrega el mismo mas un punto ((x.)000.000-0)
if($c[0]){
$cedula $c[0].'.';
}

// Luego el resto del formato de cedula (x.(nnn.nnn-n))
$cedula .= $c[1].$c[2].$c[3].'.'.$c[4].$c[5].$c[6].'-'.$c[7];

return $cedula;
}

}
« Última modificación: Marzo 18, 2009, 11:59:06 por Julio » En línea
nicolas
Newbie
*
Mensajes: 14



Ver Perfil WWW
« Respuesta #1 : Marzo 20, 2009, 10:38:23 »

A simple vista me parece que está bastante bien, tendrá que instalara par probarla.
En línea

enriqueplace
Newbie
*
Mensajes: 5



Ver Perfil WWW
« Respuesta #2 : Marzo 24, 2009, 12:14:09 »

Desde ya Julio felicitaciones por usar el estándar de codificación de Zend y hacer uso de PHPdoc, todo un mérito trabajar tan prolijo ;-)
En línea
Julio
Newbie
*
Mensajes: 5


Ver Perfil
« Respuesta #3 : Marzo 25, 2009, 03:36:39 »

Desde ya Julio felicitaciones por usar el estándar de codificación de Zend y hacer uso de PHPdoc, todo un mérito trabajar tan prolijo ;-)


Gracias, seguí unos consejos que vi por ahí Gui&ntilde;ar
En línea
chitoso
Newbie
*
Mensajes: 2



Ver Perfil WWW
« Respuesta #4 : Mayo 20, 2009, 02:02:24 »

Buenas!
Muy prolijo lo tuyo.

No se porque, pero tengo la idea de que la forma de calcular el digito verificador es diferente. Quiza haya varios(?) Recuerdo que en el liceo vi el algoritmo. Voy a buscar el pdf y lo chequeo, de paso pruebo la func.

Me imagino que ya escribiste algunas pruebas unitarias y le tiraste de todo un poco...
En línea
chitoso
Newbie
*
Mensajes: 2



Ver Perfil WWW
« Respuesta #5 : Mayo 21, 2009, 08:25:00 »

Julio, un mes despues, espero que puedas ver esto. Como prometí, te paso esa info. Es el mismo método, capaz que te sirve verlo más formalizado para verificar.

Un saludo. El crédito va para el Prof. Gustavo Bermúdez Canzani  Sonrisa


La cédula de identidad uruguaya es un número de siete cifras, seguido de un dígito de una cifra. Éste es
un carácter de control que se calcula tomando como base para el cálculo el número 2.987.634, al que
llamaremos módulo verificador, e indicaremos con m. Para explicar el cálculo del dígito que
corresponde a una cédula de identidad cualquiera, tomaremos como ejemplo la cédula cuyo número es
1.913.577, al que llamaremos c.. El procedimiento es el que sigue:
        se multiplica la cifra de las unidades de c, por 4, que es la cifra de las unidades de m, y se
        “guardan” sólo las unidades. En nuestro caso: 7 × 4 = 28 → 8
        se multiplica la cifra de las decenas de c, por 3, que es la cifra de las decenas de m, y se
        “guardan” sólo las unidades. En nuestro caso: 7 × 3 = 21 → 1
        Repetimos esta operación dígito a dígito, multiplicando cada cifra del número de cédula por la
        correspondiente del módulo verificador.
Los resultados para el 1.913.577 aparecen en la siguiente tabla:
                                     c m productos unidades
                                     1   2      2          2
                                     9   9     81          1
                                     1   8      8          8
                                     3   7     21          1
                                     5   6     30          0
                                     7   3     21          1
                                     7   4     28          8
                                              Tabla 1
El siguiente paso, es sumar todas las cifras correspondientes a las unidades, que aparecen en la columna
de la derecha: 2 + 1 + 8 + 1 + 0 + 1 + 8 = 21 y volver a tomar la cifra de las unidades: 21 → 1 .
Por último, restamos de 10 la cifra a la que hemos llegado, repetimos el procedimiento de quedarnos
con la cifra de las unidades y el resultado es el dígito de control de la cédula de identidad. En nuestro
caso el resultado final es
                         10 – 1 = 9 → 9
 y la cédula del ejemplo se le asigna el número 1.913.577−9. Si el número fuera 1.569.683
obtendríamos como dígito de control el 0.
        Este dígito añadido es un ejemplo de lo que se llama un carácter de control porque permite
detectar errores en la transmisión. Supongamos que intentamos transmitir el número de cédula del
ejemplo y se produce un error como en el esquema
                                                  transmitimos
                                                   →   
                             1.913.577−9                         1.914.577−9
Podemos detectarlo, porque al número 1.914.577 le corresponde el dígito 2. También podemos detectar
el intercambio de dos cifras consecutivas, al que llamaremos “trabucazo”. Si cometiéramos un
trabucazo entre la tercera y cuarta cifra obtendríamos 1.931.577-9. Notamos que hay un error, porque
ahora el dígito de control debería ser 7
En línea
marceperez
Newbie
*
Mensajes: 1


Ver Perfil
« Respuesta #6 : Octubre 05, 2009, 10:43:56 »

Excelente!!! Es lo que estaba buscando, lo probé y anda de maravilla
Estoy realizando un proyecto en php para fin del curso de Programación web y necesitaba validar la cedula y no savia como hacerlo,
Yo lo use así viendo el código,

if (strlen($ci) >9){
die("<p align='center'><font face='Arial' size='3' color='#FF0000'>Please enter a valid ci</font></p>");
}else{
$cedula=$ci;
$ValorCedula=new CedulaUruguaya($cedula);
$digito=$ValorCedula->obtenerDigito($cedula);
$cedula=$cedula.$digito;
$formato=$ValorCedula->darFormato($cedula);
echo "$formato" ;

Este ejemplo es un archivo que use para probar la clase si hay una forma mas pulida me gustaría que me lo puedan enseñar.
Saludos
En línea
Páginas: [1]
Imprimir
Ir a: