Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

nunopicado

Algoritmo de validação de NIF (PT)

Mensagens Recomendadas

nunopicado

Já aqui anda no fórum algo do género, mas creio que não em Delphi/Pascal.

Este é um algoritmo para validar um NIF (Nº de contribuinte) segundo as regras portuguesas.

É em Delphi, mas com pouco trabalho se pode adaptar a Pascal, ou mesmo a qualquer outra linguagem.

function ValidaNIF(NIF:String):Boolean;
var
  i:byte;
  Control:Integer;
begin
    // Testa o tamanho do NIF (Obrigatório 9 digitos)
    Result:=Length(NIF)=9;

    // Testa o NIF por tipo de caracteres (apenas númerico é aceite)
    try
       Control:=StrToInt(NIF);
    except
       Result:=False;
    end;

    // Testa se o digito inicial é válido (1, 2, 5, 6, 7, 8 ou 9)
    Result:=Result AND (Pos(NIF[1],'1256789')>0);

    // Calcula o CheckDigit do número e valida-o contra o último algarismo (algarismo de controle) pelo método Módulo 11
    if Result
       then begin
                 Control:=StrToInt(NIF[1])*9;
                 for i:=2 to 8 do
                     Control:=Control+(10-i)*StrToInt(NIF[i]);
                 Control:=11-(Control Mod 11);
                 if Control>=10 then Control:=0;
                 Result:=Control = StrToInt(NIF[9]);
            end;
end;

Editado por nunopicado
Adicionado o algarismo 7 como possível começo de um NIF

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

A parte de validar o tamanho e o serem números podia ser com a validação de Regular Expressions do próprio delphi

 if TRegEx.IsMatch(edit1.text, '^[0-9]\d{6}$') then
  //É valido
 else
//Não é

Editado por Rui Carlos
GeSHi
  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
nunopicado

:) Nunca usei tal. Tenho de olhar bem para isso. Regular Expressions ainda é mundo novo para mim! :(

Mas sem duvida, fica melhor!

Editado por Rui Carlos

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

Usas muito o if Result. Não gosto de ver.

begin
Result := false;

// testa condição... se não dá:
exit;

// mais testes...

// se tudo deu certo, mudas o valor no fim:
Result := true;
end;

    // Testa o NIF por tipo de caracteres (apenas númerico é aceite)
    try
       Control:=StrToInt(NIF);
    except
       Result:=False;
    end;

Se se puder evitar o Try, evita-se. Neste caso, nem é preciso criar mais variáveis do que aquelas que já tens:

Val(NIF, Control, i);
if boolean(i) then exit;


Knowledge is free! | Occasional Fortnite player

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado

Só há um pormenor que está a falhar - também podem começar por 7 (aprendi isso da pior maneira no mês passado).


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
nunopicado

:) Eu gosto do Try... Nada contra algo que me dá controle sobre o que estou a fazer.

A ideia dos IF's todos é mostrar os varios passos da validação. Tirando o checkdigit, podia ficar tudo numa condição só, mas quis simplificar ao máximo a percepção dos passos da validação!

Só há um pormenor que está a falhar - também podem começar por 7 (aprendi isso da pior maneira no mês passado).

Por 7?? Olha, essa desconhecia!

Sabes em que situações pode acontecer?


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado
Por 7?? Olha, essa desconhecia!

Sabes em que situações pode acontecer?

Acho que são NIF usados para processos de partilhas, é do conjunto dos herdeiros.


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
nunopicado

Coisa esquisita, nunca ouvi falar! Mas pronto, se for o caso é só adicionar lá em cima! :)


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
nunopicado

heheheh Como te compreendo...

Aqui está o link para a portaria que estabelece essa regra: http://www.igf.min-financas.pt/inflegal/bd_igf/bd_legis_geral/leg_geral_docs/PORTARIA_0386_98.htm

  • Voto 1

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
padrinho

Boas!!

Tenho um cliente a queixar-se de que inseriu um nif errado e o programa nao se queixou :S

O algoritmo basicamente é este:

Validar tamanho (9 digitos)

O primeiro dígito tem que ser 1, 2, 5, 6, 7, 8 ou 9

A soma de controle é dada por 9xd1 + 8xd2 + 7xd3 + 6xd4 + 5xd5 + 4xd6 + 3xd7 + 2xd8 + d9

Faz-se divisão por 11

Se o resto for inferior a 2, o check digit é 0

Caso contrario é 11 menos o resto

Se o valor for igual ao ultimo do NIF, então é valido, senão não

Estou a falhar nalguma coisa??

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
fcarvalho4
// class para validar Numero de Contribuinte
unit UValidaN;

interface

uses sysutils, classes;

type
// CalssObj Pascal Para validação de, NIF, BI, NISS
// fcarvalho98@gmail.com

TValidaNumeros=class
 protected
  FNumero : string;
  function Get_isValidoNIF:boolean;
  function Get_isValidoNISS:boolean;
  function Get_isValidoBI:boolean;
 public
  constructor create;
  property Numero:string read FNumero write FNumero;
  property isValidoNIF: boolean read Get_isValidoNIF;
  property isValidoNISS: boolean read Get_isValidoNISS;
  property isValidoBI: boolean read Get_isValidoBI;
  function IsNumero(s: string): Boolean;
end;

implementation

function TValidaNumeros.IsNumero(s: string): Boolean;
var
 i: Integer;
begin
 Result := False;
 for i := 1 to Length(s) do
case s[i] of '0'..'9':;
 else Exit;
end;
 Result := True;
end;

// Função para validar Nº idenf. Fiscal
function TValidaNumeros.Get_isValidoNIF:boolean;
var
 checkdigito, i : integer;
begin
 result := false;
 if (length(FNumero) = 9) and (isNumero(FNumero)) then
  begin
