Página 1 de 2

Calcular digito verificador

Enviado: 01 Set 2022 12:56
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


Calcular digito verificador

Enviado: 01 Set 2022 14:04
por alxsts
Olá!

Talvez encontre alguma ajuda aqui: Código de barra de uma conta de consumo

Calcular digito verificador

Enviado: 01 Set 2022 14:51
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" )

Calcular digito verificador

Enviado: 01 Set 2022 15:06
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.

Calcular digito verificador

Enviado: 01 Set 2022 15:10
por JoséQuintas
Mas do jeito que fiz tá errado, refazer os testes.

Calcular digito verificador

Enviado: 01 Set 2022 15:17
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 1527 vezes

Calcular digito verificador

Enviado: 01 Set 2022 15:38
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.

Calcular digito verificador

Enviado: 01 Set 2022 15:44
por JoséQuintas
no.png

Calcular digito verificador

Enviado: 01 Set 2022 15:50
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.

Calcular digito verificador

Enviado: 01 Set 2022 17:59
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.

Calcular digito verificador

Enviado: 01 Set 2022 18:16
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.

Calcular digito verificador

Enviado: 01 Set 2022 18:27
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

Calcular digito verificador

Enviado: 01 Set 2022 18:39
por JoséQuintas
Ok, não vai ser desprezado.
Porque soma na anterior, e deduz nessa.
Mas porque 9 e não 10 ?

Calcular digito verificador

Enviado: 01 Set 2022 18:50
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.

Calcular digito verificador

Enviado: 01 Set 2022 19:11
por JoséQuintas
Testei, mas deu inválido nos dois casos.