Rentas, Patentes y RegExp
Introducción
Esto es una historia real que me ocurrio hace unos instantes. No sabia si postearlo acá pero como es mi blog hago lo que quiero. Hace un rato queria ver cuanto debía del impuesto de patente de mi auto. Por motivos que no es prudente comentar acá hacia tiempo que no me llegaban las boletas y no reclamaba asi que quise ver si internet me daba una solución. Vaya si me dio una solución… Por prudencia no voy a poner la dirección donde pueden encontrar las páginas que destriparé en los párrafos siguientes, confio en que sabrán googlear
Prolegómenos
Sin problemas encontré que en la página web de rentas de la ciudad autónoma de buenos aires es posible consultar el estado de la deuda con tan solo poner el número de patente. Sin embargo es necesario ingresar un “digito verificador” por motivos que, estimo, tienen que ver con salvaguardar la información del deudor. Dicho digito se encuentra impreso en la boleta pero como comente mas arriba, hace tiempo que no la tengo.
La página presentaba dos cuadros de texto donde introducir la patente y el digito verificador (se llama digito verificador a pesar de estar formado por Dos digitos). Puse la patente de mi auto y tire algunos digitos al azar. Naturalmente, no acerte con el digito verificador pero me llamó poderosamente la atención de que la validación se hacia instantaneamente y un hermoso alert() se encargaba de avisarnos de nuestro error. Algo olía a Javascript.
En pleno siglo XXI cuesta creer que alguien use javascript para realizar este tipo de validación, sin embargo las tecnicas de ofuscación de codigo a veces confunden a ciertas personas. Digo las confunde porque a veces se olvidan de ofuscar su código… asi que, firebug mediante, pude hacerme con el código de validación que comparto en este link.
Años atras, cuando el tiempo libre era algo que me sobraba, curioseando por ahí habia podido comprobar en incontables veces lo patético que son los emprendimientos informaticos del estado, sobretodo en lo referente a seguridad, desde el servicio meteorológico de las fuerzas aereas hasta el ministerio de educacion. Más cerca en el tiempo habia sufrido con las aplicaciones de rentas y los tramites via web de la afip. Sabía de las limitaciones del estado. Pero no sabia que se habian vuelto a superar…
Tratamiento
Todo empieza con una curiosa función titulada ValidarDigitoPatente() la cual, increiblemente, valida nuestra patente y el digito verificador. Efectivamente la lógica que hace la validación esta del lado del cliente y el codigo no esta ofuscado… bueno… no a la manera tradicional porque se las ingeniaron para que cueste entenderlo
Lo primero que hace esta función es validar que la patente ingresada sea valida (para los hermanos latinoamericanos en argentina las patentes, ó matriculas, de los autos tienen 3 letras seguidas de 3 digitos. ABC 123, DFG 167 y UIO 654 son ejemplos de patentes validas. Antiguamente se usaba una codificación formada por una letra y 7 numeros). El codigo que se encarga de hacer esto, contengan las risas, es el siguiente:
if (EsLetra(n.charAt(0))) {
if (n.length == 8 &&
isDigit(n.charAt(1)) &&
isDigit(n.charAt(2)) &&
isDigit(n.charAt(3)) &&
isDigit(n.charAt(4)) &&
isDigit(n.charAt(5)) &&
isDigit(n.charAt(6)) && isDigit(n.charAt(7))) {
Javascript posee una de las implementaciones mas lindas de expresiones regulares que existen. Los estatales argentinos, sin embargo, no saben usarlas. Esa maraña de código para chequear la validez de una patente se puede reducir a:
if(n.match('[a-zA-z]{3}[0-9]{3}')) {
Esta bien, no seria taaaaan grave que no dominen el arte oscuro de las expresiones regulares. Sucede que hay patentes de otro tipo de vehiculos, e incluso las patentes que se usaban antiguamente, que tienen otro formato. ¿Como hacen para evaluar los otros formatos? Facil, seguimos enmarañando el código.
if (isDigit(n.charAt(0))) {
if (n.length > 1 && isDigit(n.charAt(1))) {
if (n.length > 2 && isDigit(n.charAt(2))) {
if (n.length == 6 &&
EsLetra(n.charAt(3)) &&
EsLetra(n.charAt(4)) && EsLetra(n.charAt(5))) {
Más alla de esto lo que nos importa es poder averiguar el bendigo digito, que son dos, verificador. Para eso se valen de una enigmatica funcion Codigo(). Esta función recibe una letra y devuelve un número de dos cifras aparentemente asignados al azar, no soy un criptoanalista ni mire muy detenidamente la serie, pero esos numeros me parecen familiares. Bueno, con un array asociativo devolvemos como value dos digitos a partir de una letra que usamos como clave y listo. No necesariamente…
function Codigo(letra) {
if (letra == "a" || letra == "A") {
return "14";
} else if (letra == "b" || letra == "B") {
return "01";
} else if (letra == "c" || letra == "C") {
return "00";
//asi hasta el infinito y mas allá...
Detalles… detalles… ¿Pero como funciona la funcion validadora? Para seguir con la tradicion de los digitos del CUIT vamos a hacer un par de cuentitas con los valores que devuelve esta funcion y a otra cosa. En el caso de la patente de mi auto, con tres letras y tres digitos, el codigo verificador se evalua de esta forma:
//la patente esta en n
var a = new String(Codigo(n.charAt(0)) + Codigo(n.charAt(1)) + Codigo(n.charAt(2)) + n.charAt(3) + n.charAt(4) + n.charAt(5));
//quedaria a como un string de 9 digitos ya que cada letra se cambia por dos numeros y los ultimos 3 numeros quedan igual.
document.frmLogin.chapa_patente_copia.value = n;
//se copia la patente original (WTF?)
var digitos_impares = new String(a.charAt(0) * 1 + a.charAt(2) * 1 + a.charAt(4) * 1 + a.charAt(6) * 1 + a.charAt(8) * 1);
//aca empieza lo bueno: se castean los digitos en las posiciones pares de a y se suman entre ellos.
var digitos_pares = new String(a.charAt(1) * 1 + a.charAt(3) * 1 + a.charAt(5) * 1 + a.charAt(7) * 1);
//se hace lo mismo pero para las posiciones impares del string a
if (digitos_impares.length == 2) {
digitos_impares = new String(digitos_impares.charAt(0) * 1 + digitos_impares.charAt(1) * 1);
}
if (digitos_pares.length == 2) {
digitos_pares = new String(digitos_pares.charAt(0) * 1 + digitos_pares.charAt(1) * 1);
}
if (digitos_impares.length == 2) {
//aca es donde el agua nos empieza a tapar...
digitos_impares = new String(digitos_impares.charAt(0) * 1 + digitos_impares.charAt(1) * 1);
}
if (digitos_pares.length == 2) {
digitos_pares = new String(digitos_pares.charAt(0) * 1 + digitos_pares.charAt(1) * 1);
}
//aca es donde nos tapo el agua.
var digito_verificador = new String(digitos_impares + digitos_pares);
Con el agua al cuello puede darse la ¿casualidad? de que los benditos digitos_pares una vez sumados den una cifra de dos digitos, como 39, por lo que volvemos a sumarlos para obtener uno solo… aunque 3+9 da 11… deberiamos repetir el procedimiento y llegariamos como resultado a 2. No comprobe como se comportan los digitos que devuelve la funcion Codigo() para ver si podria darse el caso de llegar a situaciones que requieran volver a sumar los digitos del resultado hasta alcanzar un valor final de un solo digito. Los personajes de rentas aparentemente ya agotaron estas arduas cuestiones metafisicas y parece que con dos sumas siempre se llega a un resultado de un digito ¿maravilloso verdad? Para hacer esto no usaremos recursion, ni closures, ni un miserable ciclo while. Hacemos copy&paste del codigo y le prendemos una vela a los santos agradecidos por haber inventado el hardcoding.
Conclusión
Uno se encuentra con cosas raras en las operaciones informáticas de la administración pública. No puedo evitar reflexionar sobre estas cuestiones cada vez que tengo que hacer una declaracion jurada via internet en la pagina de la afip, o llenar un formulario de arba. Creo que la información de las personas es uno de los bienes más sensibles y deben ser manejados de la mejor forma por nuestras autoridades.
Lo importante resulto ser que el “digito verificador” de mi patente es el 43, uno más que el sentido de la vida, el universo y todo lo demás. Finalmente si alguien quiere saber cuanto debo de patentes esta es la respuesta que obtuve en el sitio de rentas:
ERROR DE COMUNICACION: INTENTE MAS TARDE.
Para todos los que llegan buscando como sacar su numerito de la suerte les dejo algo para que lo usen con fines beneficos solamente. Escriban la patente en el cuadro presionen en el boton, crucen los dedos y quiza se hagan con el numerito
Jajajjajjajajaja
Mató lo que hicieron en vez de usar regexp! que payasos jajja.
Y después, el hardcoding, ese copy&paste trucho que hicieron jajjaj, no se de que me río, es deprimente…
Muy bueno el artículo, yo me encuentro bastante seguido con estas páginas de mierda que hacen este tipo de verificaciones client-side! (y ni hablar de ofuscar el código juaa!).
Lo más deprimente de todo, es que muchas de estas páginas pertenecen a organismos que poseen datos personales de muchos individuos.. antes me molestaba en escribirles un mail explicándoles el “bug”, pero nah.. con esos sueldos, se CAGAN en nuestros datos jaja.
Comentado por Sherekan
— 07/05/2008 #
* Increible la cantidad de gente que llega a este post buscando en google
* “digito verificador patente” y nadie se digna a preguntar como sacar
* el f*cking numero.
* Acá pueden pasar dos cosas: A – todo el mundo le gusta debuguear javascript
* y estan haciendo reverse engineer del codigo. B – Todos se aburren en el
* primer parrafo y vuelven a google buscando alguna respuesta mas directa.
*
* Me juego por la segunda opcion..
Comentado por mauricio
— 07/05/2008 #
me podran pasar la formula en criollo pa’hacer a lapiz vio, desde ya gracias
Comentado por marcelo
— 16/07/2008 #
a lapiz es medio bardo. pasame la patente y te devuelvo el numero.
Comentado por mauricio
— 16/07/2008 #
genial. no sabes lo que te agradezco..pense que el “burro” era Yo …pero no nuevamente percibo que en lo maquiavelico de la administracion publica,todavia se rinde pleitesia a: “Si lo podemos hacer dificil,hay que aunar esfuerzos para que asi sea”….no sea cosa que cualquiera con una pc. nos venga a quitar el sueño de seguir siendo (empleado,proveedor,asesor o contratado ) de algun organismo oficial… Por ultimo no me imgagino que tipo de delito se puede cometer si sabemos el estado de pago de patentes…pero mi mente es practica y obtusa…no es mi funcion ..eso es para los paladines de la defensa de la “BURROCRACIA”.nuevamente te agradezco y a GOOGLE el haberme arrimado un hilo de luz en esto..
Comentado por nelson
— 04/08/2008 #
Hola. Buscando lo del digito verificador de las patentes, llegué aquí. Gracias. No se nada de programación, y desearía saber si me podes ayudar. Trabajo para una ONG, haciendo búaquedas, en internet, en bases de datos, etc.
Tengo un progrma llamado Autopad(2003)que no pude usar más, ya que hace falta una clave. Al instalarlo se genera un clave que se debía enviar al vendedor quien te pasaba un codigo de activación, pero nunca más lo pude encontrar. Deseo saber si hay alguna manera de poder utilizarlo.
Muchas Gracias.
Patricia.
Comentado por Patricia
— 26/08/2008 #
Gracias!!! Yo tampoco tenia las boletas, me mude hace mil años y nunca las busque…ni las pague. EL digito verificador me dio perfecto y pude averiguar la deuda con tu programa. Capooooo
Comentado por sol
— 21/02/2010 #
che no entiendo nada alguien me puede explicar porque no entiendo nada loco. donde tengo que introducir el numero la letras de la chapa mas el numero para que me de el codigo?
Comentado por RICHARD
— 15/03/2010 #
La función Codigo(letra) parece ser un resabio de cuando las patentes eran una letra según la provincia y luego dígitos.
Es aparente por que la “C” retorna 00, la “B” retorna 01, la “S” 02, la “X” 03, las letras de las provincias más pobladas C = Capital, B = Buenos Aires, S = Santa Fé, X = Córdoba.
Comentado por Juan Lanus
— 11/08/2010 #
Muchas pero muchas gracias, realmente me sacastes de un problemon cada vez que fui a rentas a preguntar…. una cola infernal me sometia y perdia mi horario de almuerzo sin el bendito digito verificador… no quiero ser un especialista en java me realmente tus comentarios y el link me resultaron de utilidad y conocimiento … MASTER!! mis respectos … nuevamente graciaaaaaasss CAPOOOO.
Comentado por CarlosDR
— 09/10/2010 #