UNPKG

test-nino

Version:

The fastest NINO (UK National Insurance number) generator and validator. Generates and validates UK NI numbers to NIM39110 specifications on Gov.uk.

171 lines (136 loc) 8.89 kB
# test-nino <p> <img src="https://badgen.net/npm/v/test-nino" /> <img src="https://badgen.net/bundlephobia/dependency-count/test-nino" /> <img src="https://badgen.net/bundlephobia/minzip/test-nino" /> <img src="https://badgen.net/npm/dt/test-nino" /> <img src="https://badgen.net/github/last-commit/Tom-Hudson/test-nino" /> <img src="https://badgen.net/npm/license/test-nino" /> <a href="https://codecov.io/github/Tom-Hudson/test-nino" > <img src="https://codecov.io/github/Tom-Hudson/test-nino/branch/master/graph/badge.svg?token=XEMCXN2P7A"/> </a> </p> The fastest NINO (UK National Insurance number) generator and validator. Generates and validates UK NI numbers to NIM39110 specifications on Gov.uk. `test-nino` is a performance focused and has zero dependencies. The [benchmarks](#benchmarks) speak for themselves. - [Getting Started](#getting-started) * [Install](#install) * [Import](#import) - [Available functions](#available-functions) * [random](#random) * [incremental](#incremental) * [validate](#validate) * [normalise](#normalise) - [Benchmarks](#benchmarks) - [What is a valid UK National Insurance number?](#what-is-a-valid-uk-national-insurance-number) - [How many valid UK National Insurance numbers are there?](#how-many-valid-uk-national-insurance-numbers-are-there) ## Getting Started ### Install You can install the [test-nino](https://www.npmjs.com/package/test-nino) package from npm: ``` npm i test-nino ``` ### Import ```js // ESM/TypeScript import * as testNino from 'test-nino'; // CommonJS const testNino = require('test-nino'); ``` ## Available functions ### random Used to generate a random NINO: ```js const nino = testNino.random(); // Returns a valid UK National Insurance number e.g. AA000000A ``` > Warning: it is not guaranteed that you couldn't generate the same NINO more than once using this method. If you require a unique NINO every time, I suggest you use the [incremental](#incremental) generator. ### incremental This method is best if you want to ensure you don't generate a duplicate NINO. This function utilises a [JavaScript Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator) to enumerate through all possible valid UK NI numbers `AA000000A-ZY999999D` (there are [1,492,000,000 in total](#how-many-valid-uk-national-insurance-numbers-are-there)). The generator will enumerate on prefix, number and then suffix. ```js // Create a generator instance const uniqueNiGenerator = testNino.incremental(); for(let i = 0; i <= 10000000; i++) { uniqueNiGenerator.next() // Returns the next instance from the generator // on the 1st iteration it will return { value: 'AA000000A', done: false } // on the 2nd iteration it will return { value: 'AA000000B', done: false } // ... // on the 10000000th iteration it will return { value: 'AC500000A', done: false } } ``` > The `done` property will only return `true` once all possible combinations have been enumerated. ### validate This function will validate the provided NINO and return an object which details which rules have passed or failed. > It is expected that the NINO is already without formatting etc. - you can use [`normalise`](#normalise) to prepare the NINO if required. ```js // A valid NINO testNino.validate("AB123456C"); // { // rules: { // type: true, // length: true, // prefix: true, // number: true, // suffix: true // }, // outcome: true // } // An invalid NINO testNino.validate(1); // { // rules: { // type: false, // }, // outcome: false // } ``` > The object returned will always have an `outcome` property but the function fails fast and so will only return a result for each tested element of the NINO. ### normalise This function will normalise NINOs, stripping whitespace and converting it to uppercase characters. ```js testNino.normalise('aa 00 00 00 a') // AA000000A testNino.normalise('BB 123456 B') // BB123456B ``` > This can be used as a primer for the [`validate`](#validate) function ## Benchmarks All benchmarks are ran using [benchmark.js](https://www.npmjs.com/package/benchmark) on Node v18.16.0. CommonJS imports are used for all packages to keep things fair. You can run the benchmarks yourself from the `benchmarks` folder. Results have been rounded to 3 significant figures to smooth out variances between runs and provide more comparable results. ### random `test-nino` is more than **2.6x faster** than the next fastest random NI number generator: | package | version | ops/sec | |------------------------------------------------------------------|---------|------------| | [fake-nino](https://www.npmjs.com/package/fake-nino) | 0.0.1 | 5,810,000 | | [random_uk_nino](https://www.npmjs.com/package/random_uk_nino) | 1.0.3 | 6,340,000 | | [avris-generator](https://www.npmjs.com/package/avris-generator) | 0.8.2 | 2,900,000 | | **test-nino** | latest | 17,000,000 | > Other packages use loops which go through the process of `Generate random NINO > is it valid? > no > repeat`, until a valid nino is given. This costs precious CPU time and [blocks the Node Event Loop](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/). `test-nino` is made different and instead stores the complete list of valid prefixes which are then picked at random. No loops result in consistent performance that is not guaranteed with other packages. ### validate `test-nino` is more than **14x faster** than the next fastest validate function when validating a valid nino: | package | version | valid (AA000000A) | invalid (A) | invalid (null) | invalid (AAX00000A) | invalid (AA00000XA) | |--------------------------------------------------------------------------------------------|---------|-------------------| -----------------| ---------------- | ------------------- | ------------------- | | [valid-nino](https://www.npmjs.com/package/valid-nino) | 1.0.0 | 34,000,000 | 84,600,000 | 64,100,000 | 75,200,000 | 27,000,000 | | [is-national-insurance-number](https://www.npmjs.com/package/is-national-insurance-number) | 1.0.0 | 42,800,000 | 1,030,000,000 | 1,030,000,000 | 80,000,000 | 33,000,000 | | [avris-generator](https://www.npmjs.com/package/avris-generator) | 0.8.2 | 4,190,000 | 232,000 (throws) | 105,000 (throws) | 230,000 (throws) | 230,000 (throws) | | **test-nino** | latest | 609,000,000 | 1,030,000,000 | 1,030,000,000 | 1,020,000,000 | 601,000,000 | > Most other packages rely on Regex patterns, the validate function in `test-nino` instead utilises indexed character lookups which are much faster. The function also fails fast, meaning even bigger gains for specific invalid scenarios. ## What is a valid UK National Insurance number? To cite the rules at the time of implementation from [Gov.uk](https://www.gov.uk/hmrc-internal-manuals/national-insurance-manual/nim39110): > A NINO is made up of 2 letters, 6 numbers and a suffix, which is always A, B, C, or D. > > It looks something like this: QQ 12 34 56 A > >All prefixes are valid except: > >* The characters D, F, I, Q, U, and V are not used as either the first or second letter of a NINO prefix. >* The letter O is not used as the second letter of a prefix. >* Prefixes BG, GB, KN, NK, NT, TN and ZZ are not to be used ## How many valid UK National Insurance numbers are there? First, let's consider the restrictions on the first two letters of the NINO prefix: * The characters D, F, I, Q, U, and V are not used as either the first or second letter of the prefix, so there are 20 possible choices for the first letter (A-Z excluding D, F, I, Q, U, and V) and 19 possible choices for the second letter (A-Z excluding D, F, I, Q, U, V, and O). * The prefixes BG, GB, KN, NK, NT, TN and ZZ are not to be used, so there are 20 x 19 - 7 = 373 possible combinations of the first two letters. Next, let's consider the restrictions on the final letter, which is the suffix: * The suffix can only be A, B, C, or D, so there are 4 possible suffixes. Finally, let's consider the six numbers in the NINO: * Each of the six numbers can have 10 possible values (0-9), so there are 10^6 (1 million) possible combinations of the six numbers. Putting this all together, the number of possible unique NINOs would be: 373 (for the first two letters) x 10^6 (for the six numbers) x 4 (for the final letter) = **1,492,000,000** possible NINOs.