if (FNumero[1] in ['1','2','5','6','8','9'])  then
 begin
	 checkdigito := strtoint(FNumero[1]) * 9;
	for i := 3 to 9 do
	 checkdigito := checkdigito + (strtoint(FNumero[i-1])  * (11 - i));
	 checkdigito := 11 - (checkDigito mod 11);
	if (checkDigito >= 10) then checkDigito := 0;
	if (checkDigito = strtoint(FNumero[9])) then result := True;
  end;
end
  else
result := false;
end;

// Função para validar Nº idenf. Seg social
function TValidaNumeros.Get_isValidoNISS:boolean;
const
factor : array[1..10] of byte = (29,23,19,17,13,11,7,5,3,2);
var
soma, i : integer;
begin
 result := false;
 soma := 0;
 if (length(FNumero) = 11) and (isNumero(FNumero)) then
  begin
if (FNumero[1] in ['1','2'] ) then
 begin
	for i := 1 to 10 do
	 soma  := soma + ((strtoint(FNumero[i])  * factor[i]));
	 If (strtoint(FNumero[11]) = (9 - (soma mod 10))) then result := True;
  end;
end
  else
result := false;
end;

// Valida
constructor TValidaNumeros.create;
begin
FNumero := '123456789';
end;

function TValidaNumeros.Get_isValidoBI:boolean;
var
 soma : integer;
 TamanhoBI, i, cont : byte;
begin
 soma := 0;
 result := false;
 TamanhoBI := length(FNumero);
 if ((tamanhoBI > 6) and (TamanhoBI < 11)) and (isNumero(FNumero)) then
  begin
	cont := 0;
	for i := TamanhoBI downto 1 do
	 begin
	  inc(cont);
	  soma  := soma + ((strtoint(FNumero[i])  * cont));
	 end;
	 if ((Soma mod 11 = 0) or (soma mod 11 = 10)) then result := True;
end
  else
result := false;
end;


end.

Editado por nunopicado
Adicionadas tags GeShi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
satanuke

Boas!!

Tenho um cliente a queixar-se de que inseriu um nif errado e o programa nao se queixou :S

O algoritmo basicamente é este:

Validar tamanho (9 digitos)

O primeiro dígito tem que ser 1, 2, 5, 6, 7, 8 ou 9

A soma de controle é dada por 9xd1 + 8xd2 + 7xd3 + 6xd4 + 5xd5 + 4xd6 + 3xd7 + 2xd8 + d9

Faz-se divisão por 11

Se o resto for inferior a 2, o check digit é 0

Caso contrario é 11 menos o resto

Se o valor for igual ao ultimo do NIF, então é valido, senão não

Estou a falhar nalguma coisa??

Esse algoritmo tem uma falha.

Na soma de controlo não se adiciona o digito 9 pois este é apenas o check digit.

Fiz uma implementação desse algoritmo em Java e cometi o mesmo erro.

O algoritmo correcto será :

Validar tamanho (9 digitos)

O primeiro dígito tem que ser 1, 2, 5, 6, 7, 8 ou 9

A soma de controle é dada por 9xd1 + 8xd2 + 7xd3 + 6xd4 + 5xd5 + 4xd6 + 3xd7 + 2xd8

Faz-se divisão por 11

Se o resto for inferior a 2, o check digit é 0

Caso contrario é 11 menos o resto

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Icepick.pt

Aqui fica o código para validação com Javascript


function validaContribuinte(contribuinte){
// algoritmo de validação do NIF de acordo com
// http://pt.wikipedia.org/wiki/N%C3%BAmero_de_identifica%C3%A7%C3%A3o_fiscal

var temErro=0;

if (
contribuinte.substr(0,1) != '1' && // pessoa singular
contribuinte.substr(0,1) != '2' && // pessoa singular
contribuinte.substr(0,1) != '3' && // pessoa singular
contribuinte.substr(0,2) != '45' && // pessoa singular não residente
contribuinte.substr(0,1) != '5' && // pessoa colectiva
contribuinte.substr(0,1) != '6' && // administração pública
contribuinte.substr(0,2) != '70' && // herança indivisa
contribuinte.substr(0,2) != '71' && // pessoa colectiva não residente
contribuinte.substr(0,2) != '72' && // fundos de investimento
contribuinte.substr(0,2) != '77' && // atribuição oficiosa
contribuinte.substr(0,2) != '79' && // regime excepcional
contribuinte.substr(0,1) != '8' && // empresário em nome individual (extinto)
contribuinte.substr(0,2) != '90' && // condominios e sociedades irregulares
contribuinte.substr(0,2) != '91' && // condominios e sociedades irregulares
contribuinte.substr(0,2) != '98' && // não residentes
contribuinte.substr(0,2) != '99' // sociedades civis

) { temErro=1;}
var check1 = contribuinte.substr(0,1)*9;
var check2 = contribuinte.substr(1,1)*8;
var check3 = contribuinte.substr(2,1)*7;
var check4 = contribuinte.substr(3,1)*6;
var check5 = contribuinte.substr(4,1)*5;
var check6 = contribuinte.substr(5,1)*4;
var check7 = contribuinte.substr(6,1)*3;
var check8 = contribuinte.substr(7,1)*2;

var total= check1 + check2 + check3 + check4 + check5 + check6 + check7 + check8;
var divisao= total / 11;
var modulo11=total - parseInt(divisao)*11;
if ( modulo11==1 || modulo11==0){ comparador=0; } // excepção
else { comparador= 11-modulo11;}


var ultimoDigito=contribuinte.substr(8,1)*1;
if ( ultimoDigito != comparador ){ temErro=1;}

if (temErro==1){ alert('O numero de contribuinte parece estar errado' ); }

}

  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.