list-decoder-qr 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- list_decoder_qr-0.1.0/MANIFEST.in +3 -0
- list_decoder_qr-0.1.0/PKG-INFO +162 -0
- list_decoder_qr-0.1.0/README.md +148 -0
- list_decoder_qr-0.1.0/list_decoder_qr.egg-info/PKG-INFO +162 -0
- list_decoder_qr-0.1.0/list_decoder_qr.egg-info/SOURCES.txt +15 -0
- list_decoder_qr-0.1.0/list_decoder_qr.egg-info/dependency_links.txt +1 -0
- list_decoder_qr-0.1.0/list_decoder_qr.egg-info/requires.txt +2 -0
- list_decoder_qr-0.1.0/list_decoder_qr.egg-info/top_level.txt +1 -0
- list_decoder_qr-0.1.0/pyproject.toml +15 -0
- list_decoder_qr-0.1.0/qr_list_decoder/__init__.py +101 -0
- list_decoder_qr-0.1.0/qr_list_decoder/matrix.py +1499 -0
- list_decoder_qr-0.1.0/qr_list_decoder/wu_core.cpp +1212 -0
- list_decoder_qr-0.1.0/qr_list_decoder/wu_qr.py +1817 -0
- list_decoder_qr-0.1.0/requirements.txt +9 -0
- list_decoder_qr-0.1.0/setup.cfg +4 -0
- list_decoder_qr-0.1.0/setup.py +37 -0
- list_decoder_qr-0.1.0/tests/test_decoder.py +123 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: list-decoder-qr
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Wu's list decoder for Reed-Solomon / QR codes over GF(2^8)
|
|
5
|
+
Author: Tejas
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Tejas423/List-Decoding-of-QR-codes
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: Pillow
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
|
|
15
|
+
# qr-list-decoder
|
|
16
|
+
|
|
17
|
+
**Wu's list decoder QR codes**
|
|
18
|
+
|
|
19
|
+
Completed as Master's Thesis Project (MTP) in the CSE Department at IIT Bombay.
|
|
20
|
+
|
|
21
|
+
This library implements Wu's list decoding algorithm, enabling error correction **beyond the standard decoding radius** of the code. It can recover QR codes with significantly more damage than standard decoders can handle.
|
|
22
|
+
|
|
23
|
+
Not only does it contain the advanced mathematical backend, but it also includes an end-to-end QR code pipeline (generating matrices, reading images, unmasking, and decoding).
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
**From PyPI (Recommended):**
|
|
28
|
+
```bash
|
|
29
|
+
pip install list-decoder-qr
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**From Source / Development:**
|
|
33
|
+
If you want to modify the code locally, clone the repository and install it in editable mode:
|
|
34
|
+
```bash
|
|
35
|
+
pip install .
|
|
36
|
+
# or for development
|
|
37
|
+
pip install -e .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## What You Can Do With This Library
|
|
43
|
+
|
|
44
|
+
Here are the main tasks you can perform with `qr-list-decoder`:
|
|
45
|
+
|
|
46
|
+
### Task 1: Read a QR Code from an Image File
|
|
47
|
+
If you have a picture of a QR code and you want to extract the hidden text from it:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from qr_list_decoder import decode_qr_image
|
|
51
|
+
|
|
52
|
+
# Pass the path to your image
|
|
53
|
+
result = decode_qr_image("my_scratched_qr.png")
|
|
54
|
+
|
|
55
|
+
if result.get('wu_success') or result.get('bm_success'):
|
|
56
|
+
print("Decoded Text:", result.get('wu_text') or result.get('bm_text'))
|
|
57
|
+
else:
|
|
58
|
+
print("Decoding failed:", result.get('error'))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Task 2: Batch Process a Whole Folder of Images
|
|
62
|
+
If you have a folder containing hundreds of QR code images and want to decode all of them at once:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from qr_list_decoder import decode_folder
|
|
66
|
+
|
|
67
|
+
# This will scan the folder, process every image, and print the results
|
|
68
|
+
decode_folder("./dataset_of_qr_codes")
|
|
69
|
+
```
|
|
70
|
+
*(You can also do this directly from the command line: `python qr_demo.py --folder ./dataset_of_qr_codes`)*
|
|
71
|
+
|
|
72
|
+
### Task 3: Generate a New QR Code Image
|
|
73
|
+
You can use the library to encode text and create your own QR code images:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from qr_list_decoder import qr_encode_text, get_best_qr_matrix, render_qr
|
|
77
|
+
|
|
78
|
+
# 1. Convert text to bytes (e.g., Version 2 QR)
|
|
79
|
+
data_bytes = qr_encode_text("Hi Tejas!", version=2)
|
|
80
|
+
|
|
81
|
+
# 2. Let the library calculate the ECC bytes and build the best 2D matrix
|
|
82
|
+
matrix, mask_used = get_best_qr_matrix(data_bytes, version=2, ecc_level='high')
|
|
83
|
+
|
|
84
|
+
# 3. Render the matrix into an image and save it!
|
|
85
|
+
img = render_qr(matrix, scale=10, fg=(0, 0, 0), bg=(255, 255, 255))
|
|
86
|
+
img.save("my_new_qr.png")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Task 4: Decode a Raw 2D Matrix
|
|
90
|
+
If you already extracted the binary grid yourself (or generated it) and want to bypass the image processing step:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from qr_list_decoder import decode_raw_matrix
|
|
94
|
+
|
|
95
|
+
# A 2D list or NumPy array where 1 is black and 0 is white.
|
|
96
|
+
my_matrix = [
|
|
97
|
+
[1, 1, 1, 1, 1, 1, 1, 0, 0, 1, ...],
|
|
98
|
+
[1, 0, 0, 0, 0, 0, 1, 0, 1, 1, ...],
|
|
99
|
+
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, ...],
|
|
100
|
+
# ... rest of the matrix rows
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
result = decode_raw_matrix(my_matrix)
|
|
104
|
+
if result.get('wu_success') or result.get('bm_success'):
|
|
105
|
+
print("Decoded Text:", result.get('wu_text') or result.get('bm_text'))
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Task 5: Byte-level Decoding
|
|
109
|
+
If you don't care about images or matrices, and just want to play with the underlying math:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from qr_list_decoder import rs_encode, wu_decode
|
|
113
|
+
|
|
114
|
+
# 1. Create a raw codeword
|
|
115
|
+
codeword = rs_encode(n=26, k=9, message=[72, 101, 108, 108, 111])
|
|
116
|
+
|
|
117
|
+
# 2. Simulate data corruption (flip random bytes)
|
|
118
|
+
corrupted = codeword.copy()
|
|
119
|
+
corrupted[2] ^= 255
|
|
120
|
+
corrupted[8] ^= 128
|
|
121
|
+
corrupted[14] ^= 42
|
|
122
|
+
|
|
123
|
+
# 3. Use Wu's algorithm to mathematically recover the original bytes!
|
|
124
|
+
candidates = wu_decode(n=26, k=9, received=corrupted)
|
|
125
|
+
print("Recovered bytes:", candidates[0])
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## API Reference
|
|
131
|
+
|
|
132
|
+
The library exposes the following high-level core API components. Please check the source code for more advanced mathematical helper functions.
|
|
133
|
+
|
|
134
|
+
| Function | Description |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `rs_encode(n, k, message)` | Encode a message into an RS(n, k) codeword |
|
|
137
|
+
| `rs_syndromes(n, k, received)` | Compute syndromes of a received word |
|
|
138
|
+
| `berlekamp_massey(syndromes)` | Run standard Berlekamp-Massey |
|
|
139
|
+
| `wu_decode(n, k, received)` | **Main math entry point** — list-decode a corrupted codeword |
|
|
140
|
+
| `decode_qr_image(img_path)` | Decode a QR code directly from an image file |
|
|
141
|
+
| `decode_raw_matrix(matrix)` | Decode a 2D array of 0s and 1s |
|
|
142
|
+
| `decode_folder(path)` | Batch process a folder of QR images |
|
|
143
|
+
|
|
144
|
+
## Dependencies
|
|
145
|
+
|
|
146
|
+
- Python ≥ 3.8
|
|
147
|
+
- NumPy
|
|
148
|
+
- Pillow (PIL)
|
|
149
|
+
- *Optional:* OpenCV (`opencv-python`) for robust perspective-unwarping on camera photos.
|
|
150
|
+
|
|
151
|
+
## Optional C++ Acceleration
|
|
152
|
+
|
|
153
|
+
The package includes an optional C++ backend (`wu_core`) built with pybind11 that provides a massive ~20x-50x speedup on hot-path polynomial operations. It is automatically used if compiled:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pip install pybind11
|
|
157
|
+
python setup.py build_ext --inplace
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# qr-list-decoder
|
|
2
|
+
|
|
3
|
+
**Wu's list decoder QR codes**
|
|
4
|
+
|
|
5
|
+
Completed as Master's Thesis Project (MTP) in the CSE Department at IIT Bombay.
|
|
6
|
+
|
|
7
|
+
This library implements Wu's list decoding algorithm, enabling error correction **beyond the standard decoding radius** of the code. It can recover QR codes with significantly more damage than standard decoders can handle.
|
|
8
|
+
|
|
9
|
+
Not only does it contain the advanced mathematical backend, but it also includes an end-to-end QR code pipeline (generating matrices, reading images, unmasking, and decoding).
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
**From PyPI (Recommended):**
|
|
14
|
+
```bash
|
|
15
|
+
pip install list-decoder-qr
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**From Source / Development:**
|
|
19
|
+
If you want to modify the code locally, clone the repository and install it in editable mode:
|
|
20
|
+
```bash
|
|
21
|
+
pip install .
|
|
22
|
+
# or for development
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## What You Can Do With This Library
|
|
29
|
+
|
|
30
|
+
Here are the main tasks you can perform with `qr-list-decoder`:
|
|
31
|
+
|
|
32
|
+
### Task 1: Read a QR Code from an Image File
|
|
33
|
+
If you have a picture of a QR code and you want to extract the hidden text from it:
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from qr_list_decoder import decode_qr_image
|
|
37
|
+
|
|
38
|
+
# Pass the path to your image
|
|
39
|
+
result = decode_qr_image("my_scratched_qr.png")
|
|
40
|
+
|
|
41
|
+
if result.get('wu_success') or result.get('bm_success'):
|
|
42
|
+
print("Decoded Text:", result.get('wu_text') or result.get('bm_text'))
|
|
43
|
+
else:
|
|
44
|
+
print("Decoding failed:", result.get('error'))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Task 2: Batch Process a Whole Folder of Images
|
|
48
|
+
If you have a folder containing hundreds of QR code images and want to decode all of them at once:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from qr_list_decoder import decode_folder
|
|
52
|
+
|
|
53
|
+
# This will scan the folder, process every image, and print the results
|
|
54
|
+
decode_folder("./dataset_of_qr_codes")
|
|
55
|
+
```
|
|
56
|
+
*(You can also do this directly from the command line: `python qr_demo.py --folder ./dataset_of_qr_codes`)*
|
|
57
|
+
|
|
58
|
+
### Task 3: Generate a New QR Code Image
|
|
59
|
+
You can use the library to encode text and create your own QR code images:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from qr_list_decoder import qr_encode_text, get_best_qr_matrix, render_qr
|
|
63
|
+
|
|
64
|
+
# 1. Convert text to bytes (e.g., Version 2 QR)
|
|
65
|
+
data_bytes = qr_encode_text("Hi Tejas!", version=2)
|
|
66
|
+
|
|
67
|
+
# 2. Let the library calculate the ECC bytes and build the best 2D matrix
|
|
68
|
+
matrix, mask_used = get_best_qr_matrix(data_bytes, version=2, ecc_level='high')
|
|
69
|
+
|
|
70
|
+
# 3. Render the matrix into an image and save it!
|
|
71
|
+
img = render_qr(matrix, scale=10, fg=(0, 0, 0), bg=(255, 255, 255))
|
|
72
|
+
img.save("my_new_qr.png")
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Task 4: Decode a Raw 2D Matrix
|
|
76
|
+
If you already extracted the binary grid yourself (or generated it) and want to bypass the image processing step:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from qr_list_decoder import decode_raw_matrix
|
|
80
|
+
|
|
81
|
+
# A 2D list or NumPy array where 1 is black and 0 is white.
|
|
82
|
+
my_matrix = [
|
|
83
|
+
[1, 1, 1, 1, 1, 1, 1, 0, 0, 1, ...],
|
|
84
|
+
[1, 0, 0, 0, 0, 0, 1, 0, 1, 1, ...],
|
|
85
|
+
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, ...],
|
|
86
|
+
# ... rest of the matrix rows
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
result = decode_raw_matrix(my_matrix)
|
|
90
|
+
if result.get('wu_success') or result.get('bm_success'):
|
|
91
|
+
print("Decoded Text:", result.get('wu_text') or result.get('bm_text'))
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Task 5: Byte-level Decoding
|
|
95
|
+
If you don't care about images or matrices, and just want to play with the underlying math:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from qr_list_decoder import rs_encode, wu_decode
|
|
99
|
+
|
|
100
|
+
# 1. Create a raw codeword
|
|
101
|
+
codeword = rs_encode(n=26, k=9, message=[72, 101, 108, 108, 111])
|
|
102
|
+
|
|
103
|
+
# 2. Simulate data corruption (flip random bytes)
|
|
104
|
+
corrupted = codeword.copy()
|
|
105
|
+
corrupted[2] ^= 255
|
|
106
|
+
corrupted[8] ^= 128
|
|
107
|
+
corrupted[14] ^= 42
|
|
108
|
+
|
|
109
|
+
# 3. Use Wu's algorithm to mathematically recover the original bytes!
|
|
110
|
+
candidates = wu_decode(n=26, k=9, received=corrupted)
|
|
111
|
+
print("Recovered bytes:", candidates[0])
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
The library exposes the following high-level core API components. Please check the source code for more advanced mathematical helper functions.
|
|
119
|
+
|
|
120
|
+
| Function | Description |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `rs_encode(n, k, message)` | Encode a message into an RS(n, k) codeword |
|
|
123
|
+
| `rs_syndromes(n, k, received)` | Compute syndromes of a received word |
|
|
124
|
+
| `berlekamp_massey(syndromes)` | Run standard Berlekamp-Massey |
|
|
125
|
+
| `wu_decode(n, k, received)` | **Main math entry point** — list-decode a corrupted codeword |
|
|
126
|
+
| `decode_qr_image(img_path)` | Decode a QR code directly from an image file |
|
|
127
|
+
| `decode_raw_matrix(matrix)` | Decode a 2D array of 0s and 1s |
|
|
128
|
+
| `decode_folder(path)` | Batch process a folder of QR images |
|
|
129
|
+
|
|
130
|
+
## Dependencies
|
|
131
|
+
|
|
132
|
+
- Python ≥ 3.8
|
|
133
|
+
- NumPy
|
|
134
|
+
- Pillow (PIL)
|
|
135
|
+
- *Optional:* OpenCV (`opencv-python`) for robust perspective-unwarping on camera photos.
|
|
136
|
+
|
|
137
|
+
## Optional C++ Acceleration
|
|
138
|
+
|
|
139
|
+
The package includes an optional C++ backend (`wu_core`) built with pybind11 that provides a massive ~20x-50x speedup on hot-path polynomial operations. It is automatically used if compiled:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pip install pybind11
|
|
143
|
+
python setup.py build_ext --inplace
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: list-decoder-qr
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Wu's list decoder for Reed-Solomon / QR codes over GF(2^8)
|
|
5
|
+
Author: Tejas
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Tejas423/List-Decoding-of-QR-codes
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: Pillow
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
|
|
15
|
+
# qr-list-decoder
|
|
16
|
+
|
|
17
|
+
**Wu's list decoder QR codes**
|
|
18
|
+
|
|
19
|
+
Completed as Master's Thesis Project (MTP) in the CSE Department at IIT Bombay.
|
|
20
|
+
|
|
21
|
+
This library implements Wu's list decoding algorithm, enabling error correction **beyond the standard decoding radius** of the code. It can recover QR codes with significantly more damage than standard decoders can handle.
|
|
22
|
+
|
|
23
|
+
Not only does it contain the advanced mathematical backend, but it also includes an end-to-end QR code pipeline (generating matrices, reading images, unmasking, and decoding).
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
**From PyPI (Recommended):**
|
|
28
|
+
```bash
|
|
29
|
+
pip install list-decoder-qr
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**From Source / Development:**
|
|
33
|
+
If you want to modify the code locally, clone the repository and install it in editable mode:
|
|
34
|
+
```bash
|
|
35
|
+
pip install .
|
|
36
|
+
# or for development
|
|
37
|
+
pip install -e .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## What You Can Do With This Library
|
|
43
|
+
|
|
44
|
+
Here are the main tasks you can perform with `qr-list-decoder`:
|
|
45
|
+
|
|
46
|
+
### Task 1: Read a QR Code from an Image File
|
|
47
|
+
If you have a picture of a QR code and you want to extract the hidden text from it:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from qr_list_decoder import decode_qr_image
|
|
51
|
+
|
|
52
|
+
# Pass the path to your image
|
|
53
|
+
result = decode_qr_image("my_scratched_qr.png")
|
|
54
|
+
|
|
55
|
+
if result.get('wu_success') or result.get('bm_success'):
|
|
56
|
+
print("Decoded Text:", result.get('wu_text') or result.get('bm_text'))
|
|
57
|
+
else:
|
|
58
|
+
print("Decoding failed:", result.get('error'))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Task 2: Batch Process a Whole Folder of Images
|
|
62
|
+
If you have a folder containing hundreds of QR code images and want to decode all of them at once:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from qr_list_decoder import decode_folder
|
|
66
|
+
|
|
67
|
+
# This will scan the folder, process every image, and print the results
|
|
68
|
+
decode_folder("./dataset_of_qr_codes")
|
|
69
|
+
```
|
|
70
|
+
*(You can also do this directly from the command line: `python qr_demo.py --folder ./dataset_of_qr_codes`)*
|
|
71
|
+
|
|
72
|
+
### Task 3: Generate a New QR Code Image
|
|
73
|
+
You can use the library to encode text and create your own QR code images:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from qr_list_decoder import qr_encode_text, get_best_qr_matrix, render_qr
|
|
77
|
+
|
|
78
|
+
# 1. Convert text to bytes (e.g., Version 2 QR)
|
|
79
|
+
data_bytes = qr_encode_text("Hi Tejas!", version=2)
|
|
80
|
+
|
|
81
|
+
# 2. Let the library calculate the ECC bytes and build the best 2D matrix
|
|
82
|
+
matrix, mask_used = get_best_qr_matrix(data_bytes, version=2, ecc_level='high')
|
|
83
|
+
|
|
84
|
+
# 3. Render the matrix into an image and save it!
|
|
85
|
+
img = render_qr(matrix, scale=10, fg=(0, 0, 0), bg=(255, 255, 255))
|
|
86
|
+
img.save("my_new_qr.png")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Task 4: Decode a Raw 2D Matrix
|
|
90
|
+
If you already extracted the binary grid yourself (or generated it) and want to bypass the image processing step:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from qr_list_decoder import decode_raw_matrix
|
|
94
|
+
|
|
95
|
+
# A 2D list or NumPy array where 1 is black and 0 is white.
|
|
96
|
+
my_matrix = [
|
|
97
|
+
[1, 1, 1, 1, 1, 1, 1, 0, 0, 1, ...],
|
|
98
|
+
[1, 0, 0, 0, 0, 0, 1, 0, 1, 1, ...],
|
|
99
|
+
[1, 0, 1, 1, 1, 0, 1, 0, 0, 0, ...],
|
|
100
|
+
# ... rest of the matrix rows
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
result = decode_raw_matrix(my_matrix)
|
|
104
|
+
if result.get('wu_success') or result.get('bm_success'):
|
|
105
|
+
print("Decoded Text:", result.get('wu_text') or result.get('bm_text'))
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Task 5: Byte-level Decoding
|
|
109
|
+
If you don't care about images or matrices, and just want to play with the underlying math:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from qr_list_decoder import rs_encode, wu_decode
|
|
113
|
+
|
|
114
|
+
# 1. Create a raw codeword
|
|
115
|
+
codeword = rs_encode(n=26, k=9, message=[72, 101, 108, 108, 111])
|
|
116
|
+
|
|
117
|
+
# 2. Simulate data corruption (flip random bytes)
|
|
118
|
+
corrupted = codeword.copy()
|
|
119
|
+
corrupted[2] ^= 255
|
|
120
|
+
corrupted[8] ^= 128
|
|
121
|
+
corrupted[14] ^= 42
|
|
122
|
+
|
|
123
|
+
# 3. Use Wu's algorithm to mathematically recover the original bytes!
|
|
124
|
+
candidates = wu_decode(n=26, k=9, received=corrupted)
|
|
125
|
+
print("Recovered bytes:", candidates[0])
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## API Reference
|
|
131
|
+
|
|
132
|
+
The library exposes the following high-level core API components. Please check the source code for more advanced mathematical helper functions.
|
|
133
|
+
|
|
134
|
+
| Function | Description |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `rs_encode(n, k, message)` | Encode a message into an RS(n, k) codeword |
|
|
137
|
+
| `rs_syndromes(n, k, received)` | Compute syndromes of a received word |
|
|
138
|
+
| `berlekamp_massey(syndromes)` | Run standard Berlekamp-Massey |
|
|
139
|
+
| `wu_decode(n, k, received)` | **Main math entry point** — list-decode a corrupted codeword |
|
|
140
|
+
| `decode_qr_image(img_path)` | Decode a QR code directly from an image file |
|
|
141
|
+
| `decode_raw_matrix(matrix)` | Decode a 2D array of 0s and 1s |
|
|
142
|
+
| `decode_folder(path)` | Batch process a folder of QR images |
|
|
143
|
+
|
|
144
|
+
## Dependencies
|
|
145
|
+
|
|
146
|
+
- Python ≥ 3.8
|
|
147
|
+
- NumPy
|
|
148
|
+
- Pillow (PIL)
|
|
149
|
+
- *Optional:* OpenCV (`opencv-python`) for robust perspective-unwarping on camera photos.
|
|
150
|
+
|
|
151
|
+
## Optional C++ Acceleration
|
|
152
|
+
|
|
153
|
+
The package includes an optional C++ backend (`wu_core`) built with pybind11 that provides a massive ~20x-50x speedup on hot-path polynomial operations. It is automatically used if compiled:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pip install pybind11
|
|
157
|
+
python setup.py build_ext --inplace
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
MANIFEST.in
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
requirements.txt
|
|
5
|
+
setup.py
|
|
6
|
+
list_decoder_qr.egg-info/PKG-INFO
|
|
7
|
+
list_decoder_qr.egg-info/SOURCES.txt
|
|
8
|
+
list_decoder_qr.egg-info/dependency_links.txt
|
|
9
|
+
list_decoder_qr.egg-info/requires.txt
|
|
10
|
+
list_decoder_qr.egg-info/top_level.txt
|
|
11
|
+
qr_list_decoder/__init__.py
|
|
12
|
+
qr_list_decoder/matrix.py
|
|
13
|
+
qr_list_decoder/wu_core.cpp
|
|
14
|
+
qr_list_decoder/wu_qr.py
|
|
15
|
+
tests/test_decoder.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qr_list_decoder
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "pybind11>=2.10"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "list-decoder-qr"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Wu's list decoder for Reed-Solomon / QR codes over GF(2^8)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
dependencies = ["numpy", "Pillow"]
|
|
13
|
+
|
|
14
|
+
[project.urls]
|
|
15
|
+
Homepage = "https://github.com/Tejas423/List-Decoding-of-QR-codes"
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
qr_list_decoder — Wu's list decoder for Reed-Solomon / QR codes.
|
|
3
|
+
|
|
4
|
+
This package provides a pure-Python (with optional C++ acceleration)
|
|
5
|
+
implementation of Wu's rational interpolation-based list decoder for
|
|
6
|
+
Reed-Solomon codes over GF(2^8), targeting QR-code applications.
|
|
7
|
+
|
|
8
|
+
Quick start::
|
|
9
|
+
|
|
10
|
+
from qr_list_decoder import wu_decode, rs_encode, rs_syndromes
|
|
11
|
+
|
|
12
|
+
# Encode a message
|
|
13
|
+
codeword = rs_encode(n=26, k=9, message=[72, 101, 108, 108, 111])
|
|
14
|
+
|
|
15
|
+
# Decode a corrupted codeword (list decoding beyond t0)
|
|
16
|
+
candidates = wu_decode(n=26, k=9, received=corrupted_cw)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .wu_qr import (
|
|
20
|
+
# --- Encoding ---
|
|
21
|
+
rs_generator,
|
|
22
|
+
rs_encode,
|
|
23
|
+
|
|
24
|
+
# --- Syndrome computation ---
|
|
25
|
+
rs_syndromes,
|
|
26
|
+
|
|
27
|
+
# --- Berlekamp-Massey ---
|
|
28
|
+
berlekamp_massey,
|
|
29
|
+
|
|
30
|
+
# --- Wu list decoder (main entry point) ---
|
|
31
|
+
wu_decode,
|
|
32
|
+
wu_params,
|
|
33
|
+
|
|
34
|
+
# --- Sub-components (for advanced users) ---
|
|
35
|
+
build_interp,
|
|
36
|
+
nullspace,
|
|
37
|
+
hensel_series,
|
|
38
|
+
rr_series,
|
|
39
|
+
recover_from_series,
|
|
40
|
+
chien_search,
|
|
41
|
+
decode_from_positions,
|
|
42
|
+
|
|
43
|
+
# --- GF(2^8) arithmetic utilities ---
|
|
44
|
+
gf_mul,
|
|
45
|
+
gf_inv,
|
|
46
|
+
gf_div,
|
|
47
|
+
gf_pow,
|
|
48
|
+
|
|
49
|
+
# --- Polynomial utilities ---
|
|
50
|
+
padd,
|
|
51
|
+
pmul,
|
|
52
|
+
peval,
|
|
53
|
+
pdeg,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
from .matrix import (
|
|
57
|
+
decode_raw_matrix,
|
|
58
|
+
decode_qr_image,
|
|
59
|
+
make_qr_matrix,
|
|
60
|
+
get_best_qr_matrix,
|
|
61
|
+
read_qr_image,
|
|
62
|
+
qr_encode_text,
|
|
63
|
+
qr_decode_text,
|
|
64
|
+
extract_qr_data,
|
|
65
|
+
render_qr,
|
|
66
|
+
decode_folder,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
__version__ = "0.1.0"
|
|
70
|
+
__all__ = [
|
|
71
|
+
"rs_generator",
|
|
72
|
+
"rs_encode",
|
|
73
|
+
"rs_syndromes",
|
|
74
|
+
"berlekamp_massey",
|
|
75
|
+
"wu_decode",
|
|
76
|
+
"wu_params",
|
|
77
|
+
"build_interp",
|
|
78
|
+
"nullspace",
|
|
79
|
+
"hensel_series",
|
|
80
|
+
"rr_series",
|
|
81
|
+
"recover_from_series",
|
|
82
|
+
"chien_search",
|
|
83
|
+
"decode_from_positions",
|
|
84
|
+
"gf_mul",
|
|
85
|
+
"gf_inv",
|
|
86
|
+
"gf_div",
|
|
87
|
+
"gf_pow",
|
|
88
|
+
"padd",
|
|
89
|
+
"pmul",
|
|
90
|
+
"peval",
|
|
91
|
+
"pdeg",
|
|
92
|
+
"decode_raw_matrix",
|
|
93
|
+
"decode_qr_image",
|
|
94
|
+
"make_qr_matrix",
|
|
95
|
+
"read_qr_image",
|
|
96
|
+
"qr_encode_text",
|
|
97
|
+
"qr_decode_text",
|
|
98
|
+
"extract_qr_data",
|
|
99
|
+
"render_qr",
|
|
100
|
+
"decode_folder",
|
|
101
|
+
]
|