Executando verificação de segurança...
4

Mas com a notícia de CNPJ alfanumérico para 2026, as opções agora serão mais limitadas, então os tipos numericos deixam de ser opções para novos projetos desenvolvidos a partir de agora já prevendo essa mudança.

Carregando publicação patrocinada...
3

vergilSparda, nesse caso do CNPJ Alfanumérico seria guardado no banco de dados como uma sequência de bytes ou um Base64 (ou ainda, um Base32)? Não pensei no que seria mais eficiente. 2026 chega em menos de 14 meses!!

Encontrei uma discussão referente ao caso do CNPJ Alfanumérico, que inclusive cita uma documentação oficial.
Nota Técnica nº49/2024, COCAD/SUARA/RFB (PDF | 603 KB)

Com relação à discussão no blog, a mesma é bem sucinta. Segundo explicam (achei melhor citar ipsis litris):

A fórmula de cálculo do dígito verificador do CNPJ Alfanumérico não muda: foi mantido o cálculo pelo módulo 11. Porém, para garantir a utilização dos atuais números do CNPJ (tipo numérico), será necessária a alteração do modo como se calcula o dígito verificador pelo módulo 11. Serão utilizados, no cálculo do módulo 11, os valores relativos a letras maiúsculas lastreadas na tabela denominada código ASCII, como solução para unificar a representação de caracteres alfanuméricos.

Na rotina de cálculo do Dígito Verificador (DV)no CNPJ, serão substituídos os valores numéricos e alfanuméricos pelo valor decimal correspondente ao código constante na tabela ASCII e dele subtraído o valor48. Desta forma os caracteres numéricos continuarão com os mesmos montantes, e os caracteres alfanuméricos terão os seguintes valores: A=17, B=18, C=19… e assim sucessivamente. Esta definição permitirá que o atual número do CNPJ tenha o mesmo cálculo do seu dígito verificador quando os sistemas iniciarem a identificação alfanumérica.
Fonte: http://www.pctoledo.com.br/forum/viewtopic.php?f=4&t=27693#p165547

O motivo do salto indicado na explicação anterior (... "A"=17, "B"=18, "C"=19 etc.) é facilmente observado ao inspecionar a posição dos números e letras maiúsculas na tabela ASCII:

Caractere ASCII | Valor em decimal | Correspondente
       0                48                 0
       1                49                 1
     ...               ...               ...
       8                56                 8
       9                57                 9
     ...               ...               ...
       A                65                17
       B                66                18
     ...               ...               ...
       Y                89                41
       Z                90                42

Antevendo a alteração do padrão do CNPJ ajustei a rotina de validação co CNPJ...
Espero poder auxiliar os colegas no tocante ao assunto...
Fonte: http://www.pctoledo.com.br/forum/viewtopic.php?f=43&t=27691#p165545
Código a seguir:

O markdown ainda não tem syntax hightlight compatível com pascal language.

function CNPJ_validar(pCNPJ, plMsg )
// #toya: 24/06/2024 - 07:00:00 - mrb_2024 Release .001.001

Local lResult := .t.
local soma := 0
local dv := ""
local digito := 0
local num := 0
Local wCGC := iif(ValType(pCNPJ)="U", "", pCNPJ)
local i := 0
local j := 0
local Validos := "0123456789"

DEFAULT plMsg := .t.

wCGC := StrTran(wCGC, ".", "")   
wCGC := StrTran(wCGC, "-", "")   
wCGC := StrTran(wCGC, "/", "")
if Empty(wCGC)
    lResult := .t.
else
    if len(wCGC) < 14
        lResult := .f.
    else
      for i = 1 to 12
         if substr(wCGC, i, 1) $ "ABCDEFGHIJKLMNOPQRSTUWYXZ"
            Validos := "0123456789ABCDEFGHIJKLMNOPQRSTUWYXZ"
            exit    
         endif
      next
        dv := ""
        num := 5
        for j = 1 to 2
            soma := 0
            for i = 1 to 12
                soma += (asc(substr(wCGC, i, 1)) - 48) * num
                num--
                if num == 1
                    num := 9
                endif
            next
            if j == 2
                soma+=( 2 * val(dv))
            endif
            digito = soma - (int(soma / 11) * 11)
            if digito == 0 .or. digito == 1
                dv := dv + "0"
            else
                dv := dv + str(11 - digito, 1)
            endif
            num := 6
        next
        if dv <> substr(wCGC, 13, 2)
            lResult := .f.
        endif
    endif
    if !lResult
       if plMsg
           Msg_OK("CNPJ Incorreto ou Digito Invalido..." + " [" + dv + "]" )
       endif
   endif
endif

return lResult

function Msg_Ok(cMsg, cTitle)

Return(MessageBox(GetActiveWindow(), cMsg, cTitle, nOR(16,0)))

# fonte: Reforma Tributária
         - Nota Técnica nº49/2024, COCAD/SUARA/RFB
         - Novo formato de CNPJ em alfanumérico

Outra fonte propõe um código bem mais simples

* nPos  [Int]
* sCNPJ [String, UpperCase]
* cPos  [Char]
* aDigito [Array[12], Int]

   For nPos := 1 To 12
      cPos := Subs( sCNPJ, nPos, 1 )
      aDigito[ nPos ] := Asc( cPos ) - 48
   Next
* Fonte: http://www.pctoledo.com.br/forum/viewtopic.php?f=4&t=27693#p165547
3

Complicação desnecessária. A validação de CNPJ fica por conta da aplicação. Fazer uma interpretação de dados na hora de ler e escrever é um desperdício a nível de banco, pois você teria que fazer uma interpretação atômica. Nesse caso, mesma solução se aplica, armazena-se em CHAR e utiliza um CRC para otimizar o cálculo de busca.

2

Verdade! A ideia que perguntei empregando Base64/32 parece-se com aquela invenção do Ra-Tim-Bum para apagar uma vela 8-). Valeu pela crítica, caiquearaujo e pela proposta mais eficiente. O campo com CHAR é nativo e um dos diferentes CRCs funcionaria como se fosse um hash de comprimento relativamente curto.

1

Acredito que números, exceto antigamente pela questão de armazenamento que tanto justificava isso, nem deveriam ser considerados nesse caso. A natureza de números de identificação de pessoas não é numérica. Em breve, até CPFs deverão passar pela mudança.