Pular para o conteúdo
ValidadorCNPJ Gerar CNPJ

Delphi · código pronto

Validar CNPJ alfanumérico em Delphi

Validador de CNPJ alfanumérico em Delphi / Object Pascal, compatível com sistemas legados.

Testar um CNPJ agora Gerar massa de teste

Muito sistema fiscal brasileiro roda em Delphi, e é exatamente onde o CNPJ costuma estar guardado em campo numérico. A unit abaixo funciona do Delphi 2009 em diante (e no Lazarus/Free Pascal) e não depende de nada além da SysUtils.

O algoritmo é sempre o mesmo: cada caractere vale o seu código ASCII menos 48 (0=0 … 9=9, A=17 … Z=42), os pesos vão de 2 a 9 da direita para a esquerda, soma-se tudo, divide-se por 11 e o dígito é 0 quando o resto é menor que 2, ou 11 menos o resto. Ver a conta detalhada.

Código completo

validação de CNPJ alfanumérico em Delphi
unit uCnpj;

interface

function LimparCnpj(const Valor: string): string;
function CalcularDvCnpj(const Base: string): string;
function CnpjValido(const Valor: string): Boolean;
function FormatarCnpj(const Valor: string): string;

implementation

uses
  SysUtils;

function LimparCnpj(const Valor: string): string;
var
  I: Integer;
  C: Char;
begin
  Result := '';
  for I := 1 to Length(Valor) do
  begin
    C := UpCase(Valor[I]);
    if CharInSet(C, ['0'..'9', 'A'..'Z']) then
      Result := Result + C;
  end;
end;

{ Calcula um dígito do módulo 11 (valor do caractere = ASCII - 48). }
function Digito(const Sequencia: string): Integer;
var
  I, Soma, Valor, Peso, Resto, Tamanho: Integer;
begin
  Soma := 0;
  Tamanho := Length(Sequencia);

  for I := 1 to Tamanho do
  begin
    Valor := Ord(Sequencia[I]) - 48;
    Peso := ((Tamanho - I) mod 8) + 2;
    Soma := Soma + (Valor * Peso);
  end;

  Resto := Soma mod 11;

  if Resto < 2 then
    Result := 0
  else
    Result := 11 - Resto;
end;

function CalcularDvCnpj(const Base: string): string;
var
  Primeiro, Segundo: Integer;
begin
  Primeiro := Digito(Base);
  Segundo := Digito(Base + IntToStr(Primeiro));
  Result := IntToStr(Primeiro) + IntToStr(Segundo);
end;

function TodosCaracteresIguais(const Texto: string): Boolean;
var
  I: Integer;
begin
  Result := True;
  for I := 2 to Length(Texto) do
    if Texto[I] <> Texto[1] then
    begin
      Result := False;
      Exit;
    end;
end;

function CnpjValido(const Valor: string): Boolean;
var
  Cnpj: string;
  I: Integer;
begin
  Cnpj := LimparCnpj(Valor);

  if Length(Cnpj) <> 14 then
    Exit(False);

  { Os dois dígitos verificadores continuam sendo numéricos }
  for I := 13 to 14 do
    if not CharInSet(Cnpj[I], ['0'..'9']) then
      Exit(False);

  if TodosCaracteresIguais(Cnpj) then
    Exit(False);

  Result := CalcularDvCnpj(Copy(Cnpj, 1, 12)) = Copy(Cnpj, 13, 2);
end;

function FormatarCnpj(const Valor: string): string;
var
  Cnpj: string;
begin
  Cnpj := LimparCnpj(Valor);

  if Length(Cnpj) <> 14 then
    Exit(Cnpj);

  Result := Copy(Cnpj, 1, 2) + '.' + Copy(Cnpj, 3, 3) + '.' +
            Copy(Cnpj, 6, 3) + '/' + Copy(Cnpj, 9, 4) + '-' +
            Copy(Cnpj, 13, 2);
end;

end.

Testes e integração com o framework

uso na aplicação
procedure TFrmEmpresa.edtCnpjExit(Sender: TObject);
begin
  if edtCnpj.Text = '' then
    Exit;

  if not CnpjValido(edtCnpj.Text) then
  begin
    ShowMessage('CNPJ inválido. Confira os dígitos verificadores.');
    edtCnpj.SetFocus;
    Exit;
  end;

  edtCnpj.Text := FormatarCnpj(edtCnpj.Text);
end;

{ Antes de julho de 2026, troque no DataModule:
    FieldByName('CNPJ').AsInteger  ->  FieldByName('CNPJ').AsString
  e no banco:
    ALTER TABLE EMPRESA ALTER COLUMN CNPJ TYPE VARCHAR(14);  }

Detalhes que costumam quebrar em Delphi

Casos de teste recomendados

Cubra pelo menos estes cenários — eles pegam praticamente todos os erros de implementação:

EntradaEsperadoO que testa
12.ABC.345/01DE-35válidoexemplo oficial, com máscara
12abc34501de35válidonormalização para maiúsculas
11.222.333/0001-81válidocompatibilidade com o formato numérico
11.222.333/0001-82inválidodígito verificador errado
12ABC34501DEABinválidoletra no dígito verificador
12ABC34501DE3inválidotamanho incorreto
00.000.000/0000-00inválidosequência repetida
"" / nullinválidoentrada vazia sem exceção

Precisa de mais massa de teste? O gerador produz até 500 CNPJs alfanuméricos válidos de uma vez, com opção de baixar em .txt.

O mesmo algoritmo em outras linguagens

Dúvidas sobre CNPJ alfanumérico em Delphi

Preciso de alguma biblioteca para validar CNPJ alfanumérico em Delphi?

Não. O código desta página usa apenas a biblioteca padrão de Delphi — são cerca de 30 linhas. Bibliotecas de terceiros só valem a pena se você também precisa de formatação, geração e validação de outros documentos; e, nesse caso, confira se a versão instalada já suporta o formato alfanumérico.

A mesma função valida CNPJ numérico e alfanumérico em Delphi?

Sim. Como o valor de cada dígito é o próprio dígito (código ASCII menos 48), o algoritmo alfanumérico produz o mesmo resultado do antigo para números. Você não precisa manter duas funções nem ramificar por formato.

Como testar se a implementação está certa?

Use o exemplo oficial da Receita Federal: a base 12ABC34501DE tem dígitos verificadores 35, formando 12.ABC.345/01DE-35. Confira também um CNPJ numérico conhecido, como 11.222.333/0001-81, e um inválido, como 11.222.333/0001-82.

O que mais precisa mudar além da função de validação?

O tipo da coluna no banco (de numérico para VARCHAR(14)), qualquer conversão para inteiro no caminho do dado, as máscaras de entrada e as regex espalhadas por validações e relatórios. A função de validação costuma ser a parte mais fácil da migração.