Skip to content

Commit bda9b20

Browse files
fix: correct Reed-Solomon generator polynomial construction in QR encoder
The generator polynomial was built with coefficients in reversed order, causing wrong EC codewords and producing unreadable QR codes. Replaced the in-place accumulation loop with standard polynomial convolution that correctly multiplies (x + alpha^i) factors in descending degree order. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4a7a4e9 commit bda9b20

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

src/encoders/qr/reed-solomon.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ export function gfMultiply(a: number, b: number): number {
3030

3131
/** Generate error correction codewords for a data block */
3232
export function generateECCodewords(data: number[], ecCount: number): number[] {
33-
// Build generator polynomial
34-
const gen: number[] = Array.from({ length: ecCount + 1 }, () => 0);
35-
gen[0] = 1;
33+
// Build generator polynomial: gen[0] = leading coeff (x^ecCount), gen[ecCount] = constant
34+
// Polynomial is product of (x - alpha^i) for i = 0..ecCount-1
35+
let gen = new Uint8Array([1]);
3636
for (let i = 0; i < ecCount; i++) {
37-
// Multiply gen by (x - alpha^i)
38-
for (let j = gen.length - 1; j >= 1; j--) {
39-
gen[j] = gen[j - 1]! ^ gfMultiply(gen[j]!, GF_EXP[i]!);
37+
const factor = new Uint8Array([1, GF_EXP[i]!]);
38+
const newGen = new Uint8Array(gen.length + 1);
39+
for (let j = 0; j < gen.length; j++) {
40+
for (let k = 0; k < factor.length; k++) {
41+
newGen[j + k] ^= gfMultiply(gen[j]!, factor[k]!);
42+
}
4043
}
41-
gen[0] = gfMultiply(gen[0]!, GF_EXP[i]!);
44+
gen = newGen;
4245
}
4346

4447
// Polynomial division

0 commit comments

Comments
 (0)