Algoritmos – Validação de Título de Eleitor

Introdução

Continuando a série de algoritmos de validação, vamos ver como validar um número de título de eleitor brasileiro, com 12 ou 13 dígitos, e que informações eles contém.

Formato

O Título de eleitor brasileiro é formado normalmente pelos primeiros 8 dígitos de dados, podendo chegar a 9 dígitos em alguns estados, seguido por dois dígitos que indicam o estado que o título foi emitido — numerados de 01 a 27 — e inclusive título emitido no exterior (28), seguido por dois dígitos verificadores, totalizando 12 a 13 dígitos.

Geração / Validação do Dígito Verificador

A regra do dígito verificador do Título Eleitoral usa módulo 11 para os primeiro 8 a 9 dígitos de dados, com uma regra especial diferenciada para um módulo 11 com resto zero para os estados de São Paulo e Minas Gerais, onde ao invés de ser 0, o dígito neste caso torna-se 1.

Já o segundo dígito verificador também é calculado com módulo 11, porém considerando apenas os dois dígitos do estado — correspondente ao penúltimo par de dígitos do Título — considerando também o primeiro dígito verificador.

Programa em AdvPL

Segue a rotina junto com uma demonstração de uso:

#include 'protheus.ch'

/* ==================================================================

Formato do Título Eleitoral
NNNNNNNN UF DD 

<N...> 8 ( ou 9 ) dígitos = número do titulo 
UF = 2 dígitos = estado de emissão
DD = 2 dígitos verificadores 

Estados emissores do titulo 

SP = 01		MG = 02		RJ = 03    RS = 04
BA = 05		PR = 06		CE = 07    PE = 08
SC = 09    	GO = 10		MA = 11    PB = 12
PA = 13    	ES = 14		PI = 15    RN = 16
AL = 17    	MT = 18		MS = 19    DF = 20
SE = 21    	AM = 22		RO = 23    AC = 24
AP = 25    	RR = 26		TO = 27    ZZ = 28 ( EXTERIOR ) 

==================================================================== */

User Function TSTTItulo()
Local cTitulo
Local cDV := ''
Local cUF := ''

cTitulo := '2178862601'  

cDV := DV_TITELE(cTitulo,@cUF)

conout("Titulo ... " + cTitulo )
conout("DV ....... " + cDV )
conout("Estado ... " + cUf )

Return

// Estados de emissao do titulo 
STATIC aUFTit := {"SP","MG","RJ","RS","BA","PR","CE","PE","SC","GO","MA","PB","PA","ES" ,;
                  "PI","RN","AL","MT","MS","DF","SE","AM","RO","AC","AP","RR","TO","ZZ"}

// -------------------------------------------------------------------
// Calcula dígito verificador de Titulo Eleitoral de 12 ou 13 dígitos
// Recebe Sequencia de 10 ou 11 dígitos em string, sem separadores ou pontuação
// Retorna os dois últimos dígitos do Titulo de Eleitor 

STATIC Function DV_TITELE(cTit,cUf)
Local nI , nVL
Local nDV1 := 0 , nDV2 := 0  
Local nM1 := 9
Local nUf

If len(cTit) < 10 .or. len(cTit)>11
	conout("Tamanho inválido.")
	Return "" 
Endif

nUf := val( substr(cTit,len(cTit)-1,2) )

If nUf < 1 .or. nUf > 28
	conout("Estado de emissão inválido -- verifique o número informado.")
	Return "" 
Endif

// Alimenta o estado por referencia
cUf := aUFTit[nUF]
      
// Começa a calcular pulando os 2 últimos dígitos ( UF ) 
// Podem haver 8 ou 9 dígitos de dados. O fator multiplicador
// começa em 9, se ficar menor que 2 ( 9 dígitos ), ele 
// volta a ser 9 -- calculo da direita para a esquerda
For nI := len(cTit)-2 to 1 step -1 
	nVL := val( substr(cTit,nI,1) )
	nDV1 += (  nVL * nM1 )
	nM1--
	If nM1<2
		nM1 := 9
	Endif
Next

// Primeiro Digito Verificador - Módulo 11
nDV1 := nDV1 % 11

IF nDV1 == 0
	If nUf = 01 .or. nUf = 02
		// Regra especial para São Paulo e Minas Gerais
		// Se o resto da divisão for zero, o digito 
		// verificador é 1
		nDV1 := 1 
	Endif
ElseIf nDV1 > 9 
	// Regra geral. Resto maior que 9, dígito zero 
	nDV1 := 0 
Endif

// Segundo digito verificador, considera os
// dois ultimos valores -- correspondente ao estado 
// de emissao , mais o primeiro digito 
nDV2 += ( val( substr(cTit,len(cTit)-1,1) ) * 7 )
nDV2 += ( val( substr(cTit,len(cTit),1) ) * 8 )
nDV2 += (nDV1 * 9)

// Segundo Digito Verificador - Módulo 11
nDV2 := nDV2 % 11

IF nDV2 == 0
	If nUf = 01 .or. nUf = 02
		// Regra especial para Sao Paulo e Minas Gerais
		// Se o resto da divisão for zero, o digito 
		// verificador é 1
		nDV2 := 1 
	Endif
ElseIf nDV2 > 9 
	// Regra geral. Resto maior que 9, dígito zero 
	nDV2 := 0 
Endif

// Retorna os dígitos verificadores 
Return chr(48+nDV1) + chr(48+nDV2)

Conclusão

Em nenhum lugar eu encontrei a documentação ou referência adequada para fazer o cálculo do dígito verificador com títulos de 13 dígitos (9 dígitos no número). Esse deu um pouco de trabalho para descobrir. Mas o desafio foi deveras interessante 😉

Espero que vocês tirem proveito destas funções quando elas se fizerem necessárias. Desejo a todos TERABYTES de SUCESSO !!! 

Referências

 

 

 

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s