Skip to content
Petrus Silva Costa edited this page May 30, 2026 · 10 revisions

TISS_ANS_hash

Biblioteca multi-linguagem que calcula o hash MD5 do epílogo (<ans:hash>) de um lote XML do Padrão TISS/ANS: o código de 32 caracteres que a ANS usa para confirmar que o lote não foi adulterado. Você entrega o XML, a lib devolve o hash certo, em 13 linguagens que dão o mesmo resultado byte a byte.

O segredo (e a razão de existir)

O manual diz que o encoding do arquivo é ISO-8859-1. Mas o hash que a ANS realmente aceita é calculado sobre os bytes em UTF-8, não ISO-8859-1. Quem segue o manual ao pé da letra gera um hash errado e tem o lote rejeitado. Esta lib já faz a coisa certa para você.

Detalhe conceitual em Conceitos; a regra técnica exata na versão canônica do SPEC, seção 4.

Por onde começar

  • Nunca ouviu falar de TISS, hash ou XML: comece por Conceitos.
  • Quer pôr a mão na massa e ver um hash na tela: siga o Tutorial.
  • Já sabe o que quer e só precisa do código na sua linguagem: vá para Como usar.
  • Dúvida rápida, glossário ou um erro para resolver: veja o FAQ.

Quickstart

Go (publicado pela tag de versão):

go get github.com/petrinhu/TISS_ANS_hash/langs/go@v0.2.1
import tisshash "github.com/petrinhu/TISS_ANS_hash/langs/go"
hash, _ := tisshash.HashTissFile("lote.xml")
fmt.Println(hash) // 32 caracteres hex, ex.: 3aa0c578c95cdb861a125f480a8a4de5

Python (publicado no PyPI: pip install tiss-hash):

from tiss_hash import hash_tiss_file
print(hash_tiss_file("lote.xml"))  # 32 caracteres hex minúsculos

Node.js (publicado no npm: npm install tiss-hash):

import { hashTissFile } from 'tiss-hash';
console.log(await hashTissFile('lote.xml'));

Rust (publicado no crates.io: cargo add tiss-hash):

use tiss_hash::hash_tiss_file;
let digest = hash_tiss_file("lote.xml")?;
println!("{digest}"); // 32 caracteres hex minúsculos

PHP (publicado no Packagist: composer require petrinhu/tiss-hash):

<?php
require 'vendor/autoload.php';
use TissHash\TissHash;
echo TissHash::hashTissFile('lote.xml'); // 32 caracteres hex minúsculos

C# (publicado no NuGet: dotnet add package TissHash):

using TissHashLib = TissHash.TissHash;
Console.WriteLine(TissHashLib.HashTissFile("lote.xml")); // 32 caracteres hex minúsculos

Dart (publicado no pub.dev: dart pub add tiss_hash; em Flutter, flutter pub add tiss_hash):

import 'package:tiss_hash/tiss_hash.dart';
print(await hashTissFile('lote.xml')); // 32 caracteres hex minúsculos

As outras 6 linguagens (C, C++, Java, Kotlin, Delphi/Object Pascal e WASM) e as instruções completas de instalação estão em Como usar. O valor 3aa0c578c95cdb861a125f480a8a4de5 é um hash sintético (dados inventados), só para ilustrar o formato; o hash do seu lote será outro.

Destaque: hash no navegador (WASM)

O projeto passou de 9 para 13 linguagens, somando Kotlin, Delphi/Object Pascal (Free Pascal), Dart e WASM (WebAssembly).

O port WASM é o destaque: ele calcula o hash dentro do navegador do usuário (ou no Node.js), sem mandar nada para servidor nenhum. Esse é o argumento de privacidade mais forte do projeto. O XML TISS carrega dados pessoais de paciente (PII sob a LGPD); mandar o arquivo para um servidor hashear criaria um ponto de vazamento. No WASM o arquivo é selecionado, o hash é calculado localmente e nada trafega (nem o XML, nem o hash). O core é o mesmo Rust compilado para WebAssembly, então o resultado sai byte a byte idêntico ao dos outros 12 ports. Quickstart (browser e Node) em Como usar.

Garantia de equivalência

Python, Rust, C, C++, Node.js, PHP, Java, Go, C#, Kotlin, Delphi/Object Pascal, Dart e WASM: os 13 ports produzem o mesmo hash, byte a byte, para o mesmo XML. Isso é checado a cada mudança por uma suíte de 20 vetores de conformidade (18 positivos, com hash esperado, e 2 negativos, que devem ser recusados). Todos os dados de teste são sintéticos; nenhum dado real de paciente entra no projeto.

Release e licença

  • Release atual: v0.2.1 (13 linguagens, com artefatos prebuilt nos dois hosts, SHA256SUMS e SBOM).
  • Licença: MIT, uso livre inclusive comercial, sem garantias.
  • Código-fonte: repositório no GitHub (com espelho no Codeberg).

⭐ Changelog do teu apoio

Added

  • 1 estrela no topo deste repo (opcional, mas faz o maintainer solo sorrir).

Fixed

  • Síndrome do impostor de quem mantém FOSS de graça no fim de semana.

Custo: 1 clique. SemVer: não quebra nada.

(O botão Star fica no topo do repositório no GitHub.)

Clone this wiki locally