pix-api icon indicating copy to clipboard operation
pix-api copied to clipboard

Validação do CRC 16 e EMV

Open felipecamargo opened this issue 4 years ago • 57 comments

Percebi que muitos QR CODE estão sendo enviados com CRC 16 calculado invalido. E pouquíssimos PSP's pagadores estão validando tanto o CRC16 quanto o padrão do EMV Merchant Presented Mode como um todo.

Quanto a Estrutura EMV, pelo que eu observei não estão sendo validados:

  • Reference label até 25 caracteres.
  • Merchant Name até 25 caracteres.
  • City Name até 15 caracteres.

A maioria dos PSPs estão aceitando QR CODEs conforme listado abaixo, provavelmente os único bancos que estão tentando realizar as consistências do Padrão EMV e também dos certificados dos sites QR CODE dinâmico são Itaú e Banco do Brasil.

Exemplo:

  1. Iniciado de forma incorreta >>> 0020101021226990014br.gov.bcb.pix2577qrcode.pix.bancobmg.com.br/qrs1/01mWFiCMHqRMdrkzWFWazsiurgfoqpsJFbuXx3IcpRqfj52040000530398654040.015802BR5917JEFFERSON F SOUZA6009SAO PAULO62290525QRS1-F5CMMUTDLOVWF8UBT7Q4630413DF -> calculado errado deveria ser 2E7D

  2. Mal formatado 000201 2640 0014BR.GOV.BCB.PIX 0114+55149916479660200 52040000 5303986 54030.05 802BR5921JULIO DE SOUZA RUGOLO6009SAO.PAULO6238050050300017BR.GOV.BCB.BRCODE01051.0.06304BD79

  3. CRC 16 invalido 00020126360014BR.GOV.BCB.PIX0114+55339999117485204000053039865802BR5924LEANDRO ALVES PEREIRA 6009SAO.PAULO623450300017BR.GOV.BCB.BRCODE01051.0.063044867 -> deveria ser C3F4.

  4. Mal formatado 000201 010212 2641 0005Cielo< deveria ser indicação de BR CODE -> 14br.gov.bcb.pix 0116001019064975000102087748103252040000530398654120000000031005802BR5921AUTO POSTO BASE AEREA6011CURITIBA PR801010033"https://www.cielo.com.br/qrcode"0116111117082C14677A0212171120183512030420000404000105020106020163043256

  5. Mal formatado 000201 2653 0014BR.GOV.BCB.PIX [email protected] 0200 tamanho 00 não é permitido pelo padrão EMV. 52040000530398654030.05802BR5922ANTONIO TAKESHI FUKUDA6009SAO.PAULO6238050050300017BR.GOV.BCB.BRCODE01051.0.063045B1A

  6. Merchant Name 000201 2636 0014br.gov.bcb.pix 0114+5531998925047 52040000 5303986 54071000.00 5802BR 5938SUELI DO CARMO PEREIRA DA SILVA KUSTER -- Limite de 25 caracteres 6008CONTAGEM 6241 0503*** 5030 0017br.gov.bcb.brcode 01051.0.0 63049602

  7. Mal Formatado (nubank) 000201 2662 0014BR.GOV.BCB.PIX 013639b6c11f-8383-4378-87c1-ce62df204ab8 0200 <<< NÃO PODE SER TAMANHO 00 5204000053039865406127.505802BR5925LARISSA JUSTUS RAYMUNDO 36009SAO PAULO61080540900062160512NUomZK5qzGvA630440BB

  8. Mal Formatado (nubank) 000201 2672 0014BR.GOV.BCB.PIX 18 01366ae8a1ab-8a46-49ef-9a14-6b03df474f6a 40 0210Toma lim㯵2 040000 530398654046.005802BR5924F D C HUMMEL EIRELI - ME6009SAO PAULO61080540900062160512NUNFFQwm3oLJ63040974

felipecamargo avatar Nov 17 '20 21:11 felipecamargo

