Claculo da CHAVE DIGITO VERIFICADOR para CNPJ ALFANUMERICO

CSharp · Console

/Program.cs

using System;

///< summary>
/// Falta com uma chave real que gere DV zero ou encontrar a redação oficial
/// da NT. ASCII-48 Peso 2,3,4,5,6,7,8,9 Da direita para esquerda posição
/// mais à direita → peso 2 próxima → peso 3
/// ...
/// quando chega em 9 volta para 2
///</summary>
public class Program {
    	
    public static void Main()
    {
        // EMIR TOKTAR - Teste de 03 chaves com CNPJs Alfanuméricos
        Console.WriteLine("Iniciando validação de Chaves e geração DV");
        // NFS2611606226TS1HJ0S000170000000000000126071589021231
        string id = "NFS2611606226TS1HJ0S000170000000000000126071589021231";
        Console.WriteLine(IdNfseAlfa.CalcularDVId(id));
        // NFS2611606226TS1HJ0S000170000000000000226074472878459
        string id2 = "NFS2611606226TS1HJ0S000170000000000000226074472878459";
        Console.WriteLine(IdNfseAlfa.CalcularDVId(id2));
        // NFS2611606226TS1HJ0S000170000000000000326078203666998
        string id3 = "2611606226TS1HJ0S00017000000000000032607820366699";
        Console.WriteLine(IdNfseAlfa.CalcularDVId(id3));

		Console.WriteLine($"{Environment.NewLine}Validando uma Chave Acesso Alfanumérica: NFS2611606226TS1HJ0S000170000000000000326078203666998.");
        string idCompleto = "NFS2611606226TS1HJ0S000170000000000000326078203666998";
        Console.WriteLine($" --> Resultado: {IdNfseAlfa.ValidarId(idCompleto)}");
        Console.WriteLine($"{Environment.NewLine}FIM");
    }

    /// Algoritmo validado com NFS-e emitidas pelo Ambiente Nacional (SEFIN)
    /// - Conversão ASCII-48
    /// - Pesos 2..9 (cíclicos)
    /// - Processamento da direita para a esquerda
    /// - Módulo 11

    public static class IdNfseAlfa {
        /// <summary>
        /// Recebe o identificador da NFS-e sem o prefixo "NFS" e sem o DV (49
        /// caracteres). CalcularDV() → método interno/técnico, recebe
        /// exatamente 49.
        /// </summary>
        public static int CalcularDV(string idSemDV)
        {
            // Validação silenciosa sem custo, mas como garantia.
            if (idSemDV == null)
                throw new ArgumentNullException(nameof(idSemDV));

            if (idSemDV.Length != 49)
                throw new ArgumentException(
                    "A chave deve possuir 49 caracteres.");

            int soma = 0;
            int peso = 2;

            for (int i = idSemDV.Length - 1; i >= 0; i--) {
                soma += CharToValor(idSemDV[i]) * peso;
                peso++;
                if (peso > 9) {
                    peso = 2;
                }
            }
            int resto = soma % 11;

            // Regra que acreditamos ser a oficial
            // if (resto == 0 || resto == 1)
            //    return 0;
            // return 11 - resto;

            //  É exatamente a mesma regra que acima
            //  Conforme algoritmo do IdNFSe com CNPJ alfanumérico.
            //  Aguardar confirmação oficial apenas para os casos de resto 0
            //  e 1.
            int dv = 11 - resto;
            if (dv >= 10)
                dv = 0;
            return dv;
        }

        public static int CalcularDVId(string id)
        {
            if (string.IsNullOrWhiteSpace(id))
                throw new ArgumentNullException(nameof(id));

            if (id.StartsWith("NFS", StringComparison.OrdinalIgnoreCase))
                id = id.Substring(3);
            // Após remover NFS:
            // 49 = chave sem DV
            // 50 = chave com DV
            if (id.Length == 50) {
                id = id.Substring(0, id.Length - 1);
            }

            if (id.Length != 49)
                throw new ArgumentException("Id inválido.");

            return CalcularDV(id);
        }

        private static int CharToValor(char c)
        {
            c = char.ToUpperInvariant(c);
            if (char.IsDigit(c))
                return c - '0';
            if (c >= 'A' && c <= 'Z')
                return c - 48;
            throw new ArgumentException($"Caractere inválido: {c}");
        }

        /// Valida uma chave completa
        public static bool ValidarId(string id)
        {
            if (string.IsNullOrWhiteSpace(id))
                return false;

            if (id.StartsWith("NFS", StringComparison.OrdinalIgnoreCase))
                id = id.Substring(3);

            if (id.Length != 50)
                return false;

            int dvInformado = id[49] - '0';
            return dvInformado == CalcularDV(id.Substring(0, 49));
        }
    }
}
;