织梦CMS - 轻松建站从此开始!

欧博ABG官网-欧博官方网址-会员登入

¿Cómo validar un RFC de MéxicoDG游戏

时间:2025-07-18 19:58来源: 作者:admin 点击: 0 次
Algoritmo de validación de RFC Un RFC es válido si y solo si cumple las siguientes 7 condiciones: El RFC debe tener exactamente 12 o 13 carácteres

Algoritmo de validación de RFC

Un RFC es válido si y solo si cumple las siguientes 7 condiciones:

El RFC debe tener exactamente 12 o 13 carácteres (12 para personas morales y 13 para personas físicas). Es posible que nuestra interfaz de usuario permita introducir guiones, espacios u otros carácteres separadores. Aquí hablo solo de los carácteres que componen el RFC, los separadores se tratarían a otro nivel.

Los carácteres del nombre pueden solo contener las letras mayúsculas A-Z, el símbolo & y la Ñ. Para RFC de 12 carácteres el nombre son los 3 primeros y para 13 son los 4 primeros.

El nombre no es inconveniente. Hay una tabla con 41 nombres inconvenientes en el documento, por ejemplo MOCO, un RFC valido no puede tener ese nombre. Todos los nombres inconvenientes son para personas físicas (son todos de cuatro letras) pero al hacer la comprobación no es necesario comprobar que el RFC sea de 13 carácteres. Podemos comprobar contra los cuatro primeros directamente, si diésemos como incorrecto un RFC de persona moral por este motivo el resultado sería válido porque esto solo puede suceder si el primer dígito de la fecha no es una cifra, que sería un RFC incorrecto.

La fecha es válida. La fecha son los 6 carácteres que siguen al nombre. En formato AAMMDD ( dos últimas cifras del año, mes 01 a 12 y día 01 a 31). No sería válido ni 331403 (3 del mes 14 de algún año acabado en 33). Tampoco sería válido 010229 (29 de febrero de algún año acabado en 01).

El primer carácter diferenciador de homonimia es válido.Este es el primero que sigue a la fecha. Debe ser una letra mayúscula de la A a la V, ambas inclusive, o una cifra del 1 al 9 ambas inclusive, la Ñ y el 0 no son válidas. Esto es así porque en el apartado PROCEDIMIENTO PARA OBTENER LA CLAVE DIFERENCIADORA DE HOMONIMIA del documento que figura en la pregunta hay un paso en que se divide un número de 3 cifras entre 34 y se consulta una tabla. 999/34 = 29 . En esa tabla el 29 es la letra V

El segundo carácter diferenciador de homonimia es válido. Este es el que sigue al anterior. Debido al procedimiento que se sigue este puede ser cualquier carácter de la tabla correspondiente, es decir, de la A a la Z y del 1 al 9. La Ñ y el 0 no son válidos. El documento describe cómo se calculan los 2 carácteres diferenciadores de homonimia, pero esto no nos interesa porque solo disponemos del RFC y no del nombre que dio lugar a esos 2 carácteres diferenciadores de homonimia.

El dígito Verificador debe ser correcto. El dígito verificador es el último. Solo puede ser una cifra del 0 al 9 o la letra A. Y se calcula en función de los otros carácteres del RFC. Este dígito actúa como un código detector de errores que permite detectar la mayoría de errores cometidos por usuarios al introducir un RFC.

Nótese que por válido nos referimos a un RFC que cumple todas las normas del documento, es decir, existe una combinación de nombre y fecha de nacimiento o creación que genera ese RFC. Mientras que para un RFC inválido no hay ningún nombre y fecha que acabe generando ese RFC. Que sea válido no significa que exista.

Cálculo del dígito de verificación.

Si el RFC tiene 12 carácteres añadimos un espacio en blanco al principio.

Usamos todos los carácteres del RFC excepto el último. Es decir, usamos 12 carácteres siempre.
Cada carácter se corresponde con un valor según la siguiente tabla:

introducir la descripción de la imagen aquí

El valor del primer carácter se multiplica por 13, el segundo por 12, el tercero por 11 y así sucesivamente hasta el carácter duodécimo que se multiplica por 2.
Todos estos valores se suman. Y con la suma el documento describe unas operaciones innecesariamente complicadas que son equivalentes a :

