45 lines
1 KiB
TypeScript
45 lines
1 KiB
TypeScript
import { Controller } from '@nestjs/common';
|
|
import assert from 'assert';
|
|
|
|
@Controller()
|
|
export class EANService {
|
|
// https://en.wikipedia.org/wiki/International_Article_Number#Calculation_of_checksum_digit
|
|
calcChecksum(id: string) {
|
|
assert(id.length === 12);
|
|
let sum = id
|
|
.split('')
|
|
.map((d) => parseInt(d, 10))
|
|
.map((d, i) => d * (i % 2 === 0 ? 1 : 3))
|
|
.reduce((s, d) => s + d, 0);
|
|
while (sum > 10) {
|
|
sum -= 10;
|
|
}
|
|
return 10 - sum;
|
|
}
|
|
|
|
isValid(ean: string) {
|
|
ean = ean.trim();
|
|
assert(/^\d{13}$/.test(ean));
|
|
return this.calcChecksum(ean.slice(0, 12)) === parseInt(ean[12], 10);
|
|
}
|
|
|
|
toID(ean: string) {
|
|
ean = ean.trim();
|
|
assert(/^\d{12,13}$/.test(ean));
|
|
if (ean.length === 12) {
|
|
// it already is an ID
|
|
return ean;
|
|
}
|
|
if (!this.isValid(ean)) {
|
|
throw new Error(`Invalid EAN: "${ean}"`);
|
|
}
|
|
return ean.slice(0, 12);
|
|
}
|
|
|
|
fromID(id: string) {
|
|
id = id.trim();
|
|
assert(/^\d{12}$/.test(id));
|
|
return id + this.calcChecksum(id);
|
|
}
|
|
}
|