Calcular digito verificador

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Calcular digito verificador

Mensagem por gilbertosilverio »

Ola Amigos,

Como e feita a verificação do digito verificador das contas de telefone, agua, dare...

Tanto pela rotina que o Quintas disponibilizou como pela 'modulo11' da a mesma coisa, só que não e a que esta impressa, no caso neste exemplo 84650000000 - 1, pelo calculo da 9

E pelo modulo11 realmente que verificamos este numero ou existe outra forma?

Código: Selecionar todos


FUNCTION VERIFICAR_DIGITO()
    PRIVATE cTitle, cText, DT:=SPAC(11)
    PRIVATE nDG:=[ ], cDV:=[ ]
    MsgGet_mod11( [Entre numero para verificar digito], [Informe o numero], @DT )
    nDG:=CalculaDigito( @DT, "11" )
    HWG_MSGINFO([Digito verificador para ]+DT+ [ - ]+nDG)
    cDV    := modulo11( @DT, 2, 9 )
    HWG_MSGINFO([Digito verificador para 11 ]+DT+ [ - ]+cDV)
RETURN NIL

Anexos
t3.jpg
t3.jpg (11.62 KiB) Exibido 1529 vezes
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Calcular digito verificador

Mensagem por alxsts »

Olá!

Talvez encontre alguma ajuda aqui: Código de barra de uma conta de consumo
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Testei aqui mas só deu certo pra uma das contas.

Código: Selecionar todos

#include "inkey.ch"

PROCEDURE Main

   LOCAL cNumero := Space(70), GetList := {}

   SetMode(40,100)
   CLS

   DO WHILE .T.
      @ 5, 1 SAY "Validar:" GET cNumero PICTURE Replicate( "9", 70 ) VALID ValidaDoc( cNumero )
      READ
      IF LastKey() == K_ESC
         EXIT
      ENDIF
   ENDDO

   RETURN

STATIC FUNCTION ValidaDoc( cNumero )

   LOCAL lOk

   lOk := ValidDocPag( cNumero )
   @ 10, 1 SAY Pad( Iif( lOk, "OK", "ERRO" ), 10 )

   RETURN lOk

FUNCTION ValidDocPag( cNumero )

   LOCAL cTmp

   cTmp := Substr( cNumero, 1, 3 ) + Substr( Trim( cNumero ), 5 )

   RETURN Substr( cNumero, 4, 1 ) == CalculaDigito( cTmp, "11" )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Apelei pra ignorância, e aconteceu algo esquisito:

Código: Selecionar todos

#include "inkey.ch"

PROCEDURE Main

   LOCAL cNumero := Space(70), GetList := {}

   SetMode(40,100)
   CLS

   DO WHILE .T.
      @ 5, 1 SAY "Validar:" GET cNumero PICTURE Replicate( "9", Len( cNumero ) ) VALID ValidaDoc( cNumero )
      READ
      IF LastKey() == K_ESC
         EXIT
      ENDIF
   ENDDO

   RETURN

STATIC FUNCTION ValidaDoc( cNumero )

   LOCAL lOk, nCont

   FOR nCont = 0 TO 4
      lOk := ValidDocPag( cNumero, nCont )
      @ 10 + nCont, 1 SAY Pad( Iif( lOk, "OK", "ERRO" ), 10 )
   NEXT

   RETURN lOk

FUNCTION ValidDocPag( cNumero, nPos )

   LOCAL cTmp

   cTmp := Right( Left( cNumero, 4 ), nPos ) + Substr( Trim( cNumero ), 5 )

   RETURN Substr( cNumero, 4, 1 ) == CalculaDigito( cTmp, "11" )

FUNCTION CalculaDigito( cNumero, cModulo )

   LOCAL nFator, nCont, nSoma, nResto, nModulo, cCalculo

   hb_Default( @cModulo, "11" )
   IF Empty( cNumero )
      RETURN ""
   ENDIF
   cCalculo := AllTrim( cNumero )
   nModulo  := Val( cModulo )
   nFator   := 2
   nSoma    := 0
   IF nModulo == 10
      FOR nCont = Len( cCalculo ) To 1 Step -1
         nSoma += Val( Substr( cCalculo, nCont, 1 ) ) * nFator
         nFator += 1
      NEXT
   ELSE
      FOR nCont = Len( cCalculo ) To 1 Step -1
         nSoma += Val( Substr( cCalculo, nCont, 1 ) ) * nFator
         IF nFator == 9
            nFator := 2
         ELSE
            nFator += 1
         ENDIF
      NEXT
   ENDIF
   nResto := 11 - Mod( nSoma, 11 )
   IF nResto > 9
      nResto := 0
   ENDIF
   cCalculo := Str( nResto, 1 )

   RETURN cCalculo