Percebi que muitos QR CODE estão sendo enviados com CRC 16 calculado invalido. E pouquíssimos PSP's pagadores estão validando tanto o CRC16 quanto o padrão do EMV Merchant Presented Mode como um todo.

Quanto a Estrutura EMV, pelo que eu observei não estão sendo validados:

Reference label até 25 caracteres. Merchant Name até 25 caracteres. City Name até 15 caracteres.

@felipecamargo , obrigado pelo reporte.

ninrod avatar Nov 18 '20 11:11 ninrod

@felipecamargo Aproveito a issue, muito bem colocada, para agregar algumas informações pertinentes:

  1. Mal formatado 2641 00-05 Cielo **< deveria ser indicação de BR CODE -> 14br.gov.bcb.pix 01-16 0010190649750001 02-08 77481032

Isso parece ser um BRCode contendo um 'rail' do tipo "Cielo" (os campos '01 e '02 que seguem nao parecem ter relação com o Pix mesmo). Neste caso, esse formato de GUI EMV Cielo estaria errado de fato (pela especificação EMV). EDIT3: nao esta errado, se Cielo for um ApplicationId registrado (mas está fora do contexto Pix, nao se validam outros rails; cada um faz a sua parte).

EDIT: não se espera que os campos 01, 02, desse arranjo Cielo sejam Pix-like... um pagador Pix, ao ler este QR, deveria ignorar tudo o que está abaixo desse objeto 26 no exemplo (caso esteja esperando pagar um Pix). Apenas um pagador Cielo vai ler e entender o que vem ali.

EDIT2: um Pix poderia conviver perfeitamente no mesmo BRCode, mas estaria sob um objeto 27..., e etc.

  1. Merchant Name ... 6241 0503*** 50-30 00-17 br.gov.bcb.brcode 01-05 1.0.0

Neste (e em varios outros casos) aparece esse objeto 50 (sob o template 62). Isto não existe (gui br.gov.bcb.brcode, versão 1.0.0), não deve ser utilizado (versão obsoleta do manual BRCode).

dmkamers avatar Nov 18 '20 15:11 dmkamers

Pessoal, boa tarde!

Alguém poderia dar uma idéia de como calcular o CRC16?

Agradeço!

jeansentose avatar Nov 23 '20 17:11 jeansentose

Pessoal, boa tarde!

Alguém poderia dar uma idéia de como calcular o CRC16?

Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github.

Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação.

https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

cryptographix avatar Nov 23 '20 17:11 cryptographix

@jeansentose depois se quiser, pode copie e cola a string que gerou aqui neste site para validação.

cryptographix avatar Nov 23 '20 17:11 cryptographix

@jeansentose depois se quiser, pode copie e cola a string que gerou aqui neste site para validação.

Valeu, meu amigo !! Agradeço o apoio !!

jeansentose avatar Nov 23 '20 17:11 jeansentose

Pessoal, boa tarde! Alguém poderia dar uma idéia de como calcular o CRC16? Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github.

Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação.

https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

@SeanWykes Só uma dúvida... qual o campo que ele usa para validar? Digo, a posição que ele usa como base...

jeansentose avatar Nov 23 '20 17:11 jeansentose

Então, acabei de gerar um QR estático pelo site gerarpix.com.br, assim: 00020126330014BR.GOV.BCB.PIX01112178262481352040000530398654041.005802BR5902me6009somewhere62130509pagamento6304C3A7

Quebrando em tags (incluí espaços, indentação e quebras de linha para melhorar a leitura), tem: 0002 01 2633 .... 0014 BR.GOV.BCB.PIX .... 0111 21782624813 5204 0000 5303 986 5404 1.00 5802 BR 5902 me 6009 somewhere 6213 .... 0509 pagamento 6304 C3A7

Observe a última tag 63, de tamanho 04. O CRC deve ser calculado do início da string do QR até, e incluindo, o 6304.

Neste exemplo, calcula-se o CRC sobre 00020126330014BR.GOV.BCB.PIX01112178262481352040000530398654041.005802BR5902me6009somewhere62130509pagamento6304

