TissHash 0.1.0

dotnet add package TissHash --version 0.1.0
                    
NuGet\Install-Package TissHash -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TissHash" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TissHash" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="TissHash" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TissHash --version 0.1.0
                    
#r "nuget: TissHash, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TissHash@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TissHash&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=TissHash&version=0.1.0
                    
Install as a Cake Tool

TissHash (.NET)

Calcula a "impressão digital" do trecho final de um documento TISS/ANS. Antes do código, os termos essenciais:

  • XML: formato de arquivo de texto que organiza dados em etiquetas (tags) aninhadas, como caixas dentro de caixas. O Padrão TISS é o XML que operadoras de saúde e consultórios usam no Brasil para trocar dados de atendimento.
  • Hash: sequência curta e fixa de caracteres calculada a partir de um texto, como uma impressão digital. Mude uma letra, o hash muda inteiro.
  • MD5: a receita (algoritmo) que gera o hash; sempre 32 caracteres hexadecimais (0-9 e a-f).
  • Epílogo: a parte final do documento TISS, a etiqueta <ans:hash>, onde o hash precisa ser gravado.
  • Byte: a menor unidade de dado do computador; um arquivo de texto é uma fila de bytes.

Em uma frase: você passa os bytes de um XML TISS e recebe os 32 caracteres do hash. Este é o port C# / .NET ("port" = a mesma lib reescrita em outra linguagem) da biblioteca tiss-hash. Para entender o problema que a lib resolve, veja docs/USAGE.md (guia de uso) e docs/ARCHITECTURE.md (conceitos e visão geral).

Bate byte-a-byte com a referência Python (conformance/reference.py) nos 20 vetores de conformidade (18 positivos + 2 negativos) compartilhados em conformance/vectors.json.

  • Status: alpha (20/20 vetores PASS: 18 positivos + 2 negativos)
  • TFM: net8.0 (LTS)
  • Licença: MIT
  • Dependências runtime: System.Text.Encoding.CodePages (provider oficial Microsoft, necessário para iso-8859-1 em .NET Core+)

Antes de começar: instalar o .NET SDK

Para compilar e rodar código C# você precisa do .NET SDK (Software Development Kit: compilador + ferramentas de build + runtime). Ele traz o comando dotnet, que também baixa as dependências.

dotnet --version

Instalação

Uma dependência é uma biblioteca de terceiros que o seu código usa; o dotnet a baixa por você.

Pacote não está publicado no NuGet (o repositório oficial de pacotes .NET). Para usar localmente, adicione o projeto como referência (a partir da pasta que você baixou com git clone):

dotnet add reference path/to/lib_hash_ans/langs/csharp/src/TissHash/TissHash.csproj

Quando publicado:

dotnet add package TissHash --version 0.1.0

Uso

using TissHashLib = TissHash.TissHash; // alias evita ambiguidade ns vs classe

// A partir de bytes
byte[] xml = File.ReadAllBytes("lote.xml");
string md5 = TissHashLib.HashTiss(xml);
Console.WriteLine(md5); // 32 hex lowercase

// Atalho a partir de path
string md5b = TissHashLib.HashTissFile("lote.xml");

Erros:

  • ArgumentNullException: entrada nula.
  • TissHash.InvalidTissXmlException: XML mal-formado, vazio ou rejeitado pelo parser (DTD proibida, encoding inválido, etc.). A causa original (System.Xml.XmlException) fica em InnerException.

Algoritmo (resumo)

  1. Parse do XML (encoding detectado do prólogo ou BOM).
  2. Localizar o <ans:hash> (qualquer prefixo, namespace http://www.ans.gov.br/padroes/tiss/schemas) e tratar seu conteúdo como string vazia. Documento sem <ans:hash> é válido; com múltiplos <ans:hash> é rejeitado (InvalidTissXmlException).
  3. Concatenar o textContent de cada nó-folha (XElement ou XComment cujos filhos NÃO contêm XElement/XComment/PI) em ordem de documento.
  4. MD5 sobre os bytes UTF-8 da string concatenada.
  5. Hex lowercase, 32 caracteres.

Para detalhes completos e as 15 ambiguidades canônicas, ver:

  • docs/SPEC.md na raiz do repositório
  • conformance/AMBIGUITY_NOTES.md

Decisões técnicas

  • Parser: System.Xml.Linq.XDocument: LINQ to XML, stdlib, zero dep externa, preserva XComment como nodes filhos por padrão (essencial para a ambiguidade #2 da referência: comentários XML ENTRAM no concat).
  • Reader: XmlReader.Create(Stream, settings) com DtdProcessing.Prohibit + XmlResolver = null (anti-XXE) e IgnoreComments = false, IgnoreWhitespace = false.
  • MD5: System.Security.Cryptography.MD5.HashData: API stateless moderna (.NET 5+), evita alocação de instância.
  • Encoding ISO-8859-1: registrado via Encoding.RegisterProvider(CodePagesEncodingProvider.Instance) no construtor estático (idempotente). Necessário porque .NET Core+ não embute code pages legacy por default. Encodings suportados: ISO-8859-1 e UTF-8; UTF-16/UTF-32 são rejeitados (fora de escopo).
  • Hash bytes = UTF-8 (não ISO-8859-1, apesar do manual TISS dizer o contrário; ver caveat na seção 4 do SPEC.md).

Build e teste

Da pasta langs/csharp/ (dentro do repositorio que voce baixou com git clone):

dotnet restore           # baixa as dependencias
dotnet build -c Release  # compila a biblioteca
dotnet test              # roda os 20 vetores de conformidade

Esperado: PASS em 20 vetores de conformidade (18 positivos + 2 negativos rejeitados) mais os testes de API/erro auxiliares. Cada vetor é um par "arquivo de entrada → hash esperado": positivo deve produzir um hash, negativo deve ser rejeitado (a lib precisa recusar o arquivo, em vez de inventar um hash).

Compatibilidade

  • .NET 8.0+ (LTS).
  • Funciona em Windows, Linux, macOS (qualquer runtime .NET 8).
  • Sem deps nativas; tudo via BCL + 1 pacote oficial Microsoft.

Estrutura

langs/csharp/
├── TissHash.sln
├── LICENSE
├── README.md
├── .gitignore
├── src/TissHash/
│   ├── TissHash.csproj
│   ├── TissHash.cs                  # API pública (static class)
│   └── InvalidTissXmlException.cs
└── tests/TissHash.Tests/
    ├── TissHash.Tests.csproj
    └── ConformanceTests.cs

Licença

MIT, ver LICENSE.

Ver também

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 89 5/30/2026