Pra cada conta deu certo de um jeito, com nCont=0 ou nCont=1, significa com ou sem a parte antes do dígito.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Mas do jeito que fiz tá errado, refazer os testes.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Conta de luz bate, usando ou não o prefixo
Conta de água de jeito nenhum.
teste.png
teste.png (8.26 KiB) Exibido 1517 vezes
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Achei outro documento, mostrando que o dígito pode ser módulo 10 ou 11, mas nada feito.
Conta de luz bate com módulo 11, conta de água com nenhum.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

no.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

aqui tem versão 6, de 22/06/20 mas o cálculo é o mesmo.

https://portal.febraban.org.br/pagina/3 ... rrecadacao

sem mais novidades.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Calcular digito verificador

Mensagem por gilbertosilverio »

Quintas,

Baseado no manual da Fenabran, o calculo e esse aqui:

Código: Selecionar todos

// funcao do harbourboleto
FUNCTION DC_Mod10( mNMOG )
   LOCAL mVLDG, mSMMD, mCTDG, mRSDV, mDCMD
   mSMMD:=0
   FOR mCTDG := 1 TO LEN(mNMOG)
      mVLDG := VAL(SUBSTR(mNMOG, LEN(mNMOG) - mCTDG + 1, 1)) * IF(MOD(mCTDG,2) == 0, 1, 2)
      mSMMD += mVLDG - IF(mVLDG > 9, 9, 0)
   NEXT
   mRSDV := MOD(mSMMD, 10)
   mDCMD := IF(mRSDV == 0, "0", STR(10 - mRSDV, 1))
RETURN mDCMD
Como o pessoal estava digitando os dados errado, na hora do pagamento dava erro, com isso consigo verificar se a digitação esta correta.

Agradeço sua atenção.
Anexos
t4.jpg
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Esse é o módulo 10.
Da esquerda pra direita, 2, 1, 2, 1....
O loop fica mais simples fazendo de trás pra frente, e verificando se o elemento é par ou ímpar.

Código: Selecionar todos

FOR EACH cChar IN cCodigo DESCEND
   nTotal += Val( cChar ) * iif( Mod( cChar:__EnumIndex / 2 ) == 0, 1, 2 )
NEXT
A não ser que usando DESCEND também inverta a ordem dos elementos.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Não querendo ser chato, mas sendo.
Fonte é pra nós e não pro computador.
Sei que copiou o fonte, mas.....
Veja o que acontece só alterando os nomes

Código: Selecionar todos

// funcao do harbourboleto
FUNCTION DC_Mod10( cNumero )

   LOCAL nValor,  nSoma := 0, nPos,  nResto, nDigito

   FOR nPos := 1 TO LEN( cNumero )
      nValor := VAL(SUBSTR(cNumero, LEN(cNumero) - nPos + 1, 1)) * IF(MOD(nPos,2) == 0, 1, 2)
      nSoma += nValor - IF( nValor > 9, 9, 0)
   NEXT
   nResto := MOD( nSoma, 10 )
   nDigito := IF( nResto == 0, "0", STR(10 - nResto, 1 ) )
RETURN nDigito
Deixa até na dúvida se esta linha está correta:

Código: Selecionar todos

      nSoma += nValor - IF( nValor > 9, 9, 0)
É... porque se qualquer valor maior que 9 vai ser desprezado, isso inclui os números 5 a 9 multiplicados por 2.
Significa que 5555 e 6666 e 7777 e 8888 e 999 e todas as combinações deles dariam o mesmo resultado, o que seria uma checagem muito fraca.
nota: tudo bem, que são intercalados com outros números, e nesta explicação coloquei juntos, mas em 44 números, 22 podem ser acima de 4
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Ok, não vai ser desprezado.
Porque soma na anterior, e deduz nessa.
Mas porque 9 e não 10 ?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Ok também, de acordo com o manual soma CADA dígito e não o resultado da multiplicação.

5 * 2 = 10 = 1 + 0
6 * 2 = 11 = 1 + 1
...
9 * 2 = 18 = 1 + 9

por coincidência, é o número menos 9.

Tá valendo a transformação pra FOR/EACH, só precisa ajustar a soma pra ficar igual.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Calcular digito verificador

Mensagem por JoséQuintas »

Testei, mas deu inválido nos dois casos.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder