AltaVista
Google

39.3. Validação de dígito verificador usando PL/Ruby

Os exemplos desta seção têm por finalidade mostrar a utilização de funções escritas na linguagem PL/Ruby para validar dígito verificador.

39.3.1. Funções PL/Ruby para validar o número do CPF e do CNPJ

Nestes exemplos são mostradas funções para validar o número do CPF e do CNPJ. A primeira função recebe o número do CPF com 8 a 11 dígitos, e a segunda recebe o número do CNPJ com 14 dígitos. Ambas retornam o valor booleano verdade se os dígitos verificadores estiverem corretos, ou falso caso contrário. Se o argumento for nulo, não tiver o número de dígitos esperado, ou contiver um dígito não numérico, as funções retornam nulo.

Exemplo 39-8. Função PL/Ruby para validar o número do CPF

Rotina para validação do CPF. Recebe um argumento, o número do CPF com oito a onze dígitos. Retorna verdade se os dígitos verificadores do CPF estiverem corretos, falso caso contrário, ou nulo se o argumento for nulo, não tiver entre 8 e 11 dígitos, ou contiver um dígito não numérico. Não serão considerados válidos os seguintes CPF: 000.000.000-00, 111.111.111-11, 222.222.222-22, 333.333.333-33, 444.444.444-44, 555.555.555-55, 666.666.666-66, 777.777.777-77, 888.888.888-88, 999.999.999-99.

CREATE OR REPLACE FUNCTION ruby_cpf (text) RETURNS boolean AS $$
# verificar se o argumento é nulo (desnecessário porque a função é STRICT)
if args[0] == nil
   return nil
end
# número do CPF igual ao argumento recebido
cpf = args[0]
# verificar se o CPF tem entre 8 e 11 dígitos
if cpf.length < 8 ||  cpf.length > 11
   return nil
end
# colocar zeros à esquerda se tiver menos de 11 dígitos
if cpf.length < 11
   cpf = ("0"*(11-cpf.length)).concat(cpf)
end
# verificar se os dígitos são todos numéricos
(0...cpf.length).each do|i|
   c = cpf[i];
   if (c<?0 || c>?9)
      return nil
   end
end
# verificar se os dígitos são todos iguais
iguais = true
(0..cpf.length-2).each do|i|
   if cpf[i] != cpf[i+1]
      iguais = false
      break
   end
end
if iguais
   return false
end
# primeiro dígito verificador
fator=10
digito=0
(0..cpf.length-3).each do|i|
    digito += (cpf[i]-?0) * fator
    fator -= 1;
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
if digito != (cpf[9]-?0)
   return false;
end
# segundo dígito verificador
fator=11
digito=0
(0..cpf.length-2).each do|i|
    digito += (cpf[i]-?0) * fator
    fator -= 1;
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
if digito != (cpf[10]-?0)
   return false
end
return true
$$ LANGUAGE 'plruby' IMMUTABLE STRICT;

Os números de CPF utilizados para testar a função não estão divulgados por motivo de confidencialidade.

Exemplo 39-9. Função PL/Ruby para validar o número do CNPJ

Rotina para validação do CNPJ. Recebe um argumento, o número do CNPJ com doze a quatorze dígitos. Retorna verdade se os dígitos verificadores do CNPJ estiverem corretos, falso caso contrário, ou nulo se o argumento for nulo, não tiver entre 12 e 14 dígitos, ou contiver um dígito não numérico.

CREATE OR REPLACE FUNCTION ruby_cnpj (text) RETURNS boolean AS $$
# verificar se o argumento é nulo (desnecessário porque a função é STRICT)
if args[0] == nil
   return nil
end
# número do CNPJ igual ao argumento recebido
cnpj = args[0]
# verificar se o CNPJ tem entre 12 e 14 dígitos
if cnpj.length < 12 ||  cnpj.length > 14
   return nil
end
# colocar zeros à esquerda se tiver menos de 14 dígitos
if cnpj.length < 14
   cnpj = ("0"*(14-cnpj.length)).concat(cnpj)
end
# verificar se os dígitos são todos numéricos
(0...cnpj.length).each do|i|
   c = cnpj[i];
   if (c<?0 || c>?9)
      return nil
   end
end
# primeiro dígito verificador
fator=13
digito=0
(0..cnpj.length-3).each do|i|
    digito += (cnpj[i]-?0) * (fator>9 ? fator-8 : fator)
    fator -= 1;
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
if digito != (cnpj[12]-?0)
   return false;
end
# segundo dígito verificador
fator=14
digito=0
(0..cnpj.length-2).each do|i|
    digito += (cnpj[i]-?0) * (fator>9 ? fator-8 : fator)
    fator -= 1;
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
if digito != (cnpj[13]-?0)
   return false
