Entendendo como é formada a linha digitável nos boletos bancários

Introdução


Todo boleto bancário exige uma série de especificações que devem ser seguidas com o intuito de estabelecer uma padronização de conteúdo. A pouco tempo adquiri uma documentação da CEF - Caixa Econômica Federal, onde constava as principais características que um boleto deveria ter para poder entrar em circulação. Esta postagem levará em conta a formação da linha digitável dos boletos para a CEF.


Descrição

Uma linha digitável segue a seguinte estrutura:

Figura 1. Layout Linha Digitável

Onde:

B = banco
M = moeda(real = 9)
L = campo livre
d = dígito verificador de campo
D = dígito verificador geral
V = valor e vencimento


A linha digitável de qualquer boleto bancário é composto por 5 campos. Abaixo segue as respectivas descrições:
  • Campo 1: as posições de 1 a 3 refere-se ao código da agência, neste exemplo 104, a quarta posição refere-se a moeda(9 para o real) as próximas cinco posições são os primeiros dígitos do campo livre, mais um dígito verificador de campo.
  • Campo 2: é composto pelas posições de 6 a 15 do campo livre e um dígito verificador de campo.
  • Campo 3: composto pelas posições de 16 a 25 do campo livre e um dígito verificador de campo.
  • Campo 4: dígito verificador geral da linha digitável.
  • Campo 5: composto pelo "fator de vencimento" com quatro posições e o valor nominal do boleto, sem vígulas. Torna-se necessário a inclusão de zeros entre os dois, afim de, compor as quatorze posições.
Campo livre


O Campo Livre é formado pelo nosso número(número gerado a cada boleto) com 10 dígitos e mais 15 dígitos contendo o código do cedente fornecido pela agência.

Observe que nos três primeiros campos é colocado um ponto após a 5ª posição, afim de, facilitar a digitação caso necessário. No 5º campo, preenche-se com zero as posições restantes entre o fator de vencimento e o valor do documento.

Nota: O fator de vencimento é obtido pela diferença entre a Data Base(07/10/1997) e a data de vencimento do título. O mesmo aparece nas 4 primeiras posições do último campo.
Utiliza-se o MÓDULO 10 para cálculo do dígito verificador de campo. Para realizar o cálculo execute os seguintes passos:
  1. Inverta os valores do campo e inicialize um fator multiplicativo com 2. Tal fator irá alternar entre os valores 1 e 2.
  2. Multiplique do dígito atual do campo pelo fator multiplicativo.
  3. Caso o valor multiplicado for maior que 10, aplique a regra dos noves fora. Por exemplo 12, 12 - 9 = 3.
  4. Soma-se o valor obtido a um totalizador. Repita os passos 2, 3 e 4 até percorrer todo a extensão numérica.
  5. Faça a divisão do totalizador obtido por 10.
  6. Subtraia o resto valor obtido no passo anterior, de 10.
Abaixo segue uma função em Python que realiza o cálculo desse dígito para exemplificação.
def verifier_digit(field):        
 mult = 2
 sum = 0

 for i in range(len(field)-1, -1, -1):
     x = (int(field[i]) * mult)

     if(x > 10):
         x = (x % 10) + 1
  
     sum += x

     if(mult == 2):
         mult = 1
  
     else:
         mult = 2

 if(not (sum % 10)):
     sum = 0

 else:
     sum = 10 - (sum % 10)

 return sum
O cálculo do fator de vencimento é mais simples, basta subtrair a data de vencimento do título pela Data Base(07/10/1997).
def diff_date(date_comp):
 date_def = date(1997,10,7)

 return (str(date_comp - date_def))[0:4]
