作ったもの
QR Scanner — https://sen.ltd/portfolio/qr-scanner/
- QR コードエンコーダをゼロから実装(バージョン 1-10、バイトモード、EC レベル L/M/Q/H)
- 色・サイズ・誤り訂正レベルのカスタマイズ
- PNG ダウンロード
- ブラウザのカメラでスキャン(BarcodeDetector API)
- URL 自動検出
vanilla JS、ゼロ依存、ビルド不要。node --test で 62 ケース。
エンコードの 6 ステップ
- データエンコード(モードインジケータ + 長さヘッダ + バイト列)
- Reed-Solomon 誤り訂正(GF(256) 上)
- マトリクス構築(ファインダ・タイミング・アライメントパターン配置)
- データ配置(ジグザグトラバース)
- マスキング(8 パターンをペナルティスコアで評価)
- フォーマット情報(EC レベル + マスク、BCH 保護付き)
GF(256) の Reed-Solomon
プリミティブ多項式 0x11d(x⁸+x⁴+x³+x²+1)は QR 規格で指定されている。これを間違えると「見た目は正しいが解読できない」コードが生成される。
function gfMul(a, b) {
if (a === 0 || b === 0) return 0;
return GF_EXP[(GF_LOG[a] + GF_LOG[b]) % 255];
}
対数テーブルで乗算を O(1) 化。
8 マスクパターン
データ配置後に 8 種類のマスクを適用。スキャナを混乱させる構成(大ブロックの同色モジュール、ファインダパターンに似た構成など)を避けるため、4 つのペナルティルールでスコアリングし最小のものを選ぶ。
スキャナ側
const detector = new BarcodeDetector({ formats: ['qr_code'] });
const barcodes = await detector.detect(videoElement);
Chrome / Edge はネイティブ対応。Safari / Firefox は未対応なのでフォールバックメッセージを出す。
シリーズ
100+ 公開ポートフォリオ シリーズの #43 です。
- 📦 リポジトリ: https://github.com/sen-ltd/qr-scanner
- 🌐 デモ: https://sen.ltd/portfolio/qr-scanner/
- 🏢 会社: https://sen.ltd/