No final, concatena o CRC, que tem 16 bits / 2 bytes, como 4 caracteres HEXA (com padding de "0" em cada byte).

A página que passei tem um botão para recalcular o CRC (mas é preciso que a estrutura de tags seja válida)

cryptographix avatar Nov 23 '20 17:11 cryptographix

Valeu meu querido !! Agradeço muito a ajuda !!

jeansentose avatar Nov 23 '20 17:11 jeansentose

Valeu meu querido !! Agradeço muito a ajuda !!

Você conseguiu gerar? se sim para qual linguagem? não estou conseguindo gerar em c# :/

alexandresanlim avatar Dec 08 '20 22:12 alexandresanlim

@alexandresanlim pode usar este site para validar a sua geração. A tela também gera QR estático e dinâmico, e pode regerar o CRC correto para um QR.

Em C# tem várias libs no github, como por exemplo https://github.com/juanroman-zz/emvqr

cryptographix avatar Dec 09 '20 18:12 cryptographix

@alexandresanlim pode usar este site para validar a sua geração. A tela também gera QR estático e dinâmico, e pode regerar o CRC correto para um QR.

Em C# tem várias libs no github, como por exemplo https://github.com/juanroman-zz/emvqr

Hoje pela manhã eu finalmente consegui tendo o seu código em TypeScript como base, o resultado esta aqui. Muito obrigado pela resposta!

alexandresanlim avatar Dec 09 '20 18:12 alexandresanlim

Pessoal, boa tarde! Alguém poderia dar uma idéia de como calcular o CRC16? Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github.

Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação.

https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

@jeansentose Eu utilizo PHP para gerar o QRCODE.

A funcao que utilizo é: function crc16($string) { $CRC16POLINOMIO = 0x1021; $result = 0xFFFF; if (($length = strlen($string)) > 0) { for ($offset = 0; $offset < $length; $offset++) { $result ^= (ord($string[$offset]) << 8); for ($bitwise = 0; $bitwise < 8; $bitwise++) { if (($result <<= 1) & 0x10000) $result ^= $CRC16POLINOMIO; $result &= 0xFFFF; } } } return $result; } $CRC16 = crc16($stringPix); //Nessa string deve conter o final "6304" $CRC16 = dechex($CRC16); //transformo de decimal para hexadecimal $CRC16 = strtoupper($CRC16); //Transformo para maiusculas

Estou trabalhando em um conversor online. O exemplo está no link https://showcommerce.com.br/pix

vitorgsoares avatar Dec 22 '20 19:12 vitorgsoares

Pessoal estou enroscado aqui com o CRC16 minha string esta tudo OK mas o calculo do CRC16 não bate de jeito nenhum, uso Delphi, baixei algumas função de calculo de CRC16 mas nada esta dando certo, alguém ai que trabalhe com Delphi e já tenha passado por esse problema, pra me fazer um Freelance aqui. obrigado meu contato WhatsApp (42) 9 8403-0313 - Sergio.

uso essas funções se sucesso: function Crc16(texto: string; Polynom: WORD = $1021; Seed: WORD = $FFFF): WORD; var i, j: Integer; begin Result := Seed; for i := 1 to length(texto) do begin Result := Result xor (ord(texto[i]) shl 8); for j := 0 to 7 do begin if (Result and $8000) <> 0 then Result := (Result shl 1) xor Polynom else Result := Result shl 1; end; end; Result := Result and $FFFF; end;

function Crc16(texto: string): WORD; const polynomial = $1021; var crc: WORD; i, j: Integer; b: Byte; bit, c15: Boolean; begin crc := $FFFF; for i := 1 to length(texto) do begin b := Byte(texto[i]); for j := 0 to 7 do begin bit := (((b shr (7 - j)) and 1) = 1); c15 := (((crc shr 15) and 1) = 1); crc := crc shl 1; if (c15 xor bit) then crc := crc xor polynomial; end; end; Result := crc and $FFFF; end;