O nosso número segue o MÓDULO 11, com pesos entre 2 a 9. Segue os passos:
  1. Inverta os valores do campo e inicialize um fator multiplicativo com 2.
  2. Multiplique o valor do dígito do campo pelo fator multiplicativo.
  3. Caso o fator multiplicativo for maior que 9, inicialize-o com 2.
  4. Soma-se o valor obtido a um totalizador. Repita os passos 2, 3 e 4 até percorrer todo a extensão numérica.
  5. Faça a divisão do totalizador obtido por 11.
  6. Subtraia o resto valor obtido no passo anterior, de 11.
Abaixo segue a implementação em Python do nosso número.
def calc_our_number(our_number):
 mult = 2
 sum = 0

 for i in range(len(our_number) - 1, -1, -1):
     sum += (int(our_number[i]) * mult)

     if(mult >= 9):
         mult = 2

     else:
         mult += 1

 sum = 11 - (sum % 11)

 if(sum > 9):
     sum = 0

 return our_number + '-' + str(sum)
Os passos para cálculo do dígito verificador geral segue os mesmos do nosso número. No entanto, deve ser passado para função uma sequência seguindo a ordem:

BANCO + MOEDA + CAMPO 5 + NOSSO NÚMERO + CÓDIGO CEDENTE

Para exemplificação seguem os códigos abaixo:

Dígito verificador geral.
def general_digit(line):
 mult = 2
 sum = 0

 for i in range(len(line) - 1, -1, -1):
     sum += (int(line[i]) * mult)

     if(mult >= 9):
         mult = 2

     else:
         mult += 1

 sum = 11 - (sum % 11)

 if(sum > 9 or sum or not sum):
     sum = 1

 return sum
Montagem linha digitável

E por fim a implentação da montagem com da linha digitável.
def mount_line(bank, currency, code_transf, our_number, factor, value):
 diff = 10 - len(str(value))

 field_1 = str(verifier_digit(bank + currency + our_number[0:5]))
 field_2 = str(verifier_digit(our_number[5:10] + code_transf[0:5]))
 field_3 = str(verifier_digit(code_transf[5:15]))
 field_4 = factor + ('0' * diff) + value

 g_digit = general_digit(bank + currency + field_4 + our_number + code_transf)

 return  bank + currency + our_number[0] + '.' + our_number[1:5]+ field_1\
         + ' ' + our_number[5:10] + '.' + code_transf[0:5] + field_2\
         + ' ' + code_transf[5:10] + '.' + code_transf[10:15] + field_3\
         + ' ' + str(g_digit) + ' ' + field_4
Pode-se incorporar as funções apresentadas em um arquivo de módulo para uso posterior.

José Mauro da Silva Sandy


Leia Também

13 comentários:

  Alexandre

28 de fevereiro de 2009 12:32

Opa, esses codigos me ajudaram bastante... porém tive q fazer alguma modificações.... nada demais pq estou gerando boleto para o itau.

Porém na função general_digit acho q tem um erro... no final voce faz:
if(sum > 9 or sum or not sum):
sum = 1

dessa forma todo valor q tiver em sum vai ser trocado por 1.

Segundo o manual do itau so deve ser trocado por 1 se o resultado for igual a 11,10,1 ou 0.

entao troquei a linha para :
if(sum > 9 or sum==1 or not sum):
sum = 1

  maurim

28 de fevereiro de 2009 13:37

E ai Alexandre, blza?

Fico feliz por ter podido auxiliar para algo.

Agradeço as observações que você fez em relaçãoao erros irei verificá-los assim que puder para poder corrigí-los.

Ah! Se der me manda o manual do Itaú para eu dar uma olhada.

Abraço.

  Alexandre

2 de março de 2009 13:16

Opa, entao ja q vai verificar os erro encontrei outro :P

na funcao verifier_digit vc faz:
if(x > 10):
x = (x % 10) + 1

onde o certo seria:
if(x >= 10):
x = (x % 10) + 1

isso segundo o manual do itaú também. Coloquei ele aqui: http://rapidshare.com/files/204447989/COBRANCA_400_BYTES_CNAB_-_VERSAO_7.0_-_ITAU_-_SETEMBRO_2007.doc.html

t+

  maurim

