/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { ImplementationError } from "#MatterError.js"; /** * Verhoeff algorithm to compute a checksum. * * @see {@link https://en.wikipedia.org/wiki/Verhoeff_algorithm} */ export class Verhoeff { // This is rarely used so no need to keep those constants in memory private readonly multiply = [ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], ]; private readonly inverse = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]; private readonly permute = [ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], [7, 0, 4, 6, 9, 1, 3, 2, 5, 8], ]; computeChecksum(digits: string) { const { length } = digits; let checksum = 0; for (let i = 1; i <= length; i++) { const digit = Number.parseInt(digits[length - i]); if (Number.isNaN(digit)) { throw new ImplementationError("Invalid verhoeff checksum digit"); } checksum = this.multiply[checksum][this.permute[i % 8][digit]]; } return this.inverse[checksum]; } }