cadrumo.core.iban module

Shared ISO 13616 IBAN shape and checksum primitives.

One canonical home for the IBAN_SHAPE_RE pattern and iban_mod_97() check residue, consumed by IbanString for registry casillas declaring data_type = "iban" and by the secure-storage RefundAccount model. Keeping the primitives in core lets each domain validate an IBAN without importing the other.

Canonicalising the printed form is normalise_iban(), which lives here beside the shape and the checksum because every consumer needs the same answer before it can ask either of them: an IBAN is printed in groups of four on a bank statement and an invoice footer, so the separator-free spelling the shape gate accepts is the one that does NOT arrive. Two validators open-coded the same three-call canonicalisation and a third consumer – the confidentiality funnel – had no canonicalisation at all, which is what made the grouped rendering readable in operator output.

This module still does not decide whether a blank IBAN is allowed or choose the public error type. Registry casilla validation rejects blank IBAN data, while the refund-account model treats None and blank input as “no account on file”; both call these primitives after applying their own boundary policy.

IBAN_SHAPE_RE

ISO 13616 IBAN shape shared by registry and refund-account validators.

The pattern checks uppercase canonical text only: country code, two check digits, and an alphanumeric BBAN for a total length of 15-34 characters. It is only the structural gate; callers must also run iban_mod_97().

normalise_iban(value)[source]

Return the uppercase, separator-free form of a printed IBAN.

An IBAN is essentially always printed in groups of four – that is how it leaves a bank statement, an invoice footer and an operator’s clipboard – and hyphenated renderings are common too. IBAN_SHAPE_RE matches only the canonical spelling, so every consumer must fold the printed form onto it before asking the shape or iban_mod_97() anything.

Parameters:

value (str) – An IBAN as printed, with or without separators.

Return type:

str

Returns:

The uppercased value with spaces and hyphens removed. The result is not asserted to be a valid IBAN; the caller still runs the shape gate and the checksum.

iban_mod_97(canonical)[source]

Compute the ISO 13616 IBAN mod-97 check residue for an already-canonical IBAN.

Existing callers normalize separators and case and independently re-check IBAN_SHAPE_RE before calling this; see domain.calculations.registry.schema_scalars._validate_iban_string() and domain.deadlines.models._validate_iban. Those call-site gates are harmless belt-and-braces now that the shape is enforced here too, but they must not be the ONLY thing standing between a malformed string and a “valid” answer: a caller that forgets its own gate must still be refused, not silently pass. iban_mod_97("ES82") – four characters, no BBAN at all – previously returned 1 (a false “valid”), because the mod-97 arithmetic tolerates any string long enough to slice; nothing in the function itself demanded a real IBAN shape.

This helper moves the leading four characters to the tail, replaces each letter with its A=10 ... Z=35 numeric form, and returns the integer modulo 97. A valid IBAN yields a residue of 1.

Parameters:

canonical (str) – Uppercase, separator-free IBAN text.

Return type:

int

Returns:

The ISO 13616 check residue. 1 means the check digits are valid.

Raises:

ValueError – If canonical does not match IBAN_SHAPE_RE – it cannot be a real IBAN, so no residue is computed at all rather than an arithmetically well-formed but meaningless one.