UNPKG

@nuintun/qrcode

Version:

A pure JavaScript QRCode encode and decode library.

55 lines (51 loc) 1.83 kB
/** * @module QRCode * @package @nuintun/qrcode * @license MIT * @version 5.0.2 * @author nuintun <nuintun@qq.com> * @description A pure JavaScript QRCode encode and decode library. * @see https://github.com/nuintun/qrcode#readme */ import { Polynomial } from './Polynomial.js'; import { QR_CODE_FIELD_256 } from './GaloisField.js'; /** * @module Encoder */ function buildGenerator(field, generators, degree) { const { length } = generators; if (degree >= length) { const { generator } = field; let lastGenerator = generators[length - 1]; for (let i = length; i <= degree; i++) { const coefficients = new Int32Array([1, field.exp(i - 1 + generator)]); const nextGenerator = lastGenerator.multiply(new Polynomial(field, coefficients)); generators.push(nextGenerator); lastGenerator = nextGenerator; } } return generators[degree]; } class Encoder { #field; #generators; constructor(field = QR_CODE_FIELD_256) { this.#field = field; this.#generators = [new Polynomial(field, new Int32Array([1]))]; } encode(received, ecLength) { const dataBytes = received.length - ecLength; const infoCoefficients = new Int32Array(dataBytes); const generator = buildGenerator(this.#field, this.#generators, ecLength); infoCoefficients.set(received.subarray(0, dataBytes)); const base = new Polynomial(this.#field, infoCoefficients); const info = base.multiplyByMonomial(ecLength, 1); const [, remainder] = info.divide(generator); const { coefficients } = remainder; const numZeroCoefficients = ecLength - coefficients.length; const zeroCoefficientsOffset = dataBytes + numZeroCoefficients; received.fill(0, dataBytes, zeroCoefficientsOffset); received.set(coefficients, zeroCoefficientsOffset); } } export { Encoder };