Skip to main content

uk-bank-statement-anonymiser

Anonymise UK bank statement PDFs by scrambling personal data while preserving layout.

PyPI version CI License: MIT

Why?

You need to share bank statements with your accountant, solicitor, or lender — but the PDF contains sensitive data: account numbers, sort codes, IBANs, card numbers, and transaction details.

This tool scrambles that data while keeping the PDF looking like a real bank statement. Your financial data never leaves your machine.

Quick start

Using Python (API)

pip install uk-bank-statement-anonymiser
from bank_statement_anonymiser import anonymise_pdf

anonymise_pdf("statement.pdf", "anonymised.pdf")

Using the command line

pip install uk-bank-statement-anonymiser
anonymise-pdf statement.pdf

Prefer uv? See Installation for the uvx and uv tool install workflows.

Important: check before you share

This tool handles known patterns but cannot guarantee that all personally identifiable information has been removed. Bank statement PDFs may contain data in places this tool does not currently scan (e.g. embedded metadata, images, or unusual formatting).

  • You must review every anonymised PDF yourself before sharing it with any third party. Verify that no account numbers, names, addresses, balances, or other sensitive data remain visible.
  • Do not attach PDFs — anonymised or otherwise — to GitHub issues, PRs, or discussion threads. If anonymisation is failing, the statement will not be properly anonymised. Use text excerpts or screenshots with sensitive data redacted instead.
  • Do not paste log output, debug output, or console transcripts without checking them for PII. These may contain account numbers, names, addresses, or other sensitive data. Redact any sensitive content before sharing.

What gets anonymised

Data type Method
Sort codes Scrambled to valid format
Account numbers Replaced with random numbers
IBANs Replaced with random IBANs
Card numbers Replaced with random card numbers
Merchant names Scrambled
All other text Letters scrambled, layout preserved

Supported banks

  • HSBC UK (current & savings)
  • Natwest
  • TSB (Spend & Save & credit card)
  • Halifax

More banks can be added — see Contributing.

Why these banks? Each bank uses a different PDF encoding strategy. HSBC uses Latin-1, Natwest uses Identity-H CID fonts, and TSB uses custom ToUnicode CMaps. Other UK bank PDFs may work if they use one of the same approaches.

Custom rules

By default, the library handles common patterns automatically. You can supplement with your own rules:

anonymise_pdf(
    "statement.pdf",
    "output.pdf",
    always_anonymise_path="my_replacements.toml",
    never_anonymise_path="my_protected_phrases.toml",
)
  • always_anonymise.toml — Force specific strings to known replacements:

    "40-37-28" = "00-00-00"
    "Jason Farrar" = "John Doe"
    
  • never_anonymise.toml — Protect phrases from being scrambled:

    exclude = ["My Employer Ltd", "Salary Payment"]
    

User config files override system config on clashes. Both system and user never_anonymise lists are combined.

Do not commit user config files to source control — they may contain real account numbers or names.

Retaining transaction descriptions

By default, all text that is not protected or explicitly replaced is scrambled. If you need transaction descriptions to remain readable — for tutorials, reporting, or review — use the retain_descriptions flag.

This disables the default letter-scrambling so that only always_anonymise replacements and numeric ID substitutions (sort codes, account numbers, card numbers) are applied. Everything else — including merchant names, descriptions, customer names, and addresses — is left untouched.

anonymise_pdf(
    "statement.pdf",
    "output.pdf",
    always_anonymise_path="my_replacements.toml",
    retain_descriptions=True,
)
anonymise-pdf statement.pdf -o output.pdf \
    --always-anonymise my_replacements.toml \
    --retain-descriptions

retain_descriptions requires a user always_anonymise.toml — without it, sensitive names and addresses would remain un-anonymised. The tool raises a ValueError if you pass retain_descriptions=True without an always_anonymise_path.

API reference

def anonymise_pdf(
    input_path: str | Path,
    output_path: str | Path | None = None,
    always_anonymise_path: str | Path | None = None,
    never_anonymise_path: str | Path | None = None,
    retain_descriptions: bool = False,
    debug: bool = False,
) -> Path
Parameter Description
input_path Path to the input PDF
output_path Output path. If omitted, writes anonymised_<stem><suffix> alongside the input
always_anonymise_path User replacement rules (optional)
never_anonymise_path User protected phrases (optional)
retain_descriptions Disable default letter-scrambling; only apply always_anonymise replacements and numeric IDs (default False). Requires always_anonymise_path.
debug Print diagnostic info to stdout (default False)
Returns Absolute path to the output PDF
Raises FileNotFoundError if input_path does not exist
Raises ValueError if retain_descriptions is True but no always_anonymise_path was provided

How it works

Anonymisation workflow

  1. Identify sensitive data — Detects sort codes, account numbers, IBANs, card numbers, and other patterns. Each gets a deterministic fake replacement so the same data is always replaced consistently across pages.

  2. Protect structural text — Dates, payment type codes, bank URLs, and configured protected phrases are left unchanged.

  3. Scramble remaining text — All other letters are replaced with random alternatives; digits and symbols stay intact. The PDF's layout, fonts, images, and line breaks are preserved.

All processing happens locally via pikepdf. No network requests, no accounts, no data collection.

Customisation

The anonymiser is designed to be extended for other bank formats (e.g. US, EU) or non-bank PDFs. Three areas control what gets anonymised:

Customisation architecture

  1. Pattern detection — Regex patterns identify sort codes, account numbers, IBANs, card numbers, dates, amounts, and URLs. Add or modify patterns in the source to support new formats.

  2. System configs — Default replacement rules (always_anonymise_system.toml) and protected phrases (never_anonymise_system.toml) ship with the package.

  3. User configs — Optional TOML files passed via --always-anonymise / --never-anonymise (CLI) or always_anonymise_path / never_anonymise_path (Python API) to add custom rules. User replacements override system defaults; protected phrases are merged (union).

Regenerating diagrams: Diagrams are authored in Mermaid (.mmd files in docs/diagrams/). To regenerate SVG/PNG, install mermaid-cli (uv add --group dev mermaid-cli) and run mmdc -i <input>.mmd -o <output>.svg.

Installation

Option 1: uv (recommended)

If you have uv installed:

Run once, no permanent install:

uvx --from uk-bank-statement-anonymiser anonymise-pdf statement.pdf

uvx runs the tool in a temporary isolated environment. Nothing is permanently installed.

Install permanently (makes anonymise-pdf available anywhere):

uv tool install uk-bank-statement-anonymiser
anonymise-pdf statement.pdf

Use the Python API in your own uv project:

uv add uk-bank-statement-anonymiser
from bank_statement_anonymiser import anonymise_pdf
anonymise_pdf("statement.pdf", "anonymised.pdf")

Option 2: pip + virtual environment

python -m venv .venv
source .venv/bin/activate        # macOS / Linux
# .venv\Scripts\activate         # Windows
pip install uk-bank-statement-anonymiser
anonymise-pdf statement.pdf

Note: On Windows, use .venv\Scripts\activate instead. If you skip the virtual environment, anonymise-pdf may not be found on your PATH.

CLI usage

anonymise-pdf statement.pdf
anonymise-pdf statement.pdf -o output.pdf
anonymise-pdf statement.pdf --always-anonymise rules.toml --never-anonymise protected.toml
anonymise-pdf statement.pdf --always-anonymise rules.toml --retain-descriptions
anonymise-pdf statement.pdf --debug     # prints diagnostic info; may expose config values
Flag Description
-o, --output Output path (default: anonymised_<stem><suffix> alongside input)
--always-anonymise TOML file with forced replacements
--never-anonymise TOML file with protected phrases
--retain-descriptions Disable letter-scrambling; only apply always_anonymise rules and numeric IDs (requires --always-anonymise)
--debug Print diagnostic info to stdout

See Custom rules for TOML file format.

Related projects

This library is used by other projects in the boscorat ecosystem:

  • openstan — Free, offline UK bank statement analyser. Parse, analyse, and export your statements to Excel, CSV, or JSON. Uses uk-bank-statement-anonymiser to redact statements for safe sharing. Website: openstan.org

  • bank_statement_parser — Parse bank statement PDFs, extract structured transaction data, and persist results to Parquet or SQLite. Includes optional PDF anonymisation via uk-bank-statement-anonymiser.

Contributing

The most valuable contribution is testing the anonymiser against real bank statements from your own accounts. Your PDFs never leave your machine — you only submit a review report.

See CONTRIBUTING.md for the full workflow.

Development (for contributors)

git clone https://github.com/boscorat/uk-bank-statement-anonymiser.git
cd uk-bank-statement-anonymiser
uv sync
uv run pytest

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uk_bank_statement_anonymiser-0.2.2.tar.gz (30.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uk_bank_statement_anonymiser-0.2.2-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

File details

Details for the file uk_bank_statement_anonymiser-0.2.2.tar.gz.

File metadata

  • Download URL: uk_bank_statement_anonymiser-0.2.2.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for uk_bank_statement_anonymiser-0.2.2.tar.gz
Algorithm Hash digest
SHA256 f259e13dd701cd00f13326c7cd316f718cb24b2309ce91d5fade9b1e620622d2
MD5 d16940bd933023134f9596c3d022a897
BLAKE2b-256 4bcad6c6400e3cb7d85ac4c8eef9ddfc24c42d4a1a49a27603a78b36717aedae

See more details on using hashes here.

File details

Details for the file uk_bank_statement_anonymiser-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: uk_bank_statement_anonymiser-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 34.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for uk_bank_statement_anonymiser-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 cae5d2568b072418851373242c88059dc89b8741dced3d0dec14f4bd62d1b586
MD5 30032d1dc8b0ddc902f3574f2debfba1
BLAKE2b-256 5770d8fe68f4f0f5fa64673e1aa07641c4c42fde3d6dfc2b574e1a31981e6209

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.3

2 files

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page