ghost avatar Jan 18 '21 22:01 ghost

Fala ai blz, em delphi estou gerando desta forma.

function CRC16CCITT(texto: string): WORD; const polynomial = $1021; var crc: WORD; i, j: Integer; b: Byte; bit, c15: Boolean; begin crc := $FFFF; for i := 1 to length(texto) do begin b := Byte(texto[i]); for j := 0 to 7 do begin bit := (((b shr (7 - j)) and 1) = 1); c15 := (((crc shr 15) and 1) = 1); crc := crc shl 1; if (c15 xor bit) then crc := crc xor polynomial; end; end; Result := crc and $FFFF; end;

e chamo a função desta forma.

inttohex(CRC16CCITT(minhachave),4);

Testei em diversos bancos só o Itau que estou dependendo do gerente descobrir lá onde libera kkkk.

aslsoftware avatar Feb 22 '21 22:02 aslsoftware

Testei em diversos bancos só o Itau que estou dependendo do gerente descobrir lá onde libera kkkk.

https://github.com/renatofrota/pix-pendencias/issues/26

renatofrota avatar Feb 22 '21 22:02 renatofrota

Boa tarde Pessoal, estou tentando gerar meu calculo CRC16 através de uma função criada no SQL. Mas o calculo não está retornando da maneira esperada, conseguem dar uma força? Ou identificar algo que não estou conseguindo na minha função. Segue a fórmula abaixo: `` ALTER FUNCTION [dbo].[CRC16] ( @input varchar(max) ) RETURNS int WITH SCHEMABINDING AS BEGIN DECLARE @crc bigint = 0xffff , @result int ; SELECT @crc = dbo.CRC16calc(@crc, Ascii(Substring(@input, v.id, 1))) FROM dbo.IndexTable(1, LEN(@input)) AS v ORDER BY v.Id ; SET @result = UPPER(CONVERT(int, CONVERT(VARBINARY(4), ~@crc))) ; RETURN @result ; END

Abaixo estão as informações que estão sendo calculadas: 01 12 0014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b5 0000 986 1.00 BR SIRICOMERCIOESERVICOSLTDA SAOPAULO 0515DF06B1AAD182021 A2DA

GabrielPaixaoJustino avatar May 17 '21 15:05 GabrielPaixaoJustino

Abaixo estão as informações que estão sendo calculadas: 01 12 0014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b5 0000 986 1.00 BR SIRICOMERCIOESERVICOSLTDA SAOPAULO 0515DF06B1AAD182021 A2DA

Não sei se entendi exatamente o que você está tentando fazer. Você está tentando validar o CRC de um QR Code diretamente no SQL? Esses valores que você mencionou não são um BR Code completo. As informações estão sem os IDs dos "templates" EMV e seus tamanhos.

Por ex: o primeiro valor, 01, provavelmente deveria ser 000201 (template 00, tamanho 02, valor 01). Depois o valor 12, deveria ser 010212 (template 01, tamanho 02, valor 12). E assim por diante.

renatofrota avatar May 17 '21 16:05 renatofrota

Abaixo estão as informações que estão sendo calculadas: 01 12 0014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b5 0000 986 1.00 BR SIRICOMERCIOESERVICOSLTDA SAOPAULO 0515DF06B1AAD182021 A2DA

Não sei se entendi exatamente o que você está tentando fazer. Você está tentando validar o CRC de um QR Code diretamente no SQL? Esses valores que você mencionou não são um BR Code completo. As informações estão sem os IDs dos "templates" EMV e seus tamanhos.

Por ex: o primeiro valor, 01, provavelmente deveria ser 000201 (template 00, tamanho 02, valor 01). Depois o valor 12, deveria ser 010212 (template 01, tamanho 02, valor 12). E assim por diante.

Na verdade ele possui os tamanhos de forma correta, esse foi só um exemplo que passei das infos, segue abaixo minha string que está sendo gerada.

00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304461A

