Skip to content

Commit 5fe6fdb

Browse files
committed
Added barcode codecs
1 parent 7b81e59 commit 5fe6fdb

8 files changed

Lines changed: 1748 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ CACTCGGTCGGCCATATGTTCGGCCATATGTTCGTCTGTTCACTCGCCCATACACT
259259

260260
## :page_with_curl: List of codecs
261261

262+
#### [Barcodes](https://python-codext.readthedocs.io/en/latest/enc/barcodes.html)
263+
264+
- [X] `aztec`: real (scannable) Aztec code (ISO/IEC 24778) ; optimal high-level compaction, error correction percentage given in the name (e.g. `aztec-33` ; 23% by default), rendered as an image or, with `aztec-text`, as plain text ; decoding applies Reed-Solomon error correction
265+
- [X] `fakeqr`: hides the input bits as the modules of something that looks like a QR code but is not one, either an image or, with the `fakeqr-text` variant, plain text (the 8 QR masks are available as `fakeqr-0` to `fakeqr-7`)
266+
- [X] `qr`: real (scannable) QR code ; byte mode, error correction level given in the name (`qr-l`, `qr-m`, `qr-q`, `qr-h` ; M by default), rendered as an image or, with `qr-text`, as plain text ; decoding applies Reed-Solomon error correction
267+
262268
#### [BaseXX](https://python-codext.readthedocs.io/en/latest/enc/base.html)
263269

264270
- [X] `base1`: useless, but for the sake of completeness

‎docs/mkdocs.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ nav:
1111
- Features: features.md
1212
- 'Guess mode': guessing.md
1313
- Encodings:
14+
- Barcodes: enc/barcodes.md
1415
- Base: enc/base.md
1516
- Binary: enc/binary.md
1617
- Ciphers: enc/ciphers.md

