Precisava de uma rotina para validar CPF e CNPJ em Oracle PL/SQL.
Todas as dicas que encontrei mostram rotinas separadas.
Só encontrei uma, em Java, que utiliza o mesmo código para validar os dois identificadores.
Esse código faz parte do pacote BrazilUtils que, além de ter uma rotina única para validar os dois,
também apresenta rotinas separadas para cada um deles.
Pois bem, antes de exibir o código da função, lembremos como funciona a validação dos identificadores.
De acordo com o site da Receita Federal do Brasil o Cadastro de Pessoas Físicas - CPF é um banco de dados gerenciado pela Secretaria da Receita do Brasil - RFB que armazena informações cadastrais de contribuintes obrigados à inscrição no CPF, ou de cidadãos que se inscreveram voluntariamente.
Já a WikiPedia trás algumas informações interessantes como o significado dos dígitos e o algoritmo de validação (em Pascal).
O CNPJ é o cadastro administrado pela Receita Federal do Brasil que registra as informações cadastrais das pessoas jurídicas e de algumas entidades não caracterizadas como tais.
Os dois últimos dígitos do CPF são números de verificação: seguem um algoritmo de módulo 11,
baseado no valor dos outros dígitos, para possibilitar a verificação automática e prevenir erros de digitação.
O dígito anterior (isto é, o terceiro dígito da direita para a esquerda) revela a unidade federativa em que a pessoa
registrou-se pela primeira vez, dado que é proibido (em condições normais) trocar de número.
Vamos tomar como exemplo o número 123.456.789-09
• 1º Dígito Verificador
Primeiro calculamos a soma da multiplicação dos 9 primeiros dígitos por 10, 9, 8, ... , 3, 2, respectivamente. Ou seja:
Soma = (1*10) + (2*9) + ... + (8*3) + (9*2)
Em seguida, subtraimos 11 do resultado do módulo de 11 da soma.
Resultado = 11 - (Soma % 11)
Agora analisamos Resultado:
· Se Resultado for igual ou maior que 10, então o 1º dígito verificador é 0;
· Caso contrário, o 1º dígito verificador é o resultado.
• 2º Dígito Verificador
Primeiro calculamos a soma da multiplicação dos 9 primeiros dígitos por 11, 10, 9, ... , 4, 3, respectivamente e em seguida somamos com (Digito1*2), sendo que Digito1 é o valor encontrado para o 1º dígito verificador. Ou seja:
Soma = (1*11) + (2*10) + ... + (8*4) + (9*3) + (Digito1*2)
O resto é semelhante ao que foi feito anteriormente.
Resultado = 11 - (Soma % 11)
Agora analisamos Resultado:
· Se Resultado for igual ou maior que 10, então o 2º dígito verificador é 0;
· Caso contrário, o 2º dígito verificador é o resultado.
O código do BrasilUtils valida os dígitos informados conforme o tipo de identificador, CPF ou CNPJ, de acordo com
o tamanho do campo informado, em um único algoritmo. O CPF tem tamanho 11 e o CNPJ 14.
Esses valores são representam a quantidade de dígitos numéricos, já extraindo-se os caracteres para formatação
da máscara de exibição como “.”, “/” e “-‘.
A função pode receber como parâmetro o valor com os caracteres de máscara. Os mesmos serão removidos usando-se
expressão regular do SGBD.
Agora, vamos ao principal desse post, o código da função em PL/SQL.
CREATE OR REPLACE FUNCTION VALIDA_CPF_CNPJ(V_CPF_CNPJ VARCHAR2) RETURN BOOLEAN IS
/* Função para validar CPF/CNPJ
Banco de Dados: Oracle 10g
Data: 11/02/2008
Autor: Rogério Alcântara Valente
*/
TYPE ARRAY_DV IS VARRAY(2) OF PLS_INTEGER;
V_ARRAY_DV ARRAY_DV := ARRAY_DV(0, 0);
CPF_DIGIT CONSTANT PLS_INTEGER := 11;
CNPJ_DIGIT CONSTANT PLS_INTEGER := 14;
IS_CPF BOOLEAN;
IS_CNPJ BOOLEAN;
V_CPF_NUMBER VARCHAR2(20);
TOTAL NUMBER := 0;
COEFICIENTE NUMBER := 0;
DV1 NUMBER := 0;
DV2 NUMBER := 0;
DIGITO NUMBER := 0;
J INTEGER;
I INTEGER;
BEGIN
IF V_CPF_CNPJ IS NULL THEN
RETURN FALSE;
END IF;
/*
Retira os caracteres não numéricos do CPF/CNPJ
caso seja enviado para validação um valor com
a máscara.
*/
V_CPF_NUMBER := REGEXP_REPLACE(V_CPF_CNPJ, '[^0-9]');
/*
Verifica se o valor passado é um CPF através do
número de dígitos informados. CPF = 11
*/
IS_CPF := (LENGTH(V_CPF_NUMBER) = CPF_DIGIT);
/*
Verifica se o valor passado é um CNPJ através do
número de dígitos informados. CNPJ = 14
*/
IS_CNPJ := (LENGTH(V_CPF_NUMBER) = CNPJ_DIGIT);
IF (IS_CPF OR IS_CNPJ) THEN
TOTAL := 0;
ELSE
RETURN FALSE;
END IF;
Armazena os valores de dígitos informados para
posterior comparação com os dígitos verificadores calculados.
*/
DV1 := TO_NUMBER(SUBSTR(V_CPF_NUMBER, LENGTH(V_CPF_NUMBER) - 1, 1));
DV2 := TO_NUMBER(SUBSTR(V_CPF_NUMBER, LENGTH(V_CPF_NUMBER), 1));
V_ARRAY_DV(1) := 0;
V_ARRAY_DV(2) := 0;
/*
Laço para cálculo dos dígitos verificadores.
É utilizado módulo 11 conforme norma da Receita Federal.
*/
FOR J IN 1 .. 2
LOOP
TOTAL := 0;
COEFICIENTE := 2;
FOR I IN REVERSE 1 .. ((LENGTH(V_CPF_NUMBER) - 3) + J)
LOOP
DIGITO := TO_NUMBER(SUBSTR(V_CPF_NUMBER, I, 1));
TOTAL := TOTAL + (DIGITO * COEFICIENTE);
COEFICIENTE := COEFICIENTE + 1;
IF (COEFICIENTE > 9) AND IS_CNPJ THEN
COEFICIENTE := 2;
END IF;
END LOOP; --for i
V_ARRAY_DV(J) := 11 - MOD(TOTAL, 11);
IF (V_ARRAY_DV(J) >= 10) THEN
V_ARRAY_DV(J) := 0;
END IF;
END LOOP; --for j in 1..2
/*
Compara os dígitos calculados com os informados para informar resultado.
*/
RETURN(DV1 = V_ARRAY_DV(1)) AND(DV2 = V_ARRAY_DV(2));
END VALIDA_CPF_CNPJ;
Nenhum comentário:
Postar um comentário