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. 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. 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 RegularSi 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. 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 FalsePoco hay que comentar, ya viene todo hecho por la biblioteca. Usando programación funcional. En ScalaLa 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. 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. (责任编辑:) |