Seu jogar essa string no validador ele retorna a seguinte mensagem: ERROR - Invalid CRC, clicando em FIX CRC, ele passa...

GabrielPaixaoJustino avatar May 17 '21 16:05 GabrielPaixaoJustino

O CRC deve ser calculado em cima de:

00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304

que é "tudo menos o próprio CRC" (inclusive o 6304, que é o template ID 63, tamanho 04) e resulta em 8119 (diferente do seu resultado, 461A).

renatofrota avatar May 17 '21 16:05 renatofrota

qrCode.ods Se dá pra fazer em planilha, deve dar pra fazer em sql... :)

dmkamers avatar May 17 '21 16:05 dmkamers

O CRC deve ser calculado em cima de:

00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304

que é "tudo menos o próprio CRC" (inclusive o 6304, que é o template ID 63, tamanho 04) e resulta em 8119 (diferente do seu resultado, 461A).

Sim, já estou fazendo isso. Por isso que estou achando que existe algum problema na minha função, pois já estou contemplando a string exatamente dessa maneira, segue o trecho da minha função em SQL.

ALTER FUNCTION [dbo].[CRC16] ( @input varchar(max) ) RETURNS int WITH SCHEMABINDING AS BEGIN DECLARE @Crc bigint = 0xffff , @Result int ; SELECT @Crc = dbo.CRC16calc(@Crc, Ascii(Substring(@input, v.id, 1))) FROM dbo.IndexTable(1, LEN(@input)) AS v ORDER BY v.Id ; SET @Result = UPPER(CONVERT(int, CONVERT(VARBINARY(4), ~@Crc))) ; RETURN @Result ; END

GabrielPaixaoJustino avatar May 17 '21 17:05 GabrielPaixaoJustino

Acho que é porque você está fazendo UPPER() depois do cálculo CRC ser realizado (a alteração de caixa invalida o CRC).

renatofrota avatar May 17 '21 18:05 renatofrota

Acho que é porque você está fazendo UPPER() depois do cálculo CRC ser realizado (a alteração de caixa invalida o CRC).

Esse teste eu realizei depois Renato, mesmo sem o Upper não funciona...

GabrielPaixaoJustino avatar May 17 '21 18:05 GabrielPaixaoJustino

Eu não manjo tanto assim de SQL.

O input que tá sendo passado pra função que calcula o CRC é a string 00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304 ?

renatofrota avatar May 17 '21 18:05 renatofrota

Eu não manjo tanto assim de SQL.

O input que tá sendo passado pra função que calcula o CRC é a string 00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304 ?

Isso mesmo. De qualquer forma, obrigado pela força.

GabrielPaixaoJustino avatar May 17 '21 18:05 GabrielPaixaoJustino

É MySQL? Ou outro banco?

Achei essa resposta no SO que pode ser útil: https://stackoverflow.com/a/63901938/2847575

renatofrota avatar May 17 '21 18:05 renatofrota

E essa pra SQL Server: https://pt.stackoverflow.com/questions/485228/como-converter-uma-fun%C3%A7%C3%A3o-crc16-em-mysql-para-sql-server (a resposta é direcionada ao Pix, inclusive).

renatofrota avatar May 17 '21 18:05 renatofrota

Boa tarde a todos,

Segue solução que estou utilizando em PL/SQL:

CREATE OR REPLACE FUNCTION CRC16(V_STRING VARCHAR2) RETURN VARCHAR2 IS CURSOR C_BYTES (PIX_STRING VARCHAR2) IS SELECT TO_NUMBER(COLUMN_VALUE) AS BYTES FROM XMLTABLE( SUBSTR( DUMP(PIX_STRING), INSTR( DUMP(PIX_STRING), ':' )+1 ) );

C NUMBER; J NUMBER;

V_ANSWER VARCHAR2(4000) := 'FFFF'; V_POLINOMIO VARCHAR2(4) := '1021';

V_VERIFY NUMBER;

V_ID_CRC16 CHAR(2) := '63'; V_QTD_CRC16 CHAR(2) := '04'; BEGIN FOR R_BYTES IN C_BYTES(V_STRING||V_ID_CRC16||V_QTD_CRC16) LOOP C := R_BYTES.BYTES;

  IF (C_BYTES%ROWCOUNT = 1) THEN
    V_ANSWER := TO_NUMBER(V_ANSWER, 'XXXX');
  END IF;

  J := (C * POWER(2,8));
  V_ANSWER := (J + V_ANSWER) - BITAND(J, V_ANSWER) * 2;

  FOR BITWISE IN 0..7 LOOP
    V_ANSWER := V_ANSWER * POWER(2,1);
    V_VERIFY := BITAND(V_ANSWER, TO_NUMBER('10000', 'XXXXX'));

    IF (V_VERIFY <> 0) THEN
      V_ANSWER := (V_ANSWER + TO_NUMBER(V_POLINOMIO, 'XXXX')) - BITAND(V_ANSWER, TO_NUMBER(V_POLINOMIO, 'XXXX')) * 2;
    END IF;

    V_ANSWER := BITAND(V_ANSWER,  TO_NUMBER('FFFF', 'XXXX'));
  END LOOP;
END LOOP;

RETURN V_ID_CRC16||V_QTD_CRC16||TRIM(TO_CHAR(V_ANSWER, 'XXXX'));

END CRC16;

Estou utilizando Oracle Database 11g Release 11.2.0.4.0 - 64bit Production.

Att,

admsilva avatar May 21 '21 15:05 admsilva

Boa tarde a todos,

Segue solução que estou utilizando em PL/SQL:

CREATE OR REPLACE FUNCTION CRC16(V_STRING VARCHAR2) RETURN VARCHAR2 IS CURSOR C_BYTES (PIX_STRING VARCHAR2) IS SELECT TO_NUMBER(COLUMN_VALUE) AS BYTES FROM XMLTABLE( SUBSTR( DUMP(PIX_STRING), INSTR( DUMP(PIX_STRING), ':' )+1 ) );

C NUMBER; J NUMBER;

V_ANSWER VARCHAR2(4000) := 'FFFF'; V_POLINOMIO VARCHAR2(4) := '1021';

V_VERIFY NUMBER;

V_ID_CRC16 CHAR(2) := '63'; V_QTD_CRC16 CHAR(2) := '04'; BEGIN FOR R_BYTES IN C_BYTES(V_STRING||V_ID_CRC16||V_QTD_CRC16) LOOP C := R_BYTES.BYTES;

  IF (C_BYTES%ROWCOUNT = 1) THEN
    V_ANSWER := TO_NUMBER(V_ANSWER, 'XXXX');
  END IF;

  J := (C * POWER(2,8));
  V_ANSWER := (J + V_ANSWER) - BITAND(J, V_ANSWER) * 2;

  FOR BITWISE IN 0..7 LOOP
    V_ANSWER := V_ANSWER * POWER(2,1);
    V_VERIFY := BITAND(V_ANSWER, TO_NUMBER('10000', 'XXXXX'));

    IF (V_VERIFY <> 0) THEN
      V_ANSWER := (V_ANSWER + TO_NUMBER(V_POLINOMIO, 'XXXX')) - BITAND(V_ANSWER, TO_NUMBER(V_POLINOMIO, 'XXXX')) * 2;
    END IF;

    V_ANSWER := BITAND(V_ANSWER,  TO_NUMBER('FFFF', 'XXXX'));
  END LOOP;
END LOOP;

RETURN V_ID_CRC16||V_QTD_CRC16||TRIM(TO_CHAR(V_ANSWER, 'XXXX'));

END CRC16;

Estou utilizando Oracle Database 11g Release 11.2.0.4.0 - 64bit Production.

Att,

Boa tarde. Obrigado, vou verificar para converter em SQL.

GabrielPaixaoJustino avatar May 21 '21 17:05 GabrielPaixaoJustino