‎docs/pages/enc/barcodes.md‎

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
`codext` can generate and read matrix barcodes. The `aztec` and `qr` codecs produce real, scannable Aztec and QR codes (with Reed-Solomon error correction), while `fakeqr` only mimics the aspect of a QR code, hiding the input in an image that is not a valid one.
2+
3+
-----
4+
5+
### Aztec Code
6+
7+
This encodes the input as a real (standard, scannable) [Aztec code](https://en.wikipedia.org/wiki/Aztec_Code) (ISO/IEC 24778), a 2D matrix barcode with a central bulls-eye finder pattern and the data spiralling around it. It uses the optimal high-level compaction (upper, lower, mixed, punctuation and digit modes plus binary shift), selects the smallest symbol (compact 1 to 4 layers, then full 1 to 32 layers) that fits the data for the chosen error correction percentage (given in the codec name, 23% by default) and adds the Reed-Solomon error correction. Decoding recovers the size, layer count and error correction from the mode message and applies Reed-Solomon error correction, so that a damaged code can still be decoded ; it handles all the compaction modes, so that Aztec codes generated by other tools can be read. Like the other barcodes, the output is a grayscale PNG image by default, or plain text with the `-text` variant.
8+
9+
**Codec** | **Conversions** | **Aliases** | **Comment**
10+
:---: | :---: | --- | ---
11+
`aztec` | text <-> Aztec code (image or text) | `aztec-N` (*N* being the error correction percentage), `aztec-text`, `aztec-N-text` | 23% by default ; the symbol size is chosen automatically
12+
13+
```python
14+
>>> png = codext.encode(b"codext", "aztec")
15+
>>> png[:8]
16+
b'\x89PNG\r\n\x1a\n'
17+
>>> codext.decode(png, "aztec")
18+
b'codext'
19+
>>> print(codext.encode("Az", "aztec-text"))
20+
███████ █
21+
██ █ █
22+
███ █ ███
23+
████████████ █
24+
██ █ █ █
25+
██ █████ █ ██
26+
██ █ █ █ ██
27+
█ █ █ █ █ █ █
28+
██ █ █ █ ████
29+
██ █ █████ ████
30+
███ █
31+
█ ████████████
32+
██ ██
33+
█ █ ███ █
34+
█ █ ███ █ █
35+
>>> codext.decode(codext.encode("Az", "aztec-text"), "aztec")
36+
'Az'
37+
```
38+
39+
-----
40+
41+
### Fake QR Code
42+
43+
This hides the input bytes in something that looks like a [QR code](https://en.wikipedia.org/wiki/QR_code) but is not a valid one: each bit becomes a module (a dark module for a 1, a light one for a 0), laid out row by row in the smallest QR-like square grid (versions 1 to 40) that can hold them while skipping the three finder patterns (the corner squares) and the timing patterns (the dotted lines joining them), so that the result keeps the typical QR aspect. A 32-bit header holds the input length. An optional mask (one of the 8 QR mask patterns, given in the codec name) inverts part of the data modules depending on their coordinates, making the pixels look more random. By default, the fake QR code is a grayscale PNG image (one pixel per module), but the `-text` variant renders it as plain text instead, with a full block for a dark module and a space for a light one ; decoding accepts either form.
44+
45+
**Codec** | **Conversions** | **Aliases** | **Comment**
46+
:---: | :---: | --- | ---
47+
`fakeqr` | text <-> fake QR code (image or text) | `fakeqr-N`, `fakeqr-text`, `fakeqr-text-N` (*N* being the mask pattern) | no mask by default ; *N* ranges from 0 to 7
48+
49+
```python
50+
>>> png = codext.encode(b"this is a test", "fakeqr")
51+
>>> png[:8]
52+
b'\x89PNG\r\n\x1a\n'
53+
>>> codext.decode(png, "fakeqr")
54+
b'this is a test'
55+
>>> codext.decode(codext.encode(b"this is a test", "fakeqr-3"), "fakeqr-3")
56+
b'this is a test'
57+
>>> print(codext.encode("test", "fakeqr-text"))
58+
███████ ███████
59+
█ █ █ █
60+
█ ███ █ █ ███ █
61+
█ ███ █ █ ███ █
62+
█ ███ █ █ ███ █
63+
█ █ █ █ █
64+
███████ █ █ █ ███████
65+
██
66+
█ █ ███ █ █ ███ █
67+
█ ███ █
68+
█
69+
70+
█
71+
72+
███████
73+
█ █
74+
█ ███ █
75+
█ ███ █
76+
█ ███ █
77+
█ █
78+
███████
79+
>>> codext.decode(codext.encode("test", "fakeqr-text"), "fakeqr")
80+
'test'
81+
```
82+
83+
-----
84+
85+
### QR Code
86+
87+
This encodes the input as a real (standard, scannable) [QR code](https://en.wikipedia.org/wiki/QR_code), as opposed to the `fakeqr` codec which only mimics the aspect of one. It uses the byte mode, selects the smallest version (1 to 40) that fits the data for the chosen error correction level (`L`, `M`, `Q` or `H`, given in the codec name, `M` by default) and picks the data mask with the lowest penalty score. Decoding reads the QR code back, recovering its error correction level and mask from the format information and applying Reed-Solomon error correction, so that a damaged QR code can still be decoded ; it also handles the numeric and alphanumeric modes, so that QR codes generated by other tools can be read. Like `fakeqr`, the QR code is a grayscale PNG image by default, or plain text with the `-text` variant.
88+
89+
**Codec** | **Conversions** | **Aliases** | **Comment**
90+
:---: | :---: | --- | ---
91+
`qr` | text <-> QR code (image or text) | `qr-L`, `qr-M`, `qr-Q`, `qr-H`, `qr-text`, `qr-H-text` | `M` by default ; the mask is chosen automatically
92+
93+
```python
94+
>>> png = codext.encode(b"codext", "qr")
95+
>>> png[:8]
96+
b'\x89PNG\r\n\x1a\n'
97+
>>> codext.decode(png, "qr")
98+
b'codext'
99+
>>> print(codext.encode("QR", "qr-h-text"))
100+
███████ █ ███████
101+
█ █ █ █ █
102+
█ ███ █ █ █ ███ █
103+
█ ███ █ █ █ ███ █
104+
█ ███ █ █ ██ █ ███ █
105+
█ █ █ █ █ █
106+
███████ █ █ █ ███████
107+
█ ██
108+
██ ███ ███ █
109+
█ █ █ █ ██ ██
110+
█ █ █ ██████
111+
██ █ ███ ██
112+
██ █ ██ ████ █ █ █
113+
█ ████ █ ███
114+
███████ ██ █ █ █ █
115+
█ █ ███ █ █
116+
█ ███ █ ██ █ █ █
117+
█ ███ █ ███ █ █ █
118+
█ ███ █ █ ████ ███
119+
█ █ █ ███ ██ █
120+
███████ ███ ██ █
121+
>>> codext.decode(codext.encode("QR", "qr-h-text"), "qr")
122+
'QR'
123+
```

‎docs/pages/enc/stegano.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ This is a Polybius code with the trivial alphabetical distribution ("A" -> (1,1)
3636

3737
-----
3838

39+
3940
### Resistor Color Codes
4041

4142
This uses the [electronic color code](https://en.wikipedia.org/wiki/Electronic_color_code#Resistor_color-coding) to encode digits, displaying colors in the terminal with ANSI color codes.

‎src/codext/barcodes/__init__.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# -*- coding: UTF-8 -*-
2+
from .aztec import *
3+
from .fakeqr import *
4+
from .qr import *

0 commit comments

Comments
 (0)