- Tem que ter 9 dígitos
- O primeiro dígito tem que ser 1, 2, 5, 6, 8 ou 9
- A soma de controle dada por 9xd1+8xd2+7xd3+6xd4+5xd5+4xd6+3xd7+2xd8+d9 tem que ser múltipla de 11 (congruente com o módulo 11, isto é, dê resto 0 quando dividida por 11). d1 é o dígito mais à esquerda, e d9 o digito mais à direita (digito de controle).
- d9, em alguns casos, precisava de ter o valor 10, para que a soma de controle fosse divisível por 11. Neste caso d9 tomará o valor 0. Nitidamente uma decisão mal tomada, pois um dígito de controle igual a zero, poderá significar uma soma de controle correcta ou uma cujo resto da divisão por onze dá 1. O dígito de controle deveria ser, por exemplo, uma letra com os 11 possíveis valores de A a K. Por curiosidade, o mesmo erro, existe na validação dos BI.
Fica aqui source code exemplo em Flex:
<?xml version="1.0" encoding="utf-8"?>
<mx:canvas mx="http://www.adobe.com/2006/mxml" creationcomplete="_init()"
form="ui.form.*" jwolib="http://www.jwolib.com/2006/mxml">
<mx:script>
<![CDATA[
import mx.controls.Alert;
private function _init():void {
}
private function _validateNIF():void {
if ( tNIFToValidate.text.length < 9 ) {
Alert.show( 'O NIF deve conter 9 digitos!' );
return;
}
if ( _validateBegin( Number( tNIFToValidate.text.charAt( 0 ) ) ) ) {
var chkd:Number = _getCheckDigit( Number(
tNIFToValidate.text.substr( 0, 8 ) ) );
if ( chkd != Number( tNIFToValidate.text.charAt( 8 ) ) ) {
Alert.show( 'O Check-digit do NIF não é válido!' );
return;
}
} else {
Alert.show( 'O NIF não pode começar por 3,5 ou 7!' );
return;
}
Alert.show( 'NIF é válido!' );
}
private function _generateCheckDigit():void {
if ( tCode.text == '' || tCode.text.length < 8 ) {
Alert.show( 'Deve inserir o código totalmente para gerar o
Check-digit' );
return;
}
if ( ! _validateBegin( Number( tCode.text.charAt( 0 ) ) ) ) {
Alert.show( 'O NIF não pode começar por 3,5 ou 7!' );
return;
}
var chkd:Number = _getCheckDigit( Number( tCode.text ) );
tCheckDigit.text = String( chkd );
}
private function _validateBegin( startChar:Number ):Boolean {
if (startChar == 1 || startChar == 2 || startChar == 5 ||
startChar == 6 || startChar == 8 || startChar == 9) {
return true;
} else {
return false;
}
}
private function _getCheckDigit( code:Number ):Number {
var c:Number = Number( String( code ).charAt( 0 ) );
var checkDigit:Number = c * 9;
var i:Number = 0;
for( i = 2; i <= 8; i++ ){
checkDigit += Number( String( code ).charAt( i - 1 ) )
* ( 10 - i );
}
checkDigit = 11 - ( checkDigit % 11 );
if( checkDigit >= 10 ) checkDigit = 0;
return checkDigit;
}
private function _onChangeTCode():void {
if ( tCode.text.length == 8 ) {
_generateCheckDigit();
} else {
tCheckDigit.text = '';
}
}
]]>
</mx:Script>
<mx:vbox>
<jwolib:FieldSet title="Help" width="350"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:text text="Faz a validação de um NIF Português e gera o
check-digit." width="100%">
</jwolib:FieldSet>
<jwolib:FieldSet direction="vertical" title="Validador NIF" width="350"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:hbox>
<mx:label text="NIF" width="60">
<mx:textinput id="tNIFToValidate" restrict="[0-9]" maxchars="9"
width="85">
<mx:button label="Valida" click="_validateNIF()">
</mx:HBox>
<mx:hrule width="100%">
<mx:hbox>
<mx:label text="Gerador" width="60">
<mx:textinput id="tCode" restrict="[0-9]" width="75" maxchars="8"
change="_onChangeTCode()">
<mx:textinput id="tCheckDigit" editable="false" width="20"
maxchars="1">
<mx:button label="Gera Check-digit"
click="_generateCheckDigit()">
</mx:HBox>
</jwolib:FieldSet>
</mx:VBox>
</mx:Canvas>