end
return true
$$ LANGUAGE 'plruby' IMMUTABLE STRICT;

Os testes da função foram feitos utilizando CNPJ de órgãos públicos.

plruby=# SELECT ruby_cnpj('42498634000166');

 ruby_cnpj
-----------
 t
(1 linha)

plruby=# SELECT ruby_cnpj('42498733000148');

 ruby_cnpj
-----------
 t
(1 linha)

39.3.2. Funções PL/Ruby para validar dígitos verificadores- FEBRABAN

Nesta seção são mostradas duas funções para validação do dígito verificador. A primeira função valida o dígito verificador módulo 11 e a segunda módulo 10. As duas funções recebem um parâmetro, o número com o dígito verificador no final, e retornam verdade ou falso caso o dígito esteja correto ou errado, respectivamente. Se o argumento for nulo, tiver menos de dois dígitos, ou contiver um dígito não numérico, as funções retornam nulo.

Exemplo 39-10. Função PL/Ruby para validar o dígito verificador módulo 11

O cálculo do dígito verificador módulo 11 é feito da seguinte forma: os dígitos são multiplicados da direita para a esquerda pela seqüência de 2 a 9, ou seja, por 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, e assim por diante; os resultados do produto dos dígitos pelos valores da seqüência são somados; a soma é dividida por 11, e o resto da divisão é obtido; o dígito verificador é calculado subtraindo o resto de 11; quando o resto for igual a 0 ou 1 o dígito verificador será igual a 0. Segundo o Manual Técnico Operacional - Bloquetos de Cobrança - FEBRABAN, deve ser utilizado o dígito 1 quando o resto for 0, 10 ou 1. Existem Secretarias de Fazenda onde no cálculo do dígito verificador a seqüência retorna a 2 antes de chegar a 9. Tome cuidado antes de utilizar esta função.

CREATE OR REPLACE FUNCTION ruby_dv11 (text) RETURNS boolean AS $$
# verificar se o argumento é nulo (desnecessário porque a função é STRICT)
if args[0] == nil
   return nil
end
# número a ser verificado igual ao argumento recebido
n = args[0]
# verificar se tem ao menos dois dígitos
if n.length < 2
   return nil
end
# verificar se os dígitos são todos numéricos
(0...n.length).each do|i|
   c = n[i];
   if (c<?0 || c>?9)
      return nil
   end
end
# validar o dígito verificador
digito = 0
fator  = 2
compr  = n.length
(0..compr-2).each do|i|
    digito += (n[compr-2-i]-?0) * fator
    fator += 1;
    if fator > 9
        fator = 2
    end
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
return digito == (n[compr-1]-?0)
$$ LANGUAGE 'plruby' IMMUTABLE STRICT;

Foram utilizados valores tirados do manual da FEBRABAN e de talões de cheques para testar a função.

plruby=# SELECT ruby_dv11('99991012000003500077721305301500818975000001');

 ruby_dv11
-----------
 t
(1 linha)

plruby=# SELECT ruby_dv11('29750');

 ruby_dv11
-----------
 t
(1 linha)

plruby=# SELECT ruby_dv11('27');

 ruby_dv11
-----------
 t
(1 linha)

Exemplo 39-11. Função PL/Ruby para validar o dígito verificador módulo 10

O cálculo do dígito verificador módulo 10 é feito da seguinte forma: os dígitos são multiplicados da direita para a esquerda pela seqüência 2, 1, 2, 1, e assim por diante; os "algarismos" dos resultados do produto dos dígitos pelos valores da seqüência são somados individualmente; a soma é dividida por 10, e o resto da divisão é obtido; o dígito verificador é calculado subtraindo o resto de 10; quando o resto for igual a 0 o dígito verificador será igual a 0. Fonte: Manual Técnico Operacional - Bloquetos de Cobrança - FEBRABAN. Existe outra forma de calcular este dígito verificador onde os resultados dos produtos, e não os dígitos dos resultados dos produtos, são somados. Tome cuidado antes de utilizar esta função.

CREATE OR REPLACE FUNCTION ruby_dv10 (text) RETURNS boolean AS $$
# verificar se o argumento é nulo (desnecessário porque a função é STRICT)
if args[0] == nil
   return nil
end
# número a ser verificado igual ao argumento recebido
n = args[0]
# verificar se tem ao menos dois dígitos
if n.length < 2
   return nil
end
# verificar se os dígitos são todos numéricos
(0...n.length).each do|i|
   c = n[i];
   if (c<?0 || c>?9)
      return nil
   end
