sanjacob / CURPSuite

Análisis y validación de la CURP Mexicana en Python
https://curpsuite.readthedocs.io
GNU General Public License v2.0
7 stars 0 forks source link

Refactorización algoritmo Checksum CURP #198

Closed fitorec closed 1 year ago

fitorec commented 1 year ago

Hola,

Buenas, estuve revisando un poco el código y me llamó un poco la atención el como se genera la suma de verificación.

Veo que lo divides en dos partes:

  1. la primera en donde se genera la suma (_verification_sum)
  2. la segunda donde se extrae el ultimo dígito(_sum_to_verify_digit).

Por otra parte el alfabeto de caracteres válidos, en donde se repite el valor de N y genera de la siguiente manera:

_CHARSET = f"{string.digits}{string.ascii_uppercase[:14]}"
_CHARSET += f"N{string.ascii_uppercase[14:]}"

Si ejecutamos un print(_CHARSET) el resultado es 0123456789ABCDEFGHIJKLMNNOPQRSTUVWXYZ.

Revisando esto, se puede refactorizar dichas funciones en una sola. Si previamente se validan que todos los caracteres son validos (p.e. usando un regex), podría quedar como:

def checksum(curp: str) -> int:
        """
        Calculate the checksum for the mexican CURP.
        """
        chars = "0123456789ABCDEFGHIJKLMNNOPQRSTUVWXYZ"
        suma = sum([(18 - i) * chars.index(curp[i]) for i in range(17)])
        return (10 - (suma % 10)) % 10

Nota: Aunque dicha caracteristica se perdiera me gustó del método _verification_sum fue la creatividad de invertir el curp haciendo innecesario el uso del (18 - i) remplazandolo por solamente i.

Quizás una prueba mas amplia podría revisar el funcionamiento e incluso performance de dichas funciones,con un set de datos mas grande(un par de miles de registros) y probar si el valor generado es el esperado.

Para esto se puede usar este conjunto de datos:

Finalmente si deseas que te ayude en algo, quizás metiendo este set de datos, en las pruebas o refactolizando dicho código, avísame por este medio yo estaría encantado de colaborar.

sanjacob commented 1 year ago

Gracias por tu curiosidad.

La razón por la cuál la función está dividida en dos es porque hace el testing más sencillo. Si has tenido oportunidad de observar la estrategia de testing del proyecto, está basada en Hypothesis, con la cuál genera datos de prueba arbitrarios. De cualquier manera también se ha probado manualmente contra cerca de 60k registros.

Por ahora no tengo intenciones de modificar el proyecto pero aún así gracias por tu entusiasmo!