No final da noite de hoje vi-me desafiado por um amigo que em seu artigo citou o Algoritmo de Luhn que consiste na validação de Dígitos Verificadores.
Dígito verificador é um meio de validação e autenticação de uma série númerica para que se evite fraudes e perdas de informações.
Não entrarei em detalhe sobre a descrição do algoritmo que foi bem apresentado pelo artigo anteriormente citado. Como o desafio apresentado era descobrir o erro relatado:
"...Adicione o primeiro número (dígito de verificação) ao somatório geral, que deve iniciar com zero...."
O que acontece é que o dígito verificador não entra no cálculo para verificação da autenticidade da série. Somente a título de curiosidade gostaria de acrescentar uma breve descrição sobre os dígitos que formam a série númerica nos cartões.
A série númerica dos cartões de créditos possuem dezesseis dígitos que especificam uma gama de informações relacionadas a operadora do cartão, a entidade emissora, informações da conta, etc.
Da esquerda para direita, os seis primeiros dígitos referenciam a entidade emissora. Sendo que, o primeiro identifica a atividade da empresa e possui a seguinte descrição:
Apresentarei um código em Python que pedirá a entrada da série(obrigatório) e o dígito verificador(opcional) para verificação da autencidade. Caso o dígito informado for incorreto ou omitido será apresentado o dígito verificador.
A série númerica dos cartões de créditos possuem dezesseis dígitos que especificam uma gama de informações relacionadas a operadora do cartão, a entidade emissora, informações da conta, etc.
Da esquerda para direita, os seis primeiros dígitos referenciam a entidade emissora. Sendo que, o primeiro identifica a atividade da empresa e possui a seguinte descrição:
1- 2. Companhia aéreaO último dígito é o verificador, foi o que nos levou a essa breve apresentação, e o restante são informações relacionadas a conta bancária dos clientes.
3. Empresa de viagens, entretenimento e American Express(era ligada a navegação)
4. Visa
5. MasterCard
6. Discover)
7. Petróleo
8. Telecomunicações
0- 9. Outras atividades
Apresentarei um código em Python que pedirá a entrada da série(obrigatório) e o dígito verificador(opcional) para verificação da autencidade. Caso o dígito informado for incorreto ou omitido será apresentado o dígito verificador.
Obs.: Neste código será considerado somente o primeiro caracter informado na parte relacionada ao dígito verificador. Qualquer outro caracter será desconsiderado para cálculo.
#!/usr/bin/env python # Luhn algorithm # # AUTHOR: Jose Mauro da Silva Sandy - http://informacaocomdiversao.blogspot.com # # CONTACT: jmsandy _at_ gmail _dot_ com # # DATE: 2008-10-26 # # More information about Luhn algorithm, visit: # http://en.wikipedia.org/wiki/Luhn_algorithm ############################################################################### import easygui import math def verify_card(number_card): """Performs the sum of digits""" # Converting the string to list card = list(number_card[0]) # Reversing the positions's list card.reverse() sum = 0 for index in range(len(card)): value = int(card[index]) if(not math.fmod(index,2)): value *= 2 if(value >= 10): value %= 10 value += 1 sum += value # Checking if the sum is divisible for 10 mod = int(math.fmod(sum,10)) # If mod_10 like 10, then mod_10 = 0 if((mod >= 10) or (mod == 0)): mod_10 = 0 else: mod_10 = (10 - mod) return mod_10 msg = "Enter with number's card: " title = "Number's Card" values_names = ["Number's Card", "Verify digit"] values = [] values = easygui.multenterbox(msg, title, values_names) # Converting the values received to integer # If the value is found valid, show result # Otherwise, show error message try: int(values[0]) if(values[1]): int(values[1]) sum = verify_card(values) digit = int(values[1][0]) # If the number's card is valid, show result # Otherwise, show the valid value if(sum == digit): type_card = {'1': "Companhia Aerea", '2': "Companhia Aerea", '3': "Empresa de viagens, entretenimento ou American Express", '4': "Visa", '5': "MasterCard", '6': "Rede Discover", '7': "Petroleo", '8': "Telecomunicacoes", '9': "Outras Atividades", '0': "Outras Atividades" } easygui.msgbox("Number's card valid - " + type_card.get(values[0][0])) else: s = str(sum) easygui.msgbox("Digit verifier invalid, should to be " + s[0]) else: sum = verify_card(values) s = str(sum) easygui.msgbox("Digit verifier invalid, should to be " + s[0]) except: easygui.msgbox("Invalid Value!")José Mauro da Silva Sandy
Leia
- O Algoritmo de Luhn - Apresenta maiores detalhes sobre a implementação do algoritmo
2 comentários:
26 de outubro de 2008 às 10:40
Salve, simpatia!
Gostei! Estendeu o assunto! Mas o erro encontrado está errado. Note: eu passei 2 algoritmos. O primeiro levava em consideração o DV, pois desejava validar o número passado. O segundo não levava em consideração, pois visava o cálculo do mesmo. Inclusive, nas referências que utilizei, só constava o algoritmo que leva em consideração o DV. O outro, eu adaptei.
Contudo, a postagem foi legal. Essa do primeiro dígito eu não sabia. Já quanto à codificação, tenho algumas ressalvas:
1. (mod == 0)? (not mod) seria mais elegante...
2. mod = int(math.fmod(sum,10)) não teria o mesmo resultado que mod %= 10? Tudo bem que, pelo que já li, a função fmod() tem uma precisão melhor, mas quando você a utiliza dentro de uma função int(), ela terá o seu valor truncado, perdendo o seu diferencial...
3. Acho que seria mais fácil você trabalhar com uma string de inteiros. Pelo que entendi, você recebe uma string e a transforma numa lista de caracteres, o que adiciona a linha value = int(card[index]) ao for. Trabalhar com uma lista de inteiros também facilitaria em for item in card: (lembra?!)
4. PEP8 Na cabeça: http://versaopropria.blogspot.com/2008/10/o-estilo-de-programao-pep8.html
Ainda há um erro lá que ninguém achou...
:D
26 de outubro de 2008 às 21:12
Fala, Zé!
Inicialmente quanto ao erro não consegui achar, em sua postagem irei apresentar uma outra opção.
Agora vamos as ressalvas:
1) Quanto a legibilidade do código você tem completa razão é que eu estou me acostumando com isso...já melhorei bastante.
2) Na verdade eu não estou pegando o módulo do valor contido em mod, mod %= 10, e sim o módulo do valor contido em sum está sendo atribuido em mod. Poderia ser algo do tipo: mod = sum % 10
3) Resolvi trabalhar com string mais pelo fato de utilizar o módulo easygui e fiquei obrigado a mexer com string. Quanto ao for tinha pensado em algo: for index in range(0,len(list),2), para realizar a multiplicação de 2 em 2. De qualquer forma acredito que o fato de trabalhar com indice neste caso foi uma boa prática.
4) Com certerza e se você reparar aos poucos estou mudando meus hábitos.
E ao meu ver o erro pode ser......
[]s
Postar um comentário