A 11000 le restas la suma. Calculas el módulo 11 de la resta.

Si el resultado del módulo es 10 el dígito verificador es la A. En otro caso es el mismo número que has obtenido.

Ejemplo para el RFC GODE561231GR8

Carácter Valor Multiplicador Resultado G 16 * 13 = 208 O 25 * 12 = 300 D 13 * 11 = 143 E 14 * 10 = 140 5 5 * 9 = 45 6 6 * 8 = 48 1 1 * 7 = 7 2 2 * 6 = 12 3 3 * 5 = 15 1 1 * 4 = 4 G 16 * 3 = 48 R 28 * 2 = 56 ------------------------------------- SUMA : 1026 ( 11000 - 1026 ) % 11 = 8 -> El dígito verificador es 8 El RFC es Válido. Expresión Regular

Si fuese a utilizar una expresión regular como paso previo a la validación usaría :

[A-ZÑ&]{3,4}\d{6}[A-V1-9][A-Z1-9][0-9A]

Esta expresión acepta fechas incorrectas como 999999. Ni el día 99 ni el mes 99 existen.
No le veo sentido al complicar el regex, para rechazar los días que empiecen por 9 por ejemplo, puesto que de todas formas se van a quedar fechas no comprobadas por el regex (salvo que use un regex muy complicado). Es mejor dejar el análisis léxico para los regex (ver si los carácteres son válidos) y el semántico para otros niveles (ver si la fecha es correcta). Pero esto es opinable.

Usando Python y una biblioteca.

Con frecuencia la mejor manera de implementar algo es no hacerlo y usar una implementación ya hecha si está disponible y es fiable. Salvo para fines educativos o ciertos requisitos muy especiales.

Hay varias librerías que comprueban un RFC. Por ejemplo stdnum de Arthur de Jong and others. Disponible en https://github.com/arthurdejong/python-stdnum bajo licencia GNU Lesser General Public License versión 2.1 o posterior.

#!/usr/bin/env python from stdnum.mx.rfc import (validate,InvalidComponent,InvalidFormat, InvalidLength,InvalidChecksum) # Devuelve true si el RFC pasado es valido # rfc es un string def esValido(rfc): try: validate( rfc, validate_check_digits=True) return True except (InvalidComponent,InvalidFormat,InvalidLength,InvalidChecksum): return False

Poco hay que comentar, ya viene todo hecho por la biblioteca.

Usando programación funcional. En Scala

La función que hace la comprobación es la única pública y también se llama esValido. Al igual que la de Python devuelve true si el RFC pasado es válido.
El código incluye comentarios que explican su funcionamiento.

