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 SandyLeia
- 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