概要
以下は ISBN のバーコード読み取り誤差を防ぐためのメソッドである。
現状、3 回連続で同じ値だった場合に成功としている。これでは読み取りに時間がかかるし、正確でないこともある。
精度の向上と高速化を図り、チェックディジットによる誤差防止策に変更したい。
Quagga.onDetected(function (result) {
if (DetectedCode == result.codeResult.code) {
DetectedCount++;
} else {
DetectedCount = 0;
DetectedCode = result.codeResult.code;
}
if (DetectedCount >= 3) {
console.log(result.codeResult.code);
isbn.value = result.codeResult.code;
DetectedCode = "";
DetectedCount = 0;
}
});
値について
- 値は全 13 桁を期待する。
- チェックディジットは読み取られた値の最後の桁であり、「左端から奇数番目のケタを 1 倍、偶数番目のケタを 3 倍したものの総和」である。これが 10 で割り切れれば正しいコード、割り切れなければ誤ったコードと判定される。
解決策
- 値は slice()メソッドでチェックディジットとバーコードディジットを別々に抽出している。
- 奇数桁と偶数桁の和に 3 を掛けたものを for ループで計算する。
- 和とチェックディジットの和が 10 で割り切れるかどうかで、バーコードが正しいかどうかを判断する。
- バーコードが正しい場合、検出されたコードを記録し、isbn の値を検出されたコードに設定する。
- そうでない場合は、エラーメッセージを記録する。
Quagga.onDetected(function (result) {
const detectedCode = result.codeResult.code;
if (detectedCode.length != 13) {
//桁があっているか確認する
console.log("Barcode error: length " + detectedCode);
return;
}
const checkDigit = parseInt(detectedCode.slice(-1)); // バーコードからチェックディジットを抽出する
const barcodeDigits = detectedCode.slice(0, -1).split(""); // チェックディジットを除いたバーコードの桁を抽出する
let sum = 0;
for (let i = 0; i < barcodeDigits.length; i++) {
if (i % 2 === 0) {
sum += parseInt(barcodeDigits[i]); // 奇数桁を足す
} else {
sum += 3 * parseInt(barcodeDigits[i]); // 偶数桁を3倍する
}
}
if ((sum + checkDigit) % 10 === 0) {
// バーコードが正しいか確認する
console.log(detectedCode);
isbn.value = detectedCode;
} else {
console.log("Barcode error: " + detectedCode);
}
});