Calculate module 11 factor 2

1

I am trying to calculate the module 11 factor 2 of a number of 48 digits in python I have the following code:

def GenerarClaveAcceso(clave_acceso_48):
    """Funcion encargada de crear la clave
        de Acceso con 49 digitos basado en
        la metodologia mod 11 factor 2
    """
    print clave_acceso_48
    contador = 1
    data = []
    for clave in clave_acceso_48:
        element = {}
        if contador == 1:
            element['digito_1'] = int(clave) * 3

        if contador == 2:
            element['digito_2'] = int(clave) * 2

        if contador == 3:
            element['digito_3'] = int(clave) * 7

        if contador == 4:
            element['digito_4'] = int(clave) * 6

        if contador == 5:
            element['digito_5'] = int(clave) * 5

        if contador == 6:
            element['digito_6'] = int(clave) * 4

        if contador == 7:
            element['digito_7'] = int(clave) * 3

        if contador == 8:
            element['digito_8'] = int(clave) * 2

        if contador == 9:
            element['digito_9'] = int(clave) * 7

        if contador == 10:
            element['digito_10'] = int(clave) * 6

        if contador == 11:
            element['digito_11'] = int(clave) * 5

        if contador == 12:
            element['digito_12'] = int(clave) * 4

        if contador == 13:
            element['digito_13'] = int(clave) * 3

        if contador == 14:
            element['digito_14'] = int(clave) * 2

        if contador == 15:
            element['digito_15'] = int(clave) * 7

        if contador == 16:
            element['digito_16'] = int(clave) * 6

        if contador == 17:
            element['digito_17'] = int(clave) * 5

        if contador == 18:
            element['digito_18'] = int(clave) * 4

        if contador == 19:
            element['digito_19'] = int(clave) * 3

        if contador == 20:
            element['digito_20'] = int(clave) * 2

        if contador == 21:
            element['digito_21'] = int(clave) * 7

        if contador == 22:
            element['digito_22'] = int(clave) * 6

        if contador == 23:
            element['digito_23'] = int(clave) * 5

        if contador == 24:
            element['digito_24'] = int(clave) * 4

        if contador == 25:
            element['digito_25'] = int(clave) * 3

        if contador == 26:
            element['digito_26'] = int(clave) * 2

        if contador == 27:
            element['digito_27'] = int(clave) * 7

        if contador == 28:
            element['digito_28'] = int(clave) * 6

        if contador == 29:
            element['digito_29'] = int(clave) * 5

        if contador == 30:
            element['digito_30'] = int(clave) * 4

        if contador == 31:
            element['digito_31'] = int(clave) * 3

        if contador == 32:
            element['digito_32'] = int(clave) * 2

        if contador == 33:
            element['digito_33'] = int(clave) * 7

        if contador == 34:
            element['digito_34'] = int(clave) * 6

        if contador == 35:
            element['digito_35'] = int(clave) * 5

        if contador == 36:
            element['digito_36'] = int(clave) * 4

        if contador == 37:
            element['digito_37'] = int(clave) * 3

        if contador == 38:
            element['digito_38'] = int(clave) * 2

        if contador == 39:
            element['digito_39'] = int(clave) * 7

        if contador == 40:
            element['digito_40'] = int(clave) * 6

        if contador == 41:
            element['digito_41'] = int(clave) * 5

        if contador == 42:
            element['digito_42'] = int(clave) * 4

        if contador == 43:
            element['digito_43'] = int(clave) * 3

        if contador == 42:
            element['digito_42'] = int(clave) * 2

        if contador == 43:
            element['digito_43'] = int(clave) * 7

        if contador == 44:
            element['digito_44'] = int(clave) * 6

        if contador == 45:
            element['digito_45'] = int(clave) * 5

        if contador == 46:
            element['digito_46'] = int(clave) * 4

        if contador == 47:
            element['digito_47'] = int(clave) * 3

        if contador == 48:
            element['digito_48'] = int(clave) * 2

        contador += 1
        data.append(element)

    contador = 0
    sumatoria = 0
    for valor in data:
        contador += 1
        indice = 'digito_' + str(contador)
        sumatoria += int(valor[indice])

    mod = sumatoria % 11
    resultado_resta_mod = 11 - mod

    if int(resultado_resta_mod) == 11:
        digito_verificador = 0

    elif int(resultado_resta_mod) == 10:
        digito_verificador = 0
    else:
        digito_verificador = resultado_resta_mod

The code as you see is too long, it generates a digit but my question is whether it is well developed and if there is perhaps some way to make the calculation of it less extensive.

To perform this function use the following documentation:

Digit Verifier Module 11

Thank you in advance .. !!

    
asked by Diego Avila 03.01.2019 в 16:50
source

1 answer

1

According to the definition of the algorithm in Wikipedia, the factors to use are 2,3,4,5,6,7 starting with the least significant digit , and then repeating as we continue towards the most significant digits.

Your implementation in change uses 3,2,7,6,5,4 starting with the most significant, which is valid only if the input sequence has a number of digits that is a multiple of 6 plus 2. It is not the case for your input sequence with 48 digits, which is a multiple of 6, then you are calculating wrong.

To avoid this type of errors and to be valid for any input length, it is better to operate starting with the least significant digit, for which we can use reversed() on the input sequence.

Also, by using itertools.cycle() we can get the repetitive sequence of 2,3,4,5,6,7,2,3,4,5... as long as we need, which greatly simplifies the necessary syntax while making it more generic.

It would stay like this:

import itertools

def GenerarClaveAcceso(clave_acceso_48):
  factores = itertools.cycle((2,3,4,5,6,7))
  suma = 0
  for digito, factor in zip(reversed(clave_acceso_48), factores):
    suma += int(digito)*factor
  control = 11 - suma%11
  if control == 10:
     return 1
  else:
     return control

The function zip(secuencia1, secuencia2) is returning pairs of elements, one of each sequence, until one of them runs out. In our case the secuencia1 is that of the entry digits, but "upside down", to begin with the least significant one. The secuencia2 is the one that generates itertools.cycle() , which is infinite (or as long as needed). In this case, secuencia1 will end sooner. This way it works for any size of the entrance.

Example of use:

>>> GenerarClaveAcceso('241120180118901536380012003004000255333002553331')
6
    
answered by 03.01.2019 / 18:25
source