object RFCcheck extends App { private val caracteres = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // Estos son los carácteres permitidos en las 3 primeras posiciones (personas // morales, longitud total RFC es 12) o las 4 primeras posiciones (personas // físicas, longitud total RFC es 3) private val caracteresPrimeraParte = caracteres + "Ñ&" // Cifras permitidas en los 6 carácteres de la fecha private val cifras = "0123456789" // Carácteres permitidos en el dígito validador private val caracteresValidador = cifras + "A" // Valores permitidos para los carácteres primero y segundo de la clave // diferenciadora de la homonimia // Estos valores estan en la tabla del anexo 2 // Nótese que el primer carácter se obtiene dividiendo un numero de 3 cifras // entre 34 // 999/34 = 29 . Por tanto el máximo carácter en ese caso es 'V' private val caracteresHomonimia1 = "123456789ABCDEFGHIJKLMNOPQRSTUV" private val caracteresHomonimia2 = caracteresHomonimia1 + "WXYZ" // Comprobar que la fecha es valida // Por ejemplo, no permitir el 97 de octubre o el mes 17 // Nótese que se permite el 29 de febrero de los años acabados en 00 //porque el año 2100 no tendrá ese día pero el 2000 sí lo tuvo private val maxDiaMes = -1::31::28::31::30::31::30::31::31::30::31::30::31:: Nil private def fechaValida( s:String ):Boolean = { val anyo = s.substring( 0, 2).toInt val mes = s.substring( 2, 4).toInt val dia = s.substring( 4, 6).toInt if ( mes<1 || mes>12 ) return false if ( dia<1 ) return false if ( anyo%4==0 && mes==2 ) return dia<=29 dia<=maxDiaMes(mes) } // Carácteres en el orden de la tabla del anexo 3. Su posición es igual al // valor que se les asigna en la tabla del Anexo 3 private val tablaAnexo3 = "0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ Ñ" // Cálculo del dígito verificador private def calculaDigitoVerificador( rfc:String ):Char = { // Usar el rfc sin el último carácter que es el verificador // Para las personas morales se añade un espacio al principio val rfcSinDigitoV = if (rfc.length==13 ) rfc.substring(0,12) else " " +rfc.substring(0,11) // Para cada carácter multiplicamos su valor por (13 - posicion) // Y calculamos la suma de todas esas multiplicaciones val suma = (0 until 12 zip rfcSinDigitoV) . foldLeft (0) ( (acu,p) => acu + tablaAnexo3.indexOf(p._2) * (13-p._1) ) // Y calculamos el dígito verificador (11000-suma) módulo 11. // caracteresValidador tiene los carácteres en el orden que // necesitamos del 0 al 10 (el décimo es la A) caracteresValidador( (11000-suma) % 11) } // Palabras no permitidas según el anexo 4 private val palabrasInconvenientes = "BUEI"::"BUEY"::"CACA"::"CACO"::"CAGA":: "CAGO"::"CAKA"::"CAKO"::"COGE"::"COJA"::"COJE"::"COJI"::"COJO"::"CULO":: "FETO"::"GUEY"::"JOTO"::"KACA"::"KACO"::"KAGA"::"KAGO"::"KOGE"::"COJO":: "KAKA"::"KULO"::"MAME"::"MAMO"::"MEAR"::"MEAS"::"MEON"::"MION"::"MOCO":: "MULA"::"PEDA"::"PEDO"::"PENE"::"PUTA"::"PUTO"::"QULO"::"RATA"::"RUIN":: Nil // Calcula si es válido un rfc // El RFC debe tener exáctamente 12 carácteres para personas morales // Y 13 carácteres para personas físicas // No se admiten separadores como espacios o guiones def esValido( rfc:String ):Boolean = { val nombre = rfc.substring(0, rfc.length - 9) // Primeros 3 o 4 carácteres val fecha = rfc.substring(rfc.length - 9, rfc.length - 3) // 6 carácteres val homonimia1 = rfc(rfc.length-3) // 1º char de clave dif de homonimia val homonimia2 = rfc(rfc.length-2) // 2º char de clave dif de homonimia val digitoVerificador = rfc(rfc.length-1) // Último carácter // Un RFC es válido si se cumple todo lo siguiente: (rfc.length == 12 || rfc.length == 13) && // 12 o 13 de longitud // Solo carácteres permitidos en nombre nombre.foldLeft(true)(_ && caracteresPrimeraParte.contains(_)) && // Solo carácteres permitidos en fecha fecha. foldLeft(true)(_ && cifras.contains(_)) && // Solo carácteres permitidos en clave diferenciadora de homonimia caracteresHomonimia1.contains(homonimia1) && caracteresHomonimia2.contains(homonimia2) && // La fecha es valida fechaValida(fecha) && // Nombre no es una palabra inconveniente !palabrasInconvenientes.contains(nombre) && // El digito verificador es correcto digitoVerificador == calculaDigitoVerificador(rfc) } } Observaciones

En el documento Algoritmo para generar el RFC con homoclave para personas fisicas y morales.odt 📄 en la regla 9ª de la sección 2.2 figuran 39 palabras inconvenientes que no se pueden usar en un RFC. Sin embargo en el Anexo 4 figuran 41 palabras. Las 2 palabras extra son CAKO y MEAS. Yo he supuesto que el anexo es el correcto.

He probado con un millón de RFCs aleatorios, correctos e incorrectos, y las dos implementaciones han dado el mismo resultado en todos los casos. Aunque esto tampoco es garantía de nada.

No doy como buenos XEXX010101000 ni XAXX010101000 porque en el documento no se mencionan. La biblioteca de python hace lo mismo. Caso de que fuese necesario darlos como buenos es trivial hacer la modificación.

(责任编辑:)
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:
发布者资料
查看详细资料 发送留言 加为好友 用户等级: 注册时间:2025-07-19 06:07 最后登录:2025-07-19 06:07
栏目列表
推荐内容