Jump to content
nunopicado

Algoritmo de validação de NIF (PT)

Recommended Posts

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;

Edited by 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.

Share this post


Link to post
Share on other 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 é

Edited by Rui Carlos
GeSHi
  • Vote 1

Share this post


Link to post
Share on other sites
nunopicado

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

Mas sem duvida, fica melhor!

Edited by 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.

Share this post


Link to post
Share on other 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!

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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

  • Vote 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.

Share this post


Link to post
Share on other 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??

Share this post


Link to post
Share on other 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.

Edited by nunopicado
Adicionadas tags GeShi

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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' ); }

}

  • Vote 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.