CSharp · Console
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));
}
}
}