Yo estaba tratando de implementar el Fórmula De Luhn en Python, aquí está mi código:

import sys


def luhn_check(number):
    if number.isdigit():
        last_digit = int(str(number)[-1])
        reverse_sequence = list(int(d) for d in str(int(number[-2::-1])))

        for i in range(0, len(reverse_sequence), 2):
            reverse_sequence[i] *= 2

        for i in range(len(reverse_sequence)):
            if reverse_sequence[i] > 9:
                reverse_sequence[i] -= 9

        sum_of_digits = 0
        for i in range(len(reverse_sequence)):
            sum_of_digits += reverse_sequence[i]

        result = divmod(sum_of_digits, 10)

        if result == last_digit:
            print("[VALID] %s" % number)
        else:
            print("[INVALID] %s" % number)
        quit()

    print("[ERROR] \" %s \" is not a valid sequence." % number)
    quit()


def main():
    if len(sys.argv) < 2:
        print("Usage: python TLF.py <sequence>")
        quit()

    luhn_check(sys.argv[1])

if __name__ == '__main__':
    main()

Pero no funciona correctamente:

[INVALID] 4532015112830366
[INVALID] 6011514433546201
[INVALID] 6771549495586802

y así sucesivamente…

Pero la lógica del código parece bien a mí. He seguido este flujo de trabajo:

La Fórmula De Luhn:

  1. Caer el último dígito del número. El último dígito es lo que queremos comprobar la contra
    Revertir los números
  2. Multiplicar los dígitos en las posiciones impares (1, 3, 5, etc.) por 2 y restar 9 a todos cualquier resultado mayor que 9
  3. Agregar todos los números juntos
  4. El dígito de control (el último número de la tarjeta) es la cantidad que sería necesario agregar para obtener un múltiplo de 10 (Módulo 10)
Con el fin de comprobar los dígitos en las posiciones impares que se debe utilizar: range(1, len(reverse_sequence), 2) lugar range(0, len(reverse_sequence), 2)

OriginalEl autor JChris | 2014-01-12

6 Comentarios

  1. 6

    Creo que el algoritmo no es la correcta.

    La segundo paso necesita de la suma de los dígitos de los productos en lugar de restar 9. Referencia: Wikipedia.

    En la Wikipedia tienes este ejemplo:

    def luhn_checksum(card_number):
        def digits_of(n):
            return [int(d) for d in str(n)]
        digits = digits_of(card_number)
        odd_digits = digits[-1::-2]
        even_digits = digits[-2::-2]
        checksum = 0
        checksum += sum(odd_digits)
        for d in even_digits:
            checksum += sum(digits_of(d*2))
        return checksum % 10
    
    def is_luhn_valid(card_number):
        return luhn_checksum(card_number) == 0
    
    
    result = is_luhn_valid(4532015112830366)
    print 'Correct:' + str(result)
    result = is_luhn_valid(6011514433546201)
    print 'Correct:' + str(result)
    result = is_luhn_valid(6771549495586802)
    print 'Correct:' + str(result)

    Resultado:

    >>>Correct:True
    >>>Correct:True
    >>>Correct:True
    Mi código comprueba si el número es válido. NO generar la validación de número! En Wikipedia es el opuesto.
    Sí, lo sé. PERO en la Wikipedia hay DOS ejemplos: uno para la generación y otra para la prueba. El código que he publicado en esta respuesta es la que comprueba la validación de número.

    OriginalEl autor phyrox

  2. 2

    Hay algunos errores en su código:

    result = divmod(sum_of_digits, 10)

    devuelve una tupla, sólo necesita el modulo, que es el uso

    result = sum_of_digits % 10

    Segundo, para comprobar su validez, no omitir el último dígito (que es la suma de comprobación), pero se incluyen en los cálculos. Uso

    reverse_sequence = list(int(d) for d in str(int(number[::-1]))) 

    Y comprobar el resultado sea cero:

    if not result:
        print("[VALID] %s" % number)

    O si usted insiste en mantener esta no necesita de la complejidad, la verificación por último dígito para ser inversa de suma de comprobación modulo 10: mantener

    reverse_sequence = list(int(d) for d in str(int(number[-2::-1])))

    pero el uso de

    if (result + last_digit) % 10 == 0:
        print("[VALID] %s" % number)

    Para una más simple y el más corto código, te puedo dar una referencia a mi mayor respuesta.

    OriginalEl autor alko

  3. 1

    ver este Python receta

    def cardLuhnChecksumIsValid(card_number):
        """ checks to make sure that the card passes a luhn mod-10 checksum """
    
        sum = 0
        num_digits = len(card_number)
        oddeven = num_digits & 1
    
        for count in range(0, num_digits):
            digit = int(card_number[count])
    
            if not (( count & 1 ) ^ oddeven ):
                digit = digit * 2
            if digit > 9:
                digit = digit - 9
    
            sum = sum + digit
    
        return ( (sum % 10) == 0 )

    OriginalEl autor Guy Gavriely

  4. 1

    El siguiente podría ayudar a algunas personas a iniciar con el Luhn algoritmo en python.

    num = list(input("Please enter the number to test (no space, no symbols, only \
    numbers): "))
    
    num = list(map(int, num))[::-1] #let's transform string into int and reverse it
    
    for index in range(1,len(num),2):
        if num[index]<5:
            num[index] = num[index] *2
        else: #doubling number>=5 will give a 2 digit number
            num[index] = ((num[index]*2)//10) + ((num[index]*2)%10)
    
    checksum=sum(num)
    
    print("checksum= {}".format(checksum))
    
    if checksum%10 !=0:
        print('the number is not valid')
    else:
        print('the number is valid!')

    OriginalEl autor Sébastien Wieckowski

  5. 1

    Me gustaría mantenerlo simple y fácil de leer, algo como esto:

    def luhn(value):
        digits = map(int, str(value))
        oddSum = sum(digits[-1::-2])
        evnSum = sum([sum(divmod(2 * d, 10)) for d in digits[-2::-2]])
        return (oddSum + evnSum) % 10 == 0

    Pero hay toneladas de maneras de hacer la misma cosa. Obviamente, usted tendría que hacer de manera diferente para ver el resultado real, esto resume el total para determinar si el valor es válido.

    Mejor!

    OriginalEl autor jacktrader

  6. 0

    Esta es la forma más concisa de python fórmula para el Luhn prueba que he encontrado:

    def luhn(n):
        r = [int(ch) for ch in str(n)][::-1]
        return (sum(r[0::2]) + sum(sum(divmod(d*2,10)) for d in r[1::2])) % 10 == 0

    La función de arriba y otras implementaciones de Luhn (en diferentes lenguajes de programación están disponibles en https://www.rosettacode.org/wiki/Luhn_test_of_credit_card_numbers .

    OriginalEl autor Andreina

Dejar respuesta

Please enter your comment!
Please enter your name here