Modulus 11 (mod11) é um algoritmo para criar um dígito de verificação baseado numa sequência de números pré determinada. Ele é bastante parecido com o Algoritmo de Luhn, com a diferença de que usa pesos para multiplicar cada dígito da sequência. Estes pesos variam de 2 a n, onde n pode variar de aplicação para aplicação.
Diferentemente do algoritmo de Luhn, é difícil encontrar informações precisas sobre o mod11 e suas implementações variam bastante de programador para programador. Uma boa implementação que eu encontrei, foi a da HP:
Diferentemente do algoritmo de Luhn, é difícil encontrar informações precisas sobre o mod11 e suas implementações variam bastante de programador para programador. Uma boa implementação que eu encontrei, foi a da HP:
- Tome uma sequência de números.
- Começando da última posição, multiplique o item por 2 e adicione o resultado ao somatório, que deve iniciar com 0.
- Repita o passo 2 para os outros itens da sequência, lembrando de incrementar em 1 o fator multiplicador (quando este for maior que o valor máximo de multiplicação, deve ser reiniciado com o valor 2).
- Divida o somatório por 11 e considere o resto da divisão.
- Subtraia de 11, o valor obtido no passo 4 e o resultado será o dígito de verificação.
Apesar de parecer perfeito à primeira vista, o algoritmo apresentado possui duas falhas. Caso o resultado do passo 4 for 0 ou 1, o resultado do passo 5 será 11 ou 10, respectivamente. Isto contraria a idéia do dígito de verificação ser um número entre 0 e 9.
Segundo a implementação da HP, um resultado 10 significa que a sequência de números é inválida para utilização com o algoritmo. Já um resultado 11 implica que a saída do algoritmo é 0. Seria relativamente fácil implementar esta solução, mas isto significaria que muitos números não poderiam ser usados com este algoritmo.
Para quem não sabe, muitos documentos brasileiros utilizam o mod11 para cálculo dos seus dígitos verificadores, como o CPF, CNPJ e Título de Eleitor, além de códigos mais diversos, como o código de procedimentos do SUS (Sistema Único de Saúde). Sendo assim, era preciso adaptar o algoritmo para trabalhar com qualquer saída, tratando-a.
A solução que eu encontrei foi:
- Tome uma sequência de números.
- Começando da última posição, multiplique o item por 2 e adicione o resultado ao somatório, que deve iniciar com 0.
- Repita o passo 2 para os outros itens da sequência, lembrando de incrementar em 1 o fator multiplicador (quando este for maior que o valor máximo de multiplicação, deve ser reiniciado com o valor 2).
- Subtraia de 11, o resto da divisão do somatório por 11.
- Se o resultado obtido no passo 4 for maior que 9, o dígito verificador será 0. Senão, o dígito verificador será o próprio resultado do passo 4.
Como pode ser percebido, a diferença do segundo, para o primeiro algoritmo apresentado é que, em vez de descartar uma sequência de números cujo dígito verificador dê 10, o segundo retorna o valor 0 para o mesmo. Isto garante que o mesmo funcionará para qualquer sequência de números.
Com a implementação do algoritmo mod11 como uma função separada, fica fácil calcular os dígitos verificadores de quaisquer documentos que o utilizem, tornando os códigos mais limpos e aumentando a reusabilidade de código. Para concluir, segue abaixo a implementação deste algoritmo feita por mim em Python.
# Modulus 11 # # AUTHOR: Jose Lopes de Oliveira Junior # http://versaopropria.blogspot.com # jlojunior _at_ gmail _dot_ com # # DATE: 2008/10/27 # # LICENCE: GPLv3 - http://www.gnu.org/licenses/gpl.html # # DESCRIPTION: Implements Modulus 11 check digit algorithm # +as a function. See the docstring for more details. def mod11(list, max_weight=7): """Implements Modulus 11 check digit algorithm. It's a variation of the HP's Modulus 11 algorithm. Requires the sequence to be calculated in a list of integers. The HP's Modulus 11 algorithm can be accessed through the following link: http://docs.hp.com/en/32209-90024/apds02.html """ sum = 0 weight = 2 # Iterates through the list from right to left, # +multiplying each value for it's weight. If # +the weight reaches max_weight, then it is # +restarted to 2. for item in reversed(list): sum += item * weight weight += 1 if weight > max_weight: weight = 2 mod = 11 - sum % 11 # HP's Modulus 11 algorithm says that a 10 # +result is invalid and a 11 result is equal # +to 0. So, both values are returned as 0. if mod > 9: return 0 else: return mod
Código 1. Modulus 11 em Python.
Leia Também
- O Algoritmo de Luhn – Entenda o funcionamento e algumas aplicações deste famoso algoritmo para criação e checagem de dígitos de verificação.
- Calculando a Data da Páscoa em Python – Aprenda como são calculados os feriados móveis do ano.
- O Crivo de Eratóstenes em Python – Aprenda como funciona e veja um exemplo de implementação deste algoritmo em Python.
- Destrinchador de IPs em Java – Um Applet que obtém informações sobre um endereço IP e sua máscara.
Nenhum comentário:
Postar um comentário