2 de março de 2009 23:30

Putz...

Deixei altos furos hein. Obrigado por mais essa, não deu pra corrigir os erros pq to meio enrolando com um projeto aki.

Baixei a documentação que você anexou e no final de semana vou corrigir os erros e postar uma classe que resolva os esquema das duas carteiras.

Valeu mesmo pelas dicas, vale muito mesmo.

T+

  mila_calcados

13 de abril de 2010 01:13

Gostaria de saber o que acontece se digitar no caixa eletronico o digito verificador errado e for assim mesmo compensado???

  José Mauro

13 de abril de 2010 01:31

Olá mila_calcados!

Até onde eu sei uma linha digitável informada de forma errada será bloqueada pelo Caixa Eletrônico, Bankline...

No entanto, informada de forma errada, entende-se por alguma combinação que intervirá na validade das informações, e.g., valor de moeda inválido.

Caso a linha seja informada de forma pelo usuário e está seja válida para critérios de autencidade a boleta será compensada.

Ai deve-se procurar o gerente da conta para tentar solucionar o problema.

Não sei se ajudei mais ao meu ver seria isso.

Abraço.

  Paulo Ghiraldi

13 de abril de 2010 13:50

boa tarde, vi um site que atualiza o boleto para que seja pago no bankline, mesmo apos o vencimento, será que é real ou estarei enviando dinheiro a algum espertinho? pelo teste que fiz, gereou a mesma numeração só alterou a parte final para poder compensar o pagamento

  JP Juliano Pompilio

21 de janeiro de 2011 09:56

Olá pessoal meu é Juliano Pompilio sou Programador Junior e ainda estou aprendendo..Alguém ja montou a linha digital do 748-Sicredi...Eu li e reli o manual e nao to conseguindo montar...Eu estou me perdendo nas posições,ou seja onde cada informação deve se encontrar...Vi o layout do Banco do Brasil e é mais simples de entender esse do Sicredi não consegui..Já to de cabeça quente e acho que não vou terminar no prazo isso..rsrsrs
Se alguem puder me ajudar me adicionem no msn julianopompilio@hotmail.com
Agradeço desde já...
'Aprendendo a cada dia'

  José Mauro

21 de janeiro de 2011 11:41

Bom dia JP Juliano Pompilio!

Já precisei fazer de outros bancos mas o Sicredi nunca precisei.

Disponibilize o manual que tentarei realizar um exemplo da formação da linha digitável.

Abraço.

José Mauro

  Boleto Atualizado

24 de maio de 2012 00:56

Este comentário foi removido por um administrador do blog.
  Anônimo

8 de dezembro de 2012 07:38

Bom Dia!

Alguém já conseguiu a Linha Digitável e Código de Barras do SIcredi, estou precisando.

gilvani@brisottiruoso.com.br
Gilvani Ruoso

  Anônimo

17 de março de 2013 06:29

Olá gilvani
caso vc queira gerar o codigo de barras e linha digitavel do SICREDI, chame via api ASP:


http://www.hcsi.com.br/webservice/sicredi/gerar.asp

Parametros:
01. Banco
02. Agência
03. Posto
04. Conta
05. Cendente
06. Nº do Boleto (5 digitos)
07. Valor
08. Vencimento (dd/mm/yyyy)
09. Carteira
10. Tipo de Registro (1=COM / 3=SEM)
11. Com valor (1=COM / 0=SEM)

Retorno:
1. Código de Barra
2. Linha Digitavel
3. Nosso Número


Espero ter ajudado


Hendell Cardoso
contato@hcsi.com.br

  Anônimo

9 de julho de 2013 19:27

alguem ai sabe me informa, como que eu descubro de quem é a conta que emitiu esse boleto " 21890.01007 00145.602082 00371.313180 1 00000000000000 " eu sei que ele é do banco Bomsucesso mas o que eu queria mesmo saber é para que conta o deposito vai.
Desde já agradeço.