Kỹ thuật đọc mã QR mà không cần máy tính
(qr.blinry.org)- Tóm tắt quy trình từng bước để giải mã mã QR bằng tay, từ cấu trúc module 21×21 của phiên bản 1 cho đến gỡ mặt nạ và chuyển đổi byte
- Các vùng đặc biệt như finder pattern, timing pattern, thông tin định dạng và quiet zone là cần thiết để nhận diện, nhưng phải bỏ qua khi đọc dữ liệu thực tế
- Sau khi kiểm tra mẫu mặt nạ và mức sửa lỗi từ thông tin định dạng, dữ liệu được khôi phục bằng cách đảo các module của mã QR tại những vị trí module đen của mặt nạ
- Bắt đầu từ góc dưới bên phải, đọc theo thứ tự zigzag từng cặp hai cột; trong chế độ Byte, các nhóm 8 bit sau phần độ dài 8 bit sẽ trở thành byte ký tự
- Không cần giải thủ công cả vùng sửa lỗi; với mã QR đơn giản, chỉ cần đọc số byte mà trường độ dài chỉ ra rồi đổi theo bảng ASCII là có thể giải mã
Chuẩn bị mã QR để đọc bằng tay
- Có thể chuẩn bị mã QR luyện tập theo ba cách
- Nhập văn bản bất kỳ để cập nhật mã QR được giải thích bên dưới
- Học cách đọc bằng cách quét một mã QR có sẵn bằng camera
- Luyện tập với các từ tiếng Anh ngẫu nhiên; từ sẽ không được hiển thị nên có thể dùng để rèn luyện
- Mã QR ví dụ có kích thước 21×21 module
- Trong mã QR, đơn vị tương ứng với pixel được gọi là module
- Kích thước mã QR được phân biệt bằng version
- Phiên bản nhỏ nhất là 21×21 module
- Mỗi phiên bản tiếp theo tăng kích thước mỗi cạnh thêm 4
- Mã QR 21×21 module là phiên bản 1
Các vùng đặc biệt cần bỏ qua trong mã QR
- Finder pattern giúp máy quét nhận diện mã QR trước tiên
- Các dòng trống quanh finder pattern phải được bỏ qua khi đọc nội dung
- Mã QR phiên bản 1 không có alignment pattern
- Alignment pattern là mẫu bổ sung giúp máy quét đọc mã QR chính xác
- Timing pattern là hai dòng trong đó các module đen và trắng luôn xuất hiện xen kẽ, giúp máy quét đọc mã QR chính xác
- Thông tin định dạng quyết định mẫu mặt nạ và mức sửa lỗi
- Có thông tin định dạng theo chiều dọc và theo chiều ngang
- Timing pattern đi cắt ngang cả hai dòng này
- Quiet zone là viền trắng xung quanh mã QR
- Giúp máy quét xác định điểm bắt đầu và kết thúc của mã QR
Gỡ mẫu mặt nạ
- Mã QR sử dụng mặt nạ (mask) để tránh các mảng đen hoặc trắng quá lớn
- Có tổng cộng 8 lựa chọn mặt nạ
- Trong ví dụ, đọc module đen là 1 và module trắng là 0 để kiểm tra các bit của mẫu mặt nạ
- Các bit ví dụ là số nhị phân
110 110tương ứng với số thập phân 6
- Các bit ví dụ là số nhị phân
- Mỗi loại mặt nạ có một mẫu được định nghĩa sẵn
- Mẫu của mã QR ví dụ trông giống như một phần của cầu vồng đen trắng
- Sau khi lặp lại việc đặt mặt nạ lên vùng dữ liệu, đảo module của mã QR tại mọi vị trí là module đen trong mặt nạ
- Có cung cấp DIY zine chứa cheat sheet cho mọi loại mặt nạ
- Có thể tham khảo hình hướng dẫn này để xem ví dụ gấp thành cuốn sách nhỏ
Chế độ mã hóa và thứ tự đọc
- Việc giải mã nội dung bắt đầu bằng cách kiểm tra chế độ mã hóa
- Thông tin mã hóa luôn nằm ở góc dưới bên phải
- Chế độ mã hóa cũng phải được gỡ bằng cách áp dụng mặt nạ trước
- Trong ví dụ, xem cheat sheet và XOR hai ô
- Các chế độ mã hóa gồm Numeric, Alphanumeric, Byte, ECI, Kanji, v.v.
- Chế độ mã hóa của mã QR ví dụ là Byte(4)
- Nội dung bắt đầu từ góc dưới bên phải
- Đọc đi lên theo zigzag giữa hai cột
- Sau đó đi xuống theo zigzag ở hai cột kế tiếp bên trái
- Luôn bỏ qua mọi vùng đặc biệt
Giải mã độ dài và byte
- 4 bit đầu tiên là chế độ mã hóa
- Trong chế độ Byte, 8 bit tiếp theo chỉ định độ dài nội dung
- Sau đó, mỗi 8 bit trở thành một byte nội dung
- Thông tin độ dài cũng phải được gỡ bằng cách áp dụng mặt nạ
- Thông tin độ dài sau khi gỡ mặt nạ trong ví dụ là
00001100- Là
12ở hệ thập phân - Nghĩa là tổng độ dài nội dung là 12 byte
- Là
- Byte đầu tiên sau khi gỡ mặt nạ là
01001000- Là
0x48ở hệ thập lục phân - Ký tự ASCII tương ứng là
H
- Là
- Byte thứ hai sau khi gỡ mặt nạ là
01100101- Là
0x65ở hệ thập lục phân - Ký tự ASCII tương ứng là
e
- Là
- Các byte còn lại được để làm bài luyện tập; có thể dừng khi đã đọc đủ số ký tự mà trường độ dài đã đọc trước đó chỉ ra
Bảng ASCII và sửa lỗi
- Có thể dùng bảng ASCII để chuyển giá trị thập lục phân thành ký tự
- Chữ thường bắt đầu với
aở0x61và kết thúc vớizở0x7A- Có thể tìm ký tự ở giữa bằng cách đếm
- Không phải mọi vùng còn lại đều là nội dung
- Mã QR cũng bao gồm sửa lỗi (error correction)
- Cho phép đọc mã QR ngay cả khi một phần bị hỏng, mờ hoặc thiếu
- Sửa lỗi được tạo ra bằng toán học, nhưng không được xử lý trong mục tiêu đọc bằng tay
- Sau khi nắm được quy trình giải mã mã QR đơn giản bằng tay, có thể luyện tập các từ tiếng Anh ngắn bằng nút mã ngẫu nhiên, hoặc quét mã QR thật bằng nút Scan code
- Mã nguồn nằm trên Codeberg
- Đặc biệt hoan nghênh PR giải thích chế độ mã hóa UTF-8
1 bình luận
Các ý kiến trên Hacker News
Vào cuối thập niên 90 hoặc đầu những năm 2000, tôi muốn chuyển nội dung đĩa Atari 8-bit sang PC
Tôi biết đến cáp và phần mềm SIO2PC để nối cổng SIO của Atari với cổng serial của PC, nhưng lúc đó tôi không có đủ kỹ năng điện tử để tự làm
Cuối cùng tôi viết một chương trình Basic trên Atari để đọc đĩa theo từng sector, vẽ dữ liệu lên màn hình bằng các pixel 4 màu cỡ lớn của graphics mode 3, nối Atari vào TV card của PC, rồi viết chương trình Delphi liên tục chụp screenshot và giải mã dữ liệu
Vì các sector trống làm lệch việc hiệu chỉnh vị trí pixel, tôi thêm cả mẫu mask, checksum và địa chỉ sector; bằng cách đó tôi đã chuyển được toàn bộ nội dung các đĩa sang PC
Đến giờ tôi vẫn xem đây là thành tựu kỹ thuật lớn nhất của mình
Khoảng 10 năm sau, tôi tạo ra một chương trình SIO2PC tên là AspeQt; bản fork cộng đồng mới hơn là RespeQt hiện vẫn là công cụ được dùng nhiều nhất trong lĩnh vực này, và trên AtariAge cũng có một sub-forum riêng: https://forums.atariage.com/forum/184-respeqt-sio2pc-softwar...
Nghe nói họ cho đèn nền LCD nhấp nháy theo mẫu bit rồi dùng camera để đọc dữ liệu đó: https://mastodon.social/@bagder/111538350617290554
Phần giải thích rằng “sửa lỗi là toán phức tạp nên không xét khi đọc bằng tay” cần chi tiết hơn một chút
Tôi hiểu phần toán là khó, nhưng vẫn tò mò liệu dữ liệu sửa lỗi được gắn ở cuối, sau mỗi byte, hay chèn vào giữa
Tôi cũng muốn biết với một mã QR không bị hỏng, dù có sửa lỗi thì có thể bỏ qua phần toán và đọc bằng tay được không
% 10để ra một số từ 0 đến 9Vì vậy có xác suất 1/10 là dữ liệu sai nhưng tình cờ checksum vẫn đúng; dù sao thì chữ số cuối cũng không quan trọng đối với ID mã vạch duy nhất thực sự của sản phẩm
Có lần mã vạch của một món tôi đem trả ở Home Depot bị rách làm mất chữ số checksum; tôi cuống cuồng cố tính nó trước khi nhân viên tra cứu thủ công, nhưng cuối cùng nhân viên vẫn thắng, và tôi không thể quên được
https://www.gs1.org/services/how-calculate-check-digit-manua...
https://www.simplybarcodes.com/barcode_check_digit_calculato...
Sau đó, tùy kích thước và mức sửa lỗi, bitstream được chia thành các block, dữ liệu sửa lỗi cho từng block được tính toán, rồi các block được interleave
Vì vậy phương pháp này sẽ thất bại với QR phiên bản trên 5 bất kể mức sửa lỗi, và cũng thất bại ở phiên bản 3~5 nếu mức sửa lỗi cao
Trên thực tế, tùy loại thông tin mà dùng hai mã hơi khác nhau là Reed-Solomon và BCH
https://www.quaxio.com/an_artisanal_qr_code.html
Các bài liên quan:
Decoding small QR codes by hand (2012) - https://news.ycombinator.com/item?id=36173441 - tháng 6/2023, 69 bình luận
How a QR code works - https://news.ycombinator.com/item?id=32837565 - tháng 9/2022, 114 bình luận
Creating a QR Code step by step - https://news.ycombinator.com/item?id=24119124 - tháng 8/2020, 41 bình luận
Creating a QR Code step by step - https://news.ycombinator.com/item?id=18360847 - tháng 11/2018, 34 bình luận
Bản thân bài viết đã rất hay, nhưng việc mọi hình minh họa đều được tạo động theo giá trị đầu vào còn ấn tượng hơn
Phần giải thích cách đọc mã QR rất tốt; còn nếu muốn một bài giải mã mã vạch một chiều phổ biến như UPC thì bài này cũng ổn:
https://scanbot.io/blog/how-do-barcodes-work/
Khoảng 10 năm trước tôi từng thử đọc mã QR bằng tay nhưng đã bỏ cuộc vì mẫu mặt nạ
Ngay cả trước khi xác định được kiểu dữ liệu, vẫn phải áp dụng mẫu mặt nạ bằng XOR
Tôi thắc mắc mẫu mặt nạ này thực sự giúp ích đến mức nào cho các trình đọc mã QR thực tế
Tháng trước tôi đã tìm hiểu cấu hình sửa lỗi tối ưu, nhưng với trường hợp không bị hư hại như một ma trận nguyên vẹn hiển thị trên màn hình thì câu trả lời là “không có”, và không dễ để tìm ra kết luận này
Tôi không tìm được tài liệu so sánh nhiều cấu hình và cách triển khai quét trong môi trường thực tế; tôi cũng tự hiển thị các mã QR nhỏ trên màn hình với nhiều mức sửa lỗi rồi lắc camera để mô phỏng vấn đề đọc, nhưng không thấy khác biệt đáng kể giữa các cấu hình
Đã có ít nhất bốn dấu căn chỉnh, thêm cả vùng lề lớn và mẫu định thời, nên tôi tự hỏi liệu việc không có mặt nạ khiến xuất hiện các mảng trắng có thực sự tạo ra khác biệt lớn không
Lý do thứ hai khiến tôi bỏ ý định đọc QR bằng mắt là vì thường bên dưới đã có URL viết dưới dạng văn bản thay thế; sau này tôi cũng gặp vài trường hợp không có văn bản thay thế, nhưng rất hiếm
Nếu không dùng thì thông điệp chiếm ít không gian hơn và QR nhỏ hơn
Nếu phải vừa trong một không gian cố định như khi in nhãn dán, có thể làm các pixel lớn hơn về mặt vật lý, và với việc đọc ổn định thì pixel lớn hơn hữu ích hơn sửa lỗi
Tùy độ dài thông điệp, có những trường hợp có thể tăng mức sửa lỗi mà không làm thay đổi kích thước QR cuối cùng; khi đó coi như được cả hai
Nó dành cho những người nhét toàn bộ một URL đầy tham số theo dõi vào mã phiên bản 25, 117x117, dán lên biển hiệu lớn, rồi muốn dữ liệu vẫn sống sót dù có phân chim rơi xuống hay ai đó dán nhãn lên
Đó là thí nghiệm để xem có thể in nhỏ đến mức nào mà vẫn phát hiện được, và có vẻ như lý do là vì từng pixel riêng lẻ trở nên lớn hơn, như bình luận bên cạnh đã nói
Video giải mã QR được đăng khoảng 10 năm trước: https://www.youtube.com/watch?v=KA8hDldvfv0 (20 phút)
Tôi cũng có một trang web tương tác hướng dẫn tạo mã QR từng bước. Về cơ bản đó là quy trình ngược lại: https://www.nayuki.io/page/creating-a-qr-code-step-by-step
Tôi bắt đầu tò mò về sửa lỗi, và nghe nói mã QR có thể được thiết kế với tỷ lệ có thể khôi phục khác nhau từ 7% đến 30%
Thú vị: https://docs.beaconstac.com/en/articles/6018654-what-is-erro...
Shannon đã tìm ra giới hạn lý thuyết vào giữa thế kỷ 20, nhưng không ai biết cách đạt tới giới hạn đó
Đến thập niên 1990, khi bằng sáng chế mã turbo bất ngờ tiến gần đến giới hạn ấy, giới học thuật đã phản ứng kiểu khó mà tin nổi
Tất nhiên, chính nhờ những công nghệ như vậy mà mạng di động nhanh và đáng tin cậy mới trở nên khả thi
Trong một câu đố phái sinh của Mystery Hunt 2023, có bài yêu cầu phải giải mã thủ công một mã QR bị hỏng đến mức sửa lỗi cũng không khôi phục được
Tôi đã xem hết các hướng dẫn được nhắc đến trong phần bình luận này; chúng hữu ích nhưng chưa thật sự xuất sắc
Vì vậy tôi thấy việc có thêm các bài viết chi tiết hơn như thế này là điều tốt, và bài này chắc chắn trông rất hoàn thiện
Nếu tò mò thì câu đố ở đây, phần giải mã QR nằm ở nửa sau: https://puzzles.mit.edu/2023/abcde.puzzlefactory.place/puzzl...
Xem Wikipedia thì thấy mã QR được một nhà sản xuất linh kiện ô tô Nhật Bản phát minh vào năm 1994 để dán nhãn linh kiện ô tô
Tôi tự hỏi nếu nó được phát minh ngày nay thì liệu có thể cải tiến hơn không
Có thể làm nhỏ hơn hoặc dễ đọc hơn không?
Năm 1994, mã vạch đã có ở khắp nơi, nhưng điều đó không ngăn mã QR nổi lên
Có lẽ cũng không còn nhiều chỗ để cải tiến. Trừ khi thay đổi mạnh khái niệm, chẳng hạn chuyển sang thứ như NFC