bitlab 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.
@@ -0,0 +1,35 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install package and dev dependencies
26
+ run: pip install -e ".[dev]"
27
+
28
+ - name: Run tests
29
+ run: pytest -v
30
+
31
+ - name: Build sdist and wheel
32
+ run: python -m build
33
+
34
+ - name: Check package metadata
35
+ run: python -m twine check dist/*
@@ -0,0 +1,51 @@
1
+ name: Publish to PyPI
2
+
3
+ # Triggers when you publish a GitHub Release (recommended: tag it vX.Y.Z
4
+ # matching the version in pyproject.toml). Can also be run manually.
5
+ on:
6
+ release:
7
+ types: [published]
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install build tooling
22
+ run: pip install build
23
+
24
+ - name: Build sdist and wheel
25
+ run: python -m build
26
+
27
+ - name: Upload build artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment: pypi
37
+ permissions:
38
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
39
+
40
+ steps:
41
+ - name: Download build artifacts
42
+ uses: actions/download-artifact@v4
43
+ with:
44
+ name: dist
45
+ path: dist/
46
+
47
+ - name: Publish to PyPI
48
+ uses: pypa/gh-action-pypi-publish@release/v1
49
+ # No password/token needed: this uses PyPI's Trusted Publisher
50
+ # feature. One-time setup required on pypi.org -- see the "Publishing"
51
+ # section of README.md / CONTRIBUTING.md.
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .pytest_cache/
5
+ build/
6
+ dist/
7
+ .venv/
8
+ venv/
9
+ .DS_Store
@@ -0,0 +1,64 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Planned
11
+ - Register field mapper (`bitlab.registers`) — define a hardware register's
12
+ bit layout in Python, pack/unpack values, export to C `#define`s or a
13
+ bitfield struct.
14
+ - Computer architecture toolkit (`bitlab.arch`) — IEEE 754 float
15
+ deconstruction, endianness swapping, Gray code, Q-format fixed-point
16
+ conversion.
17
+ - COBS framing (`bitlab.comms`) — Consistent Overhead Byte Stuffing for
18
+ serial protocols.
19
+ - Reed-Solomon burst error correction — planned as a later, dedicated
20
+ release given its complexity.
21
+
22
+ ## [0.1.0] - 2026-07-14
23
+
24
+ ### Added
25
+ - **Named the project `bitlab`** and
26
+ restructured it as submodules under one umbrella package rather than a
27
+ flat namespace, to give the project room to grow beyond parity:
28
+ ```
29
+ bitlab/
30
+ ├── bitutils/ # foundational bit ops shared by every submodule
31
+ ├── parity/ # parity bit checking + Hamming(7,4)
32
+ └── crc/ # new in this release
33
+ ```
34
+ - **New `bitlab.crc` submodule**: CRC generation, checking, explanation, and
35
+ C code export.
36
+ - `crc8()`, `crc16(variant="ccitt"|"modbus")`, `crc32()` convenience
37
+ functions for the most common industry variants.
38
+ - Generic `crc(data, config)` for custom polynomials via `CRCConfig`.
39
+ - Built-in presets — `CRC8_SMBUS`, `CRC16_CCITT_FALSE`, `CRC16_MODBUS`,
40
+ `CRC32_ISO_HDLC` — each verified against its published CRC-catalogue
41
+ check value (the CRC of `b"123456789"`).
42
+ - `explain(data, config)`: step-by-step trace of the real bitwise
43
+ algorithm, for teaching/learning how CRC actually works.
44
+ - `export_c(config, function_name=None)`: exports a table-driven C99
45
+ implementation. The embedded lookup table is generated by the same code
46
+ used internally by the fast Python path, and is validated by actually
47
+ compiling the generated C with `gcc` and checking its output against
48
+ the CRC catalogue in the test suite.
49
+ - `compute_bitwise()` / `compute_table()` / `build_table()` / `self_test()`
50
+ as lower-level building blocks.
51
+ - **New `bitlab.bitutils` submodule**: `popcount`, `has_odd_parity`,
52
+ `get_bit`/`set_bit`/`flip_bit`, `reflect`, `rotate_left`/`rotate_right`,
53
+ promoted out of the old parity-only utils module so they're shared
54
+ foundational building blocks for `parity`, `crc`, and future submodules.
55
+ - Unified `bitlab` CLI covering `parity`, `hamming`, and `crc` subcommands
56
+ (previously `parity-toolkit` had its own separate CLI).
57
+ - 56 tests total, including property-based cross-validation of the bitwise
58
+ vs. table-driven CRC implementations and end-to-end compilation of
59
+ generated C source.
60
+
61
+ ---
62
+
63
+ [Unreleased]: https://github.com/KenKambi/bitlab/compare/v0.1.0...HEAD
64
+ [0.1.0]: https://github.com/KenKambi/bitlab/releases/tag/v0.1.0
@@ -0,0 +1,41 @@
1
+ # Contributing to bitlab
2
+
3
+ ## Development setup
4
+
5
+ ```bash
6
+ git clone https://github.com/KenKambi/bitlab.git
7
+ cd bitlab
8
+ pip install -e ".[dev]"
9
+ pytest
10
+ ```
11
+
12
+ Each submodule (`bitutils`, `parity`, `crc`) has its own test file(s) under
13
+ `tests/`. `test_crc_codegen.py` compiles the generated C with `gcc` and
14
+ actually runs it — install `gcc` locally (`apt install gcc` / Xcode Command
15
+ Line Tools / MinGW) or those specific tests will be skipped automatically.
16
+
17
+ ## Project layout
18
+
19
+ ```
20
+ src/bitlab/
21
+ ├── bitutils/ # foundational bit ops — add here only if it's used by 2+ other submodules
22
+ ├── parity/ # parity + Hamming(7,4)
23
+ └── crc/ # engine.py (compute), presets.py (CRCConfig + built-ins),
24
+ # explain.py (educational trace), codegen.py (C export)
25
+ ```
26
+
27
+ When adding a new domain (e.g. registers, arch, comms), give it its own
28
+ top-level submodule under `src/bitlab/`, following the same pattern as
29
+ `crc/`: a `presets.py`/config layer, a computation engine, and — where it
30
+ makes sense — an `explain()` and/or `export_c()`.
31
+
32
+ ## Before opening a PR
33
+
34
+ ```bash
35
+ pytest -v # all tests must pass
36
+ python -m build # package must build cleanly
37
+ python -m twine check dist/* # metadata must be valid
38
+ ```
39
+
40
+ CI runs the same checks across Python 3.9–3.13 on every push/PR.
41
+
bitlab-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ken Kambi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bitlab-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,266 @@
1
+ Metadata-Version: 2.4
2
+ Name: bitlab
3
+ Version: 0.1.0
4
+ Summary: A toolkit for embedded systems, binary data, and digital communications: parity, Hamming codes, and CRC — with C code export.
5
+ Project-URL: Homepage, https://github.com/KenKambi/bitlab
6
+ Project-URL: Issues, https://github.com/KenKambi/bitlab/issues
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Keywords: bit-manipulation,c-code-generation,crc,crc16,crc32,crc8,embedded,error-correction,error-detection,hamming-code,parity,serial,uart
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Communications
15
+ Classifier: Topic :: Education
16
+ Classifier: Topic :: Software Development :: Embedded Systems
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.8
19
+ Provides-Extra: dev
20
+ Requires-Dist: build; extra == 'dev'
21
+ Requires-Dist: pytest>=7.0; extra == 'dev'
22
+ Requires-Dist: twine; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # bitlab
26
+
27
+ [![CI](https://github.com/KenKambi/bitlab/actions/workflows/ci.yml/badge.svg)](https://github.com/KenKambi/bitlab/actions/workflows/ci.yml)
28
+ [![PyPI](https://img.shields.io/pypi/v/bitlab.svg)](https://pypi.org/project/bitlab/)
29
+
30
+ A toolkit for embedded systems, binary data, and digital communications.
31
+
32
+ Built around the topics an Electronic & Computer Engineering degree
33
+ actually covers: digital logic, computer architecture, embedded systems,
34
+ and communications. Each domain is a self-contained submodule, so the
35
+ package can keep growing without becoming a junk drawer.
36
+
37
+ - Zero dependencies
38
+ - Type-hinted (PEP 561, ships a `py.typed` marker)
39
+ - One CLI: `bitlab`
40
+ - Production functions **and** step-by-step educational explanations, side by side
41
+ - CRC configs export directly to compiled, table-driven C — the same table your Python code uses
42
+
43
+ ```
44
+ bitlab/
45
+ ├── bitutils/ # foundational bit ops used by every other submodule
46
+ ├── parity/ # parity bit checking + Hamming(7,4) error correction
47
+ └── crc/ # CRC-8/16/32, generic engine, explain(), export_c()
48
+ ```
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install bitlab
54
+ ```
55
+
56
+ ## `bitlab.crc` — CRC generation, checking, explanation, and C export
57
+
58
+ ```python
59
+ from bitlab.crc import crc8, crc16, crc32
60
+
61
+ crc8(b"hello") # CRC-8/SMBUS
62
+ crc16(b"hello") # CRC-16/CCITT-FALSE (default)
63
+ crc16(b"hello", variant="modbus") # CRC-16/MODBUS
64
+ crc32(b"hello") # CRC-32/ISO-HDLC (Ethernet, zlib, PNG)
65
+ ```
66
+
67
+ Every built-in preset is verified against its published CRC-catalogue check
68
+ value (the CRC of `b"123456789"`) in the test suite — these aren't "a CRC
69
+ that happens to run", they match what real hardware and protocols expect.
70
+
71
+ ### Custom polynomials
72
+
73
+ ```python
74
+ from bitlab.crc import crc, CRCConfig
75
+
76
+ my_crc = CRCConfig(
77
+ name="my-custom-crc",
78
+ width=16, poly=0x8005, init=0xFFFF,
79
+ refin=True, refout=True, xorout=0x0000,
80
+ check=0x4B37, # CRC of b"123456789", for self-testing your config
81
+ )
82
+ crc(b"some data", my_crc)
83
+ ```
84
+
85
+ ### Step-by-step explanation (the same computation, narrated)
86
+
87
+ ```python
88
+ from bitlab.crc import explain, CRC8_SMBUS
89
+
90
+ print(explain(b"AB", CRC8_SMBUS))
91
+ ```
92
+
93
+ ```
94
+ CRC algorithm: CRC-8/SMBUS
95
+ width=8 poly=0x07 init=0x00 refin=False refout=False xorout=0x00
96
+
97
+ Input bytes (2 total): 41 42
98
+
99
+ Initial register: 0x00
100
+
101
+ Byte 0: 0x41 -> XORed in, register = 0x41
102
+ bit 0: MSB=0 -> shift left -> 0x82
103
+ bit 1: MSB=1 -> shift left, XOR polynomial -> 0x03
104
+ ...
105
+
106
+ Final CRC: 0x87
107
+ ```
108
+
109
+ `explain()` runs the real bitwise algorithm with a narration attached — it's
110
+ not a separate simplified explanation, so what you read is guaranteed to
111
+ match what `crc8`/`crc16`/`crc32` actually compute.
112
+
113
+ ### Export to C
114
+
115
+ ```python
116
+ from bitlab.crc import export_c, CRC32_ISO_HDLC
117
+
118
+ print(export_c(CRC32_ISO_HDLC, function_name="my_crc32"))
119
+ ```
120
+
121
+ ```c
122
+ #include <stdint.h>
123
+ #include <stddef.h>
124
+
125
+ static const uint32_t my_crc32_table[256] = {
126
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, ...
127
+ };
128
+
129
+ uint32_t my_crc32(const uint8_t *data, size_t len)
130
+ {
131
+ uint32_t crc = 0xFFFFFFFFU;
132
+ for (size_t i = 0; i < len; i++) {
133
+ uint8_t idx = (uint8_t)(crc ^ data[i]);
134
+ crc = (crc >> 8) ^ my_crc32_table[idx];
135
+ }
136
+ return (crc ^ 0xFFFFFFFFU);
137
+ }
138
+ ```
139
+
140
+ The exported table is built by the exact same code Python's fast path
141
+ uses — the test suite actually compiles the generated C with `gcc` and
142
+ checks the output against the CRC catalogue, so this isn't just
143
+ "code that looks right."
144
+
145
+ ## `bitlab.parity` — parity bits and Hamming(7,4)
146
+
147
+ ```python
148
+ from bitlab.parity import get_parity_bit, append_parity, check_parity
149
+
150
+ get_parity_bit(0b1011, "even", 4) # -> 1
151
+ append_parity(0b1011, "even", 4) # -> 0b11011
152
+ check_parity(0b11011, "even", 4) # -> True
153
+ ```
154
+
155
+ ```python
156
+ from bitlab.parity import encode_hamming, decode_hamming
157
+
158
+ codeword = encode_hamming(0b1101)
159
+ corrupted = codeword ^ 0b0000100 # simulate a single-bit flip
160
+ result = decode_hamming(corrupted)
161
+ # HammingDecodeResult(data=13, error_position=6, corrected=True, codeword=...)
162
+ ```
163
+
164
+ See the full parity/Hamming API reference at the bottom of this file.
165
+
166
+ ## `bitlab.bitutils` — shared low-level bit helpers
167
+
168
+ ```python
169
+ from bitlab.bitutils import popcount, reflect, rotate_left, rotate_right
170
+
171
+ popcount(0b1011) # -> 3
172
+ reflect(0b1100, 4) # -> 0b0011 (bit-mirror, used internally by crc)
173
+ rotate_left(0b10000001, 1, 8) # -> 0b00000011
174
+ ```
175
+
176
+ ## CLI
177
+
178
+ ```bash
179
+ bitlab parity bit 0b1011 --type even --width 4
180
+ # -> 1
181
+
182
+ bitlab hamming encode 13
183
+ # -> 85 (0b1010101)
184
+
185
+ bitlab crc compute "123456789" --preset crc32
186
+ # -> 0xCBF43926 (3421780262)
187
+
188
+ bitlab crc explain "AB" --preset crc8
189
+ # -> step-by-step trace
190
+
191
+ bitlab crc export-c --preset crc32 --name my_crc32
192
+ # -> C source on stdout
193
+ ```
194
+
195
+ Run `bitlab --help`, `bitlab crc --help`, etc. for full usage.
196
+
197
+ ## API reference
198
+
199
+ ### `bitlab.crc`
200
+
201
+ | Function | Description |
202
+ |---|---|
203
+ | `crc8(data)` | CRC-8/SMBUS. |
204
+ | `crc16(data, variant="ccitt")` | CRC-16/CCITT-FALSE or CRC-16/MODBUS. |
205
+ | `crc32(data)` | CRC-32/ISO-HDLC (Ethernet/zlib/PNG). |
206
+ | `crc(data, config)` | Generic entry point. `config` is a `CRCConfig` or a preset name string. |
207
+ | `explain(data, config, max_bytes=4)` | Step-by-step trace of the computation. |
208
+ | `export_c(config, function_name=None)` | Table-driven C99 source implementing `config`. |
209
+ | `build_table(config)` | The 256-entry lookup table (also used internally and by `export_c`). |
210
+ | `compute_bitwise(data, config)` | Canonical bit-by-bit reference implementation. |
211
+ | `compute_table(data, config, table=None)` | Fast table-driven implementation. |
212
+ | `self_test(config)` | Verifies a config against its `check` value. |
213
+ | `CRCConfig` | Dataclass: `name, width, poly, init, refin, refout, xorout, check`. |
214
+ | `CRC8_SMBUS`, `CRC16_CCITT_FALSE`, `CRC16_MODBUS`, `CRC32_ISO_HDLC` | Built-in preset configs. |
215
+
216
+ ### `bitlab.parity`
217
+
218
+ | Function | Description |
219
+ |---|---|
220
+ | `get_parity_bit(value, type="even", bit_width=8)` | Computes the parity bit for `value`. |
221
+ | `append_parity(value, type="even", bit_width=8)` | Returns `value` with a parity bit appended as bit `bit_width`. |
222
+ | `check_parity(value_with_parity, type="even", bit_width=8)` | Returns `True` if the parity bit matches the data. |
223
+ | `generate_parity_array(values, type="even", bit_width=8)` | Parity bit for each value in a sequence. |
224
+ | `check_parity_array(values_with_parity, type="even", bit_width=8)` | Parity check for each value in a sequence. |
225
+ | `compute_message_parity(message, type="even")` | Single overall parity bit for a whole string. |
226
+ | `flip_random_bit(value, bit_width=8)` | Flips one random bit — useful for simulating errors in tests. |
227
+ | `encode_hamming(data)` | Encodes a 4-bit value (0–15) into a 7-bit Hamming codeword. |
228
+ | `decode_hamming(codeword)` | Decodes a 7-bit codeword, correcting a single-bit error if present. |
229
+
230
+ ### `bitlab.bitutils`
231
+
232
+ | Function | Description |
233
+ |---|---|
234
+ | `popcount(n)` | Number of 1-bits. |
235
+ | `has_odd_parity(n)` | True if `n` has an odd number of 1-bits. |
236
+ | `get_bit` / `set_bit` / `flip_bit` | Single-bit read/write/toggle. |
237
+ | `reflect(value, width)` | Bit-mirror the lowest `width` bits. |
238
+ | `rotate_left` / `rotate_right` | Bitwise rotation within a fixed-width register. |
239
+
240
+ ## Roadmap
241
+
242
+ Planned next:
243
+
244
+ - **Register field mapper** — define a hardware register's bit layout in
245
+ Python, pack/unpack values, export to C `#define`s or a bitfield struct.
246
+ - **Computer architecture toolkit** — IEEE 754 float deconstruction,
247
+ endianness swapping, Gray code, Q-format fixed-point conversion.
248
+ - **COBS framing** — Consistent Overhead Byte Stuffing for serial protocols.
249
+ - **Reed-Solomon** — burst error correction (QR codes, satellite comms) —
250
+ planned as a later, dedicated release given its complexity.
251
+
252
+ ## Development
253
+
254
+ ```bash
255
+ pip install -e ".[dev]"
256
+ pytest # run the test suite (56 tests, including compiling
257
+ # and running the generated C against gcc)
258
+ python -m build # produce a wheel + sdist in dist/
259
+ ```
260
+
261
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full dev workflow and release
262
+ process, and [CHANGELOG.md](CHANGELOG.md) for release history.
263
+
264
+ ## License
265
+
266
+ MIT