end
# validar o dígito verificador
digito = 0
fator  = 2
compr  = n.length
(0..compr-2).each do|i|
    produto = (n[compr-2-i]-?0) * fator
    digito += produto/10 + produto%10;
    fator -= 1;
    if fator < 1
        fator = 2
    end
end
digito = 10 - ( digito % 10 )
if digito == 10
   digito = 0
end
return digito == (n[compr-1]-?0)
$$ LANGUAGE 'plruby' IMMUTABLE STRICT;

Foram utilizados valores tirados do manual da FEBRABAN e de talões de cheques para testar a função.

plruby=# SELECT ruby_dv10('00635041429');

 ruby_dv10
-----------
 t
(1 linha)

plruby=# SELECT ruby_dv10('9999777213');

 ruby_dv10
-----------
 t
(1 linha)

plruby=# SELECT ruby_dv10('75');

 ruby_dv10
-----------
 t
(1 linha)

39.3.3. Função PL/Ruby para validar o número de inscrição eleitoral

Neste exemplo é mostrada uma função para validar o número de inscrição eleitoral. A função recebe como parâmetro o número de inscrição eleitoral, e retorna o valor booleano verdade se os dígitos verificadores estiverem corretos, ou falso caso contrário. Se o argumento for nulo, tiver menos de dez dígitos, ou contiver um dígito não numérico, a função retorna nulo. A função não verifica se a unidade da federação é válida.

Exemplo 39-12. Função PL/Ruby para validar o número de inscrição eleitoral

A função é baseada na Resolução nº 20.132, de 19.03.98, do Tribunal Superior Eleitoral, art. 10, cujo texto é reproduzido abaixo:

Art. 10 - Os Tribunais Regionais Eleitorais farão distribuir, observada a seqüência numérica fornecida pela Secretaria de Informática, às Zonas Eleitorais da respectiva Circunscrição, séries de números de inscrição eleitoral, a serem utilizados na forma deste artigo.

Parágrafo único - O número de inscrição compor-se-á de até 12 (doze) algarismos, por Unidade da Federação, assim discriminados:

a) os 8 (oito) primeiros algarismos serão seqüenciados, desprezando-se, na emissão, os zeros à esquerda;

b) os 2 (dois) algarismos seguintes serão representativos da Unidade da Federação de origem da inscrição, conforme códigos constantes da seguinte tabela:

01 - São Paulo; 02 - Minas Gerais; 03 - Rio de Janeiro; 04 - Rio Grande do Sul; 05 - Bahia; 06 - Paraná; 07 - Ceará; 08 - Pernambuco; 09 - Santa Catarina; 10 - Goiás; 11 - Maranhão; 12 - Paraíba; 13 - Pará; 14 - Espírito Santo; 15 - Piauí; 16 - Rio Grande do Norte; 17 - Alagoas; 18 - Mato Grosso; 19 - Mato Grosso do Sul; 20 - Distrito Federal; 21 - Sergipe; 22 - Amazonas; 23 - Rondônia; 24 - Acre; 25 - Amapá; 26 - Roraima; 27 - Tocantins; 28 - Exterior (ZZ).

c) os 2 (dois) últimos algarismos constituirão dígitos verificadores, determinados com base no módulo 11 (onze), sendo o primeiro calculado sobre o número seqüencial e o último sobre o código da Unidade da Federação seguido do primeiro dígito verificador.

CREATE OR REPLACE FUNCTION ruby_nie (text) RETURNS boolean AS $$
# verificar se o argumento é nulo (desnecessário porque a função é STRICT)
if args[0] == nil
   return nil
end
# número a ser verificado igual ao argumento recebido
n = args[0]
# verificar se tem ao menos dez dígitos
if n.length < 10
   return nil
end
# verificar se os dígitos são todos numéricos
(0...n.length).each do|i|
   c = n[i];
   if (c<?0 || c>?9)
      return nil
   end
end
# validar o primeiro dígito verificador
digito = 0
fator  = 2
compr  = n.length
(0..compr-5).each do|i|
    digito += (n[compr-5-i]-?0) * fator
    fator += 1;
    if fator > 9
        fator = 2
    end
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
if digito != (n[compr-2]-?0)
    return false
end
# validar o segundo dígito verificador
digito = 0
fator  = 2
compr  = n.length
(2..4).each do|i|
    digito += (n[compr-i]-?0) * fator
    fator += 1;
    if fator > 9
        fator = 2
    end
end
digito = 11 - ( digito % 11 )
if digito >= 10
   digito = 0
end
return digito == (n[compr-1]-?0)
$$ LANGUAGE 'plruby' IMMUTABLE STRICT;

Não são mostrados os números utilizados para validar a função por uma questão de confidencialidade.

SourceForge.net Logo CSS válido!