Menjawab masalah langsung
Bug pada qr-swastika-avoider v0.1.0 membuat generator QR menghasilkan pola swastika ketika modul diisi dengan data mask. Penjelasan berikut menguraikan penyebabnya, langkah debug praktis, perbaikan konkret, dan cara memvalidasi QR yang benar.
Gejala nyata yang terlihat
Pengguna melaporkan bahwa output QR tampak memiliki garis-garis berulang menyerupai swastika pada bagian tengah. QR tetap dapat dibaca oleh beberapa pemindai, tapi pola tersebut melanggar tujuan crate. Visual inspection menunjukkan area pusat yang kosong diisi oleh pola simetri dengan modul berwarna gelap dan terang yang tidak mengikuti logika mask standar.
Root cause: pengisian modul dan algoritme masking
Bagian pengisian modul yang bermasalah
Crate mengimplementasikan algoritme mask manual untuk mencegah pola tertentu. Observasi kode menunjukkan bahwa loop pengisian modul menggunakan iterasi dua dimensi dan kondisi langsung menjumlahkan offset tanpa memvalidasi apakah modul sudah ditetapkan. Ketika data frame berada dekat dengan tengara struktur (finder atau alignment), logika fallback mengeksekusi dua kali karena tidak menghentikan iterasi setelah menetapkan modul.
for y in 0..size { for x in 0..size { if needs_fill(x, y) { let bit = bitstream.next().unwrap_or(false); set_module(x, y, bit); } } }Set_module sendiri memeriksa bounding box tetapi tidak menyertakan flag "sudah diisi" sehingga mask yang sama kembali diproses, menciptakan pola berulang.
Masking yang memicu pola swastika
Masking diimplementasikan setelah pengisian data dengan fungsi yang mengubah modul berdasarkan fungsi matematika modul 2. Kombinasi iterasi mask yang tidak sinkron dengan data bit dan penanganan "balik" menyebabkan area pusat mengalami isian berlapis. Karena mask dieksekusi di atas data tanpa referensi ke modul yang sebelumnya sudah dimodifikasi, sistem menulis ulang nilai modul secara deterministik menghasilkan swastika.
Langkah deteksi
- Mode debug operasi: Jalankan crate dengan fitur logging (misalnya via
RUST_LOG=qr_swastika_avoider=debug) untuk melihat nilai modul per koordinat. - Sampling visual: Cetak matriks bit hasil sebelum dan sesudah masking, fokus pada area 3x3 di sekitar pusat.
- Logging iterasi: Catat koordinat setiap kali
set_moduledipanggil; pastikan tidak ada duplikasi tulisan untuk koordinat sama pada tubuh data.
Dengan langkah-langkah ini, tim menemukan bahwa koordinat target dibaca dua kali: sekali saat mengisi data, sekali lagi saat mask tanpa pengecekan status.
Perbaikan kode
Solusinya menambahkan struktur status modul yang mencatat apakah posisi sudah diisi, serta menyelaraskan urutan mask agar hanya memodifikasi modul yang sudah terisi dan bukan ruang kosong. Berikut patch inti:
struct ModuleState { value: bool, filled: bool }Setelah itu, pengisian data menjadi:
if needs_fill(x, y) && !modules[y][x].filled { let bit = bitstream.next().unwrap_or(false); modules[y][x] = ModuleState { value: bit, filled: true }; }Masking kini memverifikasi flag filled sebelum menukar nilai:
if modules[y][x].filled && should_apply_mask(x, y) { modules[y][x].value ^= true; }Perubahan ini memastikan mask tidak menulis ulang modul yang belum terisi sekaligus menjaga satu kali proses per koordinat.
Validasi ulang: tes unit dan integrasi
Setelah patch, buat tes unit yang memverifikasi matrix modul untuk ukuran khas (misal 25x25) dan memastikan pola tidak berubah menjadi swastika. Integrasi dengan sampel data nyata membantu memastikan pemindai QR membaca data dengan mask standar.
Contoh validasi: generate QR untuk konten "https://example.com" lalu bandingkan hash matriks sebelum dan sesudah patch, serta jalankan pemindai eksternal untuk memastikan kembalinya pola standar.
Mitigasi dan pelajaran teknis
- Pembatasan akses modul: Tangani status pengisian per modul agar tiap koordinat hanya diubah oleh satu proses.
- Logging posisi: Sertakan koordinat x/y dalam log debug untuk menelusuri penulisan ganda.
- Periksa mask di luar fase publik: Implementasikan validasi hasil mask untuk memastikan tidak menghasilkan pola deterministik yang tidak diinginkan.
- Automasi sampling visual: Simpan matriks saat debug untuk memvisualisasikan pola abnormal lebih awal.
Pelajaran penting: ketika bekerja dengan QR generator custom, setiap perubahan state harus dijaga deterministikitasnya agar mask tidak menimpa data yang sudah diatur. Dengan pendekatan ini, developer bisa menghindari kembali pola tak diinginkan pada QR di masa depan.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!