问题:如何验证墨西哥 RFC 的格式是否有效?
什么是 RFC?联邦纳税人登记处 (RFC)是墨西哥每个自然人或法人进行任何合法经济活动所需的唯一密钥。它是国家税务总局发布的个人和公司税号。
RFC 由姓名和姓氏的字母(个人)或姓名的首字母或首字母和创建日期(公司)生成。生成和验证规则在Algorithm to generate the RFC with homoclave for natural and legal persons.odt ? 中进行了描述。
上下文:我想验证 RFC是否有效。我对看看它是否真的存在不感兴趣。我实现了一个非常通用的验证,允许最后 3 位数字是可选的:
/^[A-ZÑ&]{3,4}\d{6}(?:[A-Z\d]{3})?$/
但现在我有兴趣更严格地验证完整的 RFC,看到校验位是正确的(最后一个字符)。
正则短语
以下正则表达式检查:
全面验证
我用 JavaScript 发布代码以便能够在这里运行它,但是很容易将它移植到任何其他语言。
描述
以 RFC 的构建方式为参考:
([A-ZÑ&]{3,4})
第 1 组名称。* 在这种情况下,我们可以验证它只是一个元音或“X”,但如果第一个姓有 1 或 2 个字母,则采用母姓的第一个字母(可以是辅音)。
* 对于公司,如果他们没有 3 个单词,则取以下名字的字母。
?(?:- ?)?
。接受:
" "
,"-"
," -"
," - "
,"- "
, 或没有连字符或空格。*该模式看起来很有趣,但它是:一个可选的空格,后跟一个可选的(未捕获的)组,这匹配一个连字符可选地后跟一个空格。如果您不想允许使用空格或连字符,则可以删除此模式。
(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01]))
第 2 组。\d{2}
年。(?:0[1-9]|1[0-2])
月。(?:0[1-9]|[12]\d|3[01])
天。* 我接受最多 31 个月。我相信输入日期数据的错误将在稍后使用校验位进行验证。但是,如果您想更严格一些,尽管您可以在正则表达式中进行验证,但我建议您使用所使用的编程语言的功能来进行验证。
?(?:- ?)?
。([A-Z\d]{2})
组 3的同音异位符。([A\d])
组 4。使用正则表达式验证后,我们检查前 11 或 12 个字符的预期校验位是否与输入的校验位(最后一个字符)匹配。使用称为模块 11或ISBN 10的控制代码方法的改编。
我们已经对 RFC 的 4 个部分的文本进行了单独的捕获,
rfcSinDigito
它将是前 11 或 12 个字符,digitoVerificador
它将是最后一个字符。但如果它们是 11 个字符(道德人 - 公司的 RFC),则调整为能够对两者使用相同的算法。您可以在其前面加一个空格,或直接输入计算值。
要计算预期数字,首先将每个字符的索引从 13 加到 2,乘以 12 个字符中每个字符的值,这些字符的值按照以下顺序(字典)从 0 到 38:
在加法之上,你取除以 11 的余数的 11 的补码(或模 11,因此该方法的名称)。
0
如果给出 10,则变为A
。现在是的,我们可以比较它们是否匹配以返回结果。
但是我们为通用 RFC 的特殊情况添加了 2 个例外(关于税务验证的问题和答案,第 5 点和第 6 点? ),它们不是自然人或法人的有效RFC ,但用于:
1.
XAXX010101000
::: 操作与公众一起进行。2.
XEXX010101000
::: 对未在 RFC 中注册的国外居民进行的操作。* 如您所见,我使用了可选的第二个参数 (
aceptarGenerico
),以防它们不被允许。最后,如果它通过了上述所有规则,则返回干净的 RFC 。
RFC 验证算法
一个 RFC 当且仅当它满足以下 7 个条件时才有效:
请注意,有效是指符合文档所有标准的 RFC,即生成该 RFC 的名称和出生日期或创建日期的组合。而对于无效的 RFC,没有最终生成该 RFC 的名称和日期。仅仅因为它有效并不意味着它存在。
校验位计算。
如果 RFC 有 12 个字符,我们会在开头添加一个空格。
我们使用 RFC 的所有字符,除了最后一个字符。也就是说,我们总是使用 12 个字符。
根据下表,每个字符对应一个值:
第一个字符的值乘以 13,第二个乘以 12,第三个乘以 11,以此类推,直到第十二个字符乘以 2。
所有这些值相加。此外,该文档还描述了一些不必要的复杂操作,相当于:
RFC 示例
GODE561231GR8
正则短语
如果我要使用正则表达式作为预验证步骤,我会使用:
此表达式接受不正确的日期,例如 999999。既不存在第 99 天也不存在第 99 个月。
我认为使正则表达式复杂化没有任何意义,例如拒绝以 9 开头的日期,因为正则表达式仍不会检查日期(除非您使用非常复杂的正则表达式)。最好留下正则表达式的词法分析(查看字符是否有效)和其他级别的语义(查看日期是否正确)。但这值得商榷。
使用 Python 和库。
通常,实现某事的最佳方式是不去做,如果它可用且可靠,则使用现成的实现。教育目的或某些非常特殊的要求除外。
有几个库可以检查 RFC。例如来自 Arthur de Jong 和其他人的 stdnum。可在https://github.com/arthurdejong/python-stdnum在GNU Lesser General Public License版本 2.1 或更高版本下获得。
没什么可评论的,图书馆已经完成了一切。
使用函数式编程。在规模
进行检查的函数是唯一公开的并且也被调用的函数
esValido
。与 Python 一样,true
如果传递的 RFC 有效,它就会返回。该代码包含解释其工作原理的注释。
观察
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.
Ingresando a la pagina del SAT https://portalsat.plataforma.sat.gob.mx/ConsultaRFC/ pude obtener la expresión regular y la función que ellos utilizán espero les sirva:
API gratuita
API open source siempre gratuita con un tiempo de respuesta de 600 ms y en 2 pasos para verificar el rfc, saber si esta en la lista negra del SAT y en LRFC: Documentacion.
Expresión regular
La siguiente expresión regular (en el codigo) verifica:
按照奥兰多·阿方索的答案,按照SAT SAT 2的逻辑。使用 Mariano 的示例代码。
它适用于其他语言。这是一个例子。
Actualmente ocupo esta expresion regular, valida lo siguiente: