nhs-number 1.0.3

United Kingdom (UK) National Health Service (NHS) Number — parse, format, and validate the ten-digit identifier used by UK NHS England, UK NHS Scotland, UK NHS Wales, and UK NHS Isle of Man.
Documentation
# NHS Number

**[documentation](https://docs.rs/nhs-number/)**
•
**[source](https://github.com/joelparkerhenderson/nhs-number-using-rust)**
•
**[crate](https://crates.io/crates/nhs-number)**
•
**[spec](spec.md)**
•
**[llms.txt](https://raw.githubusercontent.com/joelparkerhenderson/nhs-number-using-rust/refs/heads/main/llms.txt)**
•
**[email](mailto:joel@joelparkerhenderson.com)**

A National Health Service (NHS) Number is a unique identifier allocated in a
shared numbering scheme to registered users of the public health services in
**England** and the **Isle of Man**.

The NHS Number is the key to identifying patients — especially when
delivering safe care across provider organisations — and is required in all
new software deployed within NHS organisations.

References:

* [National Health Service (NHS)]https://en.wikipedia.org/wiki/National_Health_Service

* [NHS Number]https://en.wikipedia.org/wiki/NHS_number

## What this crate does

| Capability                          | API                                              |
| ----------------------------------- | ------------------------------------------------ |
| Wrap ten digits in a value type     | `NHSNumber { digits: [i8; 10] }`                 |
| Parse `"DDDDDDDDDD"` or `"DDD DDD DDDD"` | `NHSNumber::from_str` / `"…".parse()`        |
| Format as `"DDD DDD DDDD"`          | `Display`, `Into<String>`                        |
| Read or recompute the check digit   | `check_digit`, `calculate_check_digit`           |
| Validate the check digit            | `validate_check_digit`                           |
| Use the reserved testable range     | `TESTABLE_MIN`, `TESTABLE_MAX`, `testable_random_sample` |
| Order, equality, serialise          | `Ord`, `Eq`, `serde::{Serialize, Deserialize}`   |

For the full public surface, see [`docs/api/index.md`](docs/api/index.md).
For the canonical behavioural specification, see [`spec.md`](spec.md).

## Install

```sh
cargo add nhs-number
```

Or in `Cargo.toml`:

```toml
[dependencies]
nhs-number = "1"
```

## Syntax

The current system uses a ten-digit number in the `3 3 4` format, with the
final digit being an error-detecting checksum. An example: `943 476 5919`.

## Ranges

Currently issued ranges:

* `300 000 000``399 999 999` (England)

* `400 000 000``499 999 999` (England, Isle of Man)

* `600 000 000``799 999 999` (England, Isle of Man)

Unavailable (reserved for other systems):

* `320 000 001``399 999 999` (Northern Irish system)

* `010 100 0000``311 299 9999` (CHI numbers in Scotland)

Testable (valid by the checksum algorithm, never issued):

* `999 000 0000``999 999 9999`

For the full table and guidance on choosing test fixtures, see
[`docs/ranges/index.md`](docs/ranges/index.md).

## Checksum

The checksum is calculated by multiplying each of the first nine digits by
`11 − position`. Using `943 476 5919` as an example:

* The first digit (9) is multiplied by 10.

* The second digit (4) is multiplied by 9.

* And so on until the ninth digit (1) is multiplied by 2.

* The products are summed. Here: (9×10) + (4×9) + (3×8) + (4×7) + (7×6) +
  (6×5) + (5×4) + (9×3) + (1×2) = 299.

* The remainder when dividing by 11 yields a number in 0–10 — here, 2.

* This is subtracted from 11 to give the checksum in 1–11 — here, 9, which
  becomes the last digit of the NHS Number.

* A checksum of 11 is represented by 0 in the final NHS Number. A checksum
  of 10 means the number is **not valid**.

For two fully worked examples and the in-crate entry points, see
[`docs/checksum/index.md`](docs/checksum/index.md).

## Example

```rust
use nhs_number::NHSNumber;
use std::str::FromStr;

// A test-safe NHS Number drawn from the reserved testable range.
let input = "999 100 0003";

// Parse a string into an NHSNumber.
let nhs_number = NHSNumber::from_str(input).unwrap();

// Validate the check digit.
let is_valid: bool = nhs_number.validate_check_digit();
assert!(is_valid);

// Round-trip back to the canonical string form.
let displayed: String = nhs_number.to_string();
assert_eq!(displayed, input);
```

For a tutorial walk-through, see [`docs/usage/index.md`](docs/usage/index.md).
For runnable programs, see [`examples/`](examples/).

## Documentation map

| Where                                              | What                                      |
| -------------------------------------------------- | ----------------------------------------- |
| [`spec.md`]spec.md                               | Canonical behavioural specification.      |
| [`docs/usage/index.md`]docs/usage/index.md       | Tutorial-style walk-through.              |
| [`docs/api/index.md`]docs/api/index.md           | Full public API reference.                |
| [`docs/checksum/index.md`]docs/checksum/index.md | Check-digit algorithm with worked examples. |
| [`docs/ranges/index.md`]docs/ranges/index.md     | Issued, reserved, and testable ranges.    |
| [`docs/faq/index.md`]docs/faq/index.md           | Frequently asked questions.               |
| [`examples/`]examples/                           | Runnable `cargo run --example <name>` programs. |
| [`AGENTS.md`]AGENTS.md                           | Guidance for AI coding agents.            |

## License

Multi-licensed under MIT OR Apache-2.0 OR GPL-2.0 OR GPL-3.0 OR
BSD-3-Clause. Pick whichever fits your project.