Página 1 de 1
Validação de CNH
Enviado: 10 Ago 2007 01:46
por Maligno
CNH = Carteira Nacional de Habilitação.
Mas trata-se apenas da validação do número tipográfico. Não muito útil pra maioria. Mas,...
Código: Selecionar todos
//**********************************************************
function ValidCNHtg(cNro) // validação do número tipográfico
local d
if Val(cNro) = 0
return .F.
end
d := 11-Val(Left(cNro,8))%11
return if(d<=9,d,0) = Val(Right(cNro,1))
Re: Validação de CNH
Enviado: 27 Mai 2010 23:32
por lugab
Maligno, qual o significado de "número tipografico" e o que falta na função acima ?
Re: Validação de CNH
Enviado: 28 Mai 2010 01:09
por Maligno
Essa função não serve para validar o número da CNH. Era só pra validar o número tipográfico que é do formulário CNH. Não é útil, infelizmente.
Re: Validação de CNH
Enviado: 28 Mai 2010 07:34
por lugab
Achei essa contribuição, Maligno
http://delphiforall.blogspot.com/2008/0 ... e-cnh.html (código incorreto)
Eu uso clipper+xharbour, e Não tenho conhecimento suficiente pra adaptá-la pro meu uso, mas pode ser que vc tenha e ela te atenda.
Re: Validação de CNH
Enviado: 28 Mai 2010 09:16
por Maligno
Olhei por cima. Estou meio sem tempo. No final de semana vejo. Obrigado.
Validação de CNH
Enviado: 02 Jun 2010 14:10
por Pablo César
Bom eu não tenho conhecimento quase algum de Delphi, mas vendo a lógica foi fácil montar em xBase. Só que fiz para que aceitasse desde a linha de comando. Observem que tem duas funções de validação, uma com o código novo (até 9 dígitos e 2 verificadores) e para código antigo (8 dígitos e 1 verificador, o chamado de PGU - Prontuário Geral Único). Acho que a difrenciação pelo DETRAN é dado por: "Carteira com foto e sem foto".
Código: Selecionar todos
PARAMETERS xCnh
IF xCnh=NIL
? "Falta parƒmetro"
QUIT
ELSE
nCnh:=VAL(xCnh)
ENDIF
IF valida_new_cnh(nCnh) .or. valida_old_cnh(nCnh)
? "CNH OK"
ELSE
? "CNH INCORRETO"
ENDIF
function valida_new_cnh(nCnh)
Result := .F.
NumIguais := .T.
cCnh := strzero(nCnh,11,0)
Soma := 0
// Validando se todos o numeros sao iguais
for i := 2 to len(cCnh)-1
if !(substr(cCnh,1,1) = substr(cCnh,i,1))
NumIguais := .F.
endif
next
if NumIguais
RETURN Result
endif
for i := 1 to len(cCnh)-2
Soma := Soma + (val(substr(cCnh,i,1)) * (i + 1))
next
Conta := (Soma / 11) * 11
if (Soma - Conta) < 2
Dv := 0
else
Dv := 11 - (Soma - Conta)
endif
Digito := val(substr(cCnh,10,1))
if Digito = Dv
Result := .T.
endif
RETURN Result
function valida_old_cnh(nCnh)
Result := .F.
NumIguais := .T.
cCnh := strzero(nCnh,9,0)
Soma := 0
// Validando se todos o numeros sao iguais
for i := 2 to len(cCnh)-1
if !(substr(cCnh,1,1) = substr(cCnh,i,1))
NumIguais := .F.
endif
next
if NumIguais
RETURN Result
endif
for i := 1 to len(cCnh)-1
Soma := Soma + (val(substr(cCnh,i,1)) * (i + 1))
next
Digito := val(substr(cCnh,9,1))
Conta := mod(Soma,11)
if Conta = 10
Conta := 0
endif
if Digito = Conta
result := .T.
endif
RETURN result
Eu testei e funcionou, não tenho total certeza quanto ao
StrToInt(CnhN[10]) se está pegando o caracter da posição 10 ou apartir da posição 10 (seria os caracteres de posição 10 e 11). Cabe testar e mudar no caso. Talvez o Maligno consiga nos dizer algo...
Validação de CNH (Correta)
Enviado: 02 Jun 2010 14:21
por Pablo César
O código acima postado, não está totalmente correto. Veja os seguintes códigos (para CNHs e PGUs):
http://forum.devmedia.com.br/viewtopic. ... c&start=15
Inclusive aqui está o cdocumento que regulamenta o CNH:
http://www.denatran.gov.br/download/Res ... 192_06.doc
E a minha migração de Delphi para xBase vão ser estes exemplos:
Código: Selecionar todos
/*
Autor......: cps.art - Membro Pleno do http://forum.devmedia.com.br/
Comentários: Só as CNHs novas, com número de registro de 11 dígitos.
*/
FUNCTION VRegCnh(PVRegCnh : string) : string; stdcall;
var
j, Mult, Soma, Digito1, Digito2, Incr_dig2: integer;
CNH_Forn, Dig_Forn, Dig_Enc : string;
begin
Result := 'F';
if length(Trim(PVRegCnh)) < 11 then
Exit;
CNH_Forn := Copy(PVRegCnh,1,9);
Dig_Forn := Copy(PVRegCnh,10,2);
Incr_Dig2 := 0;
Soma := 0;
Mult := 9;
for j := 1 to 9 do
begin
Soma := Soma + (StrToInt(CNH_Forn[j]) * Mult);
Mult := Mult - 1;
end;
Digito1 := Soma Mod 11;
if Digito1 = 10 then
begin
Incr_Dig2 := -2;
end;
if Digito1 > 9 then
begin
Digito1 := 0;
end;
Soma := 0;
Mult := 1;
for j := 1 to 9 do
begin
Soma := Soma + (StrToInt(CNH_Forn[j]) * Mult);
Mult := Mult + 1;
end;
if (Soma Mod 11) + Incr_Dig2 < 0 then
begin
Digito2 := 11 + (Soma Mod 11) + Incr_Dig2;
end;
if (Soma Mod 11) + Incr_Dig2 >= 0 then
begin
Digito2 := (Soma Mod 11) + Incr_Dig2;
end;
if Digito2 > 9 then
begin
Digito2 := 0;
end;
Dig_Enc := IntToStr(Digito1)+IntToStr(Digito2);
if Dig_Forn = Dig_enc then
begin
Result := 'V';
end;
if Dig_Forn <> Dig_enc then
begin
Result := 'F';
end;
end;
Código: Selecionar todos
/*
Autor......: cps.art - Membro Pleno do http://forum.devmedia.com.br/
Comentários: função para checar números de CNHs antigas, os PGUs.
*/
FUNCTION VPguCnh(PVPguCnh : string) : string; stdcall;
var
j, Mult, Soma, Digito : integer;
PGU_Forn, Dig_Forn, Dig_Enc : string;
begin
Result := 'F';
if length(Trim(PVPguCnh)) <> 9 then
Exit;
PGU_Forn := Copy(PVPguCnh,1,8);
Dig_Forn := Copy(PVPguCnh,9,1);
Soma := 0;
Mult := 2;
for j := 1 to 8 do
begin
Soma := Soma + (StrToInt(PGU_Forn[j]) * Mult);
Mult := Mult + 1;
end;
Digito := Soma Mod 11;
if Digito > 9 then
begin
Digito := 0;
end;
Dig_Enc := IntToStr(Digito);
if Dig_Forn = Dig_enc then
begin
Result := 'V';
end;
if Dig_Forn <> Dig_enc then
begin
Result := 'F';
end;
end;
Validação de CNH (Correta e agora em xBase)
Enviado: 02 Jun 2010 16:27
por Pablo César
Acho que conseguí, com certeza ainda pode ser enxugado o código, mas acredito que está funcionando bem para CNHs e PGUs:
Código: Selecionar todos
PARAMETERS xCnh
IF xCnh=NIL
? "Falta parametro"
QUIT
ELSE
xCnh:=SO_NUMEROS(xCnh)
ENDIF
IF VER_PGU(xCnh) .or. VER_CNH(xCnh)
? "CNH OK"
ELSE
? "CNH INCORRETO"
ENDIF
FUNCTION VER_PGU(cPgu)
Result := .F.
if !(len(alltrim(cPgu)) = 9)
Return Result
endif
PGU_Forn := substr(cPgu,1,8)
Dig_Forn := substr(cPgu,9,1)
Soma := 0
Mult := 2
for j := 1 to 8
Soma := Soma + (val(substr(PGU_Forn,j,1)) * Mult)
Mult := Mult + 1
next
Digito := int(mod(Soma,11))
if Digito > 9
Digito := 0
endif
Dig_Enc := alltrim(Str(Digito))
if Dig_Forn = Dig_enc
Result := .T.
endif
if Dig_Forn <> Dig_enc
Result := .F.
endif
Return Result
FUNCTION VER_CNH(cCnh)
Result := .F.
if !(len(alltrim(cCnh))) = 11
Return Result
endif
CNH_Forn := substr(cCnh,1,9)
Dig_Forn := substr(cCnh,10,2)
Incr_Dig2 := 0
Soma := 0
Mult := 9
for j := 1 to 9
Soma := Soma + (val(substr(CNH_Forn,j,1)) * Mult)
Mult := Mult - 1
next
Digito1 := int(mod(Soma,11))
if Digito1 = 10
Incr_Dig2 := -2
endif
if Digito1 > 9
Digito1 := 0
endif
Soma := 0
Mult := 1
for j := 1 to 9
Soma := Soma + (val(substr(CNH_Forn,j,1)) * Mult)
Mult := Mult + 1
next
if int(mod(Soma,11)) + Incr_Dig2 < 0
Digito2 := 11 + int(mod(Soma,11)) + Incr_Dig2
endif
if int(mod(Soma,11)) + Incr_Dig2 >= 0
Digito2 := int(mod(Soma,11)) + Incr_Dig2
endif
if Digito2 > 9
Digito2 := 0
endif
Dig_Enc := alltrim(str(Digito1))+alltrim(str(Digito2))
if Dig_Forn = Dig_enc
Result := .T.
endif
if !(Dig_Forn = Dig_enc)
Result := .F.
endif
Return Result
FUNCTION SO_NUMEROS(xCnh)
cNums:=""
for u=1 to len(xCnh)
if isdigit(substr(xCnh,u,1))
cNums:=cNums+substr(xCnh,u,1)
endif
next
Return cNums
É bom conhecer outras linguagens de programação, o Delphi não deixa de ser Pascal (muito parecido a Clipper, tem bastante de C e algo de Java) o que me facilitou a comprensão. Bom espero que o código seja bastante útil, eu o único que fiz é adapta-lo.
Re: Validação de CNH
Enviado: 04 Jun 2010 16:09
por lugab
Pablo, eu to usando esse seu trabalho. Muito Obrigado pelo esforço da conversão.
A título de contribuição, eu detectei que a função está retornado como VÀLIDO, cnhs com as sequências: "1234567889" e "12345678901"
Grato, pela ajuda
gabriel
Validação de CNH
Enviado: 05 Jun 2010 10:45
por Pablo César
E estes números, não são verdadeiros ? Ou poderia tornar-se verdadeiros algum dia ? Se não forem e apenas esses, daria para colocar uma e outra excepção para torná-las falsas, caso assim sejam.
Este site é oficial para consultar CNHs:
http://novosite.detran.df.gov.br/habili ... ao-htm.jsp (observe que precisa clicar em (com foto ou sem foto) colocando a data nascimento ou CPF. Eu não tenho como testar pois não possuo um BD, faça o teste você mesmo e reporte e quais estão dando erro, para comprovar, seria melhor ter esses dados (data de nascimento e CPF) assim teríamos certeza da informação.
Re: Validação de CNH
Enviado: 05 Jun 2010 17:09
por lugab
Ah, ta, Pablo, desculpe.
É que eu nem aventei a possibilidade dessas sequências serem válidas...
Pelo sim, pelo não, estou recusando sequencias de mesmo número, tipo "11111111111" e progressões aritméticas, tipo "12345678901", que estão sendo dadas como ok....
Grato,
Gabriel