[firebase-br] Uma contribuição para os colegas: uma nova versão de rotina de validação de CPF e CNPJ

Francisco Carlos da Rocha Gomes fcarlos em cpafac.embrapa.br
Seg Fev 8 13:04:45 -03 2010


Colegas,

A lista de Firebird tem me ajudado tanto e acho que é importante eu 
contribuir também com os colegas.

Eu estava procurando uma boa rotina de validação de CPF e CNPJ e 
encontrei apenas a dica no site do Firebase que me serviu de base para 
fazer uma rotina mais simples e "robusta" (que aceita qualquer coisa na 
entrada), que encaminho abaixo para os colegas.

Cordial abraço,

Francisco Carlos
Embrapa Acre

-------------------------------------------------------
 
DECLARE EXTERNAL FUNCTION RTRIM
    CSTRING(80)
RETURNS CSTRING(80) FREE_IT
ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf';
 
-------------------------------------------------------
 
DECLARE EXTERNAL FUNCTION STRLEN
    CSTRING(32767)
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';
 
-------------------------------------------------------
 
DECLARE EXTERNAL FUNCTION SUBSTRLEN
   CSTRING(255), SMALLINT, SMALLINT
   RETURNS CSTRING(255) FREE_IT
   ENTRY_POINT 'IB_UDF_substrlen' MODULE_NAME 'ib_udf';
 
-------------------------------------------------------
 
DECLARE EXTERNAL FUNCTION MOD
    INTEGER, INTEGER
    RETURNS DOUBLE PRECISION BY VALUE
    ENTRY_POINT 'IB_UDF_mod' MODULE_NAME 'ib_udf';
 
-------------------------------------------------------
 
SET TERM ^ ;
CREATE PROCEDURE PEGANUMSTR (
    str varchar(20))
returns (
    numstr varchar(20),
    tamstr_completo integer,
    tamstr_num integer)
as
declare variable j integer;
declare variable c char(1);
begin
  tamstr_completo = strlen(str);
  if ((str is null) or (str = '') or (tamstr_completo = 0)) then
  begin
    numstr = null;
  end
  else
  begin
    numstr = '';
    tamstr_num = 0;
    j = 1;
    while (J <= tamstr_completo)do
    begin
      c = substrlen(str, j, 1);
      if    ((c = '0') or (c = '1') or (c = '2') or (c = '3') or (c = '4')
          or (c = '5') or (c = '6') or (c = '7') or (c = '8') or (c = 
'9')) then
      begin
        numstr = numstr || c;
        tamstr_num = tamstr_num + 1;
      end
      j = j + 1;
    end
    if (numstr = '') then
      numstr = null;
    suspend;
  end
end ^
 
SET TERM ; ^
 
-------------------------------------------------------
 
SET TERM ^ ;
CREATE PROCEDURE CPFCNPJ_OK (
    pcpfcnpj varchar(20))
returns (
    cpfcnpj_ok char(1),
    cpfcnpj_info varchar(20),
    cpfcnpj_calc varchar(20))
as
declare variable i integer;
declare variable posic integer;
declare variable peso integer;
declare variable soma integer;
declare variable digver integer;
declare variable limite integer;
declare variable ehcpf char(1);
begin
  cpfcnpj_ok = null;
  if (pcpfcnpj is not null) then
  begin
    ehcpf = null;
 
    select numstr, tamstr_num
    from peganumstr(:pcpfcnpj)
    into :cpfcnpj_info, :i;
 
    if (i = 11) then
    begin
      ehcpf = 's';
      limite = 10;
    end
    else
    if (i = 14) then
    begin
      ehcpf = 'n';
      limite = 9;
    end
 
    if (ehcpf is not null) then
    begin
      cpfcnpj_calc = substrlen(cpfcnpj_info, 1, i-2);
      i = 0;
      while (i <= 1) do
      begin
        i = i + 1;
        soma = 0;
        peso = 1;
        posic = strlen(cpfcnpj_calc);
        while (posic >= 1) do
        begin
          peso = peso + 1;
          if (peso > limite) then
            peso = 2;
          soma = soma + cast(substrlen(cpfcnpj_calc, posic, 1) as 
integer) * peso;
          posic = posic - 1;
        end
        digver = mod(soma, 11);
        if ((digver <> 0) and (digver <> 1)) then
          digver = 11 - digver;
        else
          digver = 0;
        cpfcnpj_calc = cpfcnpj_calc || digver;
        if (ehcpf = 's') then
          limite = limite + 1;
      end
    end
  end
  if (cpfcnpj_calc = cpfcnpj_info) then
    cpfcnpj_ok = 's';
  else
    cpfcnpj_ok = 'n';
  suspend;
end ^
 
SET TERM ; ^






Mais detalhes sobre a lista de discussão lista