rahasya
Thirty-four kinds of personal identifier, each a pattern with a checksum, read in context. 1.000 precision at recall 1.000 on a held-out corpus, 0.996 on the one they were tuned against. No model, no network, no gigabyte on disk.
Install
uv add rahasya
The one call
r = pii_report('Invoice for ada@example.com. Card 4111 1111 1111 1111. '
'KEY=sk-abcdefghijklmnopqrstuvwxyz123456')
r.has_pii, r.identifying
has_pii counts only IDENTIFYING kinds. An IP address is reported and does not tip the
gate.
redact('Card 4111 1111 1111 1111 charged to ada@example.com')
Digits are read in context
A number failing its checksum is not the thing the checksum protects. A number introduced by a reference word is not an identifier.
[pii_report(t).has_pii for t in
('Order 4111 1111 1111 1112 shipped', # fails Luhn
'Conforms to EN 60601-1', # a standard, not a ZIP
'Card 4111 1111 1111 1111')] # this one is a card
DESIGNATOR holds the words that do it: ISO, RFC, invoice, page, commit, order
and thirty more. It is matched against the 48 characters to the left of a candidate.
Nineteen regional identifiers, each with its own checksum
| where | kinds |
|---|---|
| India | Aadhaar, PAN, GSTIN |
| Australia | TFN, ABN, Medicare |
| Europe | Dutch BSN, French NIR, Spanish DNI and NIE, Italian codice fiscale, Polish PESEL, Swedish personnummer, Norwegian fødselsnummer, German Steuer-IdNr, UK NINO |
| Asia-Pacific | Singapore NRIC, Thai national ID |
| anywhere | IMEI |
import random
a = gen_aadhaar(random.Random(0)) # a valid one, for a fixture
a, aadhaar_ok(a), pesel_ok('44051401359'), nino_ok('AB123456C')
Names are opt-in
ner=True turns on an honorific-anchored pass. Dr Charles Babbage matches; a bare
Ada Lovelace does not. scanned_ner says whether anything looked, which keeps “none found”
apart from “not looked for”.
(pii_report('Dr Charles Babbage signed it.').has_pii,
pii_report('Dr Charles Babbage signed it.', ner=True).identifying,
redact('Dr Charles Babbage signed it.', ner=True))
What is here
| name | what it does |
|---|---|
pii_report |
spans found, and whether they tip has_pii |
pii_spans |
(start, end, kind, value), de-overlapped longest-first |
redact |
mask matched spans; [EMAIL], [CARD], or a mask you name |
redact_obj |
redact over the strings inside a nested dict or list |
redact(..., numbered=True) |
[EMAIL_1], one number per value; a dict keeps numbers across calls |
block_spans |
(block, start, end, kind, value) over a page’s blocks, scanned joined |
fingerprint |
a stable id for a finding, the same through spacing, dashes and case |
mask_preview |
enough of a finding to recognise it: a••••@g••••.com |
person_names / person_spans |
the honorific-anchored name pass |
PATTERNS |
kind to (pattern, validator); the whole detector as data |
IDENTIFYING |
which kinds tip the gate |
luhn, aadhaar_ok, pesel_ok and the rest are exported too, because a checksum is useful on
its own.
No model
Two learned detectors were measured against these patterns. Both lose on precision and recall, and are 200 times slower. A DeBERTa-v3 ONNX classifier earns its gigabyte only on names no honorific introduces (2/8 to 5/8 of them). A 350M tflite encoder finds no names at all.
Development
The notebooks in nbs/ are the source; the modules are generated.
pip install -e .
nbdev_prepare
Metadata
Release files for rahasya 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| rahasya-0.0.3.tar.gz | 18.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rahasya-0.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.0 kB
Release files / rahasya-0.0.3.tar.gz
| Download URL | rahasya-0.0.3.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45468fe6772f1cfaa31dd8af9fc2c3442788dd53742afe6a0aede013f9f57284
|
|
BLAKE2b-256 checksum How to use checksums |
e3216d140a98156e434f7c37f374f8371a62b01477aa9ad6a1deec05c1a423cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / rahasya-0.0.3-py3-none-any.whl
| Download URL | rahasya-0.0.3-py3-none-any.whl |
|---|---|
| Size | 19.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
64433936283cb013cc039701fc89db4e64136b75bde95890d592bb831bfd8e4c
|
|
BLAKE2b-256 checksum How to use checksums |
70dc3619fb642343479676bf74aa9eac2e4f2d008dc8bc317b0534f062644e2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Security for rahasya 0.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.