Files
Geradores/GeradoresService/README.md
2026-10-11 23:52:48 +01:00

72 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GeradoresService
Biblioteca .NET 10 com os algoritmos de geração e validação. Não tem dependências externas e é usada pela API
([GeradoresWS](../GeradoresWS/README.md)) e pelos testes ([UnitTest](../UnitTest/README.md)).
## Estrutura
| Caminho | Conteúdo |
|---|---|
| `Core/IGenerator.cs` | Contrato de um gerador/validador e as categorias |
| `Core/GeneratorBase.cs` | Classe base com valores por omissão e o helper `Option(...)` |
| `Core/Models.cs` | `GeneratorOption`, `GeneratedItem`, `ValidationResult`, `GeneratorContext` |
| `Core/Checksums.cs` | Algoritmos partilhados: módulo 11, Luhn (com letras), MOD 97-10, limpeza de input |
| `Data/PtData.cs` | Nomes, apelidos, localidades, bancos e outros dados portugueses fictícios |
| `Generators/<Categoria>/` | Um ficheiro por tipo |
| `GeneratorRegistry.cs` | Lista de geradores, geração em lote e detecção automática do tipo |
## Geradores
| Id | Nome | Categoria | Validação |
|---|---|---|---|
| `nif` | NIF | Identificação | Módulo 11, pesos 9..2 |
| `nipc` | NIPC | Identificação | Igual ao NIF, só prefixos de pessoa colectiva |
| `niss` | NISS | Identificação | 9 − (Σ dígito × peso) mod 10, pesos 29, 23, 19, 17, 13, 11, 7, 5, 3, 2 |
| `cc` | Cartão de Cidadão | Identificação | Módulo 11 no NIC + Luhn (A=10..Z=35) no documento |
| `passaporte` | Passaporte | Identificação | Só formato (letra + 6 dígitos) |
| `iban` | IBAN | Financeiro | ISO 7064 MOD 97-10; aceita IBAN de qualquer país |
| `nib` | NIB | Financeiro | 98 − (NIB19 × 100 mod 97) |
| `cartao-credito` | Cartão de crédito | Financeiro | Luhn |
| `multibanco` | Referência Multibanco | Financeiro | 98 − (Σ dígito × peso mod 97) sobre entidade + referência + montante |
| `pessoa` | Pessoa fictícia | Contactos e Morada | Não valida (gerador composto) |
| `telefone` | Telefone | Contactos e Morada | Só formato (Plano Nacional de Numeração) |
| `codigo-postal` | Código postal | Contactos e Morada | Só formato (NNNN-NNN) |
| `email` | Email | Contactos e Morada | Só formato |
| `matricula` | Matrícula | Outros | Só formato (todos os formatos desde 1937) |
| `ean` | EAN / Código de barras | Outros | Dígito GS1 (pesos 3,1,3,1…) |
| `uuid` | UUID / GUID | Outros | Só formato (v4 ou v7) |
`HasChecksum` indica se a validação verifica um dígito de controlo ou apenas o formato; `CanValidate` é
`false` para geradores compostos como `pessoa`.
## Utilização
```csharp
var registry = new GeneratorRegistry();
var nif = registry.Find("nif")!;
// 10 NIF de pessoa colectiva, reprodutíveis com seed
var items = registry.Generate(nif, 10, new Dictionary<string, string?> { ["tipo"] = "5" }, seed: 42);
// Validação de um tipo
ValidationResult r = nif.Validate("123456789"); // IsValid, FormatMatch, Message, Normalized, Details
// Detecção automática: válidos primeiro, depois os que têm o formato mas falham o controlo
var matches = registry.Detect("PT50 0002 0123 1234 5678 9015 4");
```
- O lote vai de 1 a `GeneratorRegistry.MaxBatch` (1000); fora disso lança `ArgumentOutOfRangeException`.
- Um valor de opção que não esteja nas escolhas do gerador lança `ArgumentException`.
- `ValidationResult.Details` traz os passos do cálculo, para explicar porque um valor é (in)válido.
## Adicionar um gerador
1. Criar uma classe em `Generators/<Categoria>/` que herde de `GeneratorBase` e implemente `Id`, `Name`,
`Category`, `Description`, `Generate` e `Validate`. As opções declaram-se com `Option(key, label, default, choices...)`
e lêem-se com `context.Option(Options[i])`.
2. Usar sempre `context.Random` (nunca `Random.Shared`), para que o `seed` produza resultados reprodutíveis.
3. Registar a instância no construtor de `GeneratorRegistry`.
O novo tipo aparece automaticamente na API e no frontend, e o `GeneratorRoundTripTests` passa a gerá-lo com
todas as opções e a confirmar que o validador aceita os valores gerados.