hexconv 0.1.1__tar.gz → 0.2.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.
- {hexconv-0.1.1/src/hexconv.egg-info → hexconv-0.2.0}/PKG-INFO +143 -1
- {hexconv-0.1.1 → hexconv-0.2.0}/README.md +142 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/pyproject.toml +1 -1
- {hexconv-0.1.1 → hexconv-0.2.0}/src/hexconv/__init__.py +66 -0
- hexconv-0.2.0/src/hexconv/_core.py +1821 -0
- {hexconv-0.1.1 → hexconv-0.2.0/src/hexconv.egg-info}/PKG-INFO +143 -1
- {hexconv-0.1.1 → hexconv-0.2.0}/tests/test_hexconv.py +75 -0
- hexconv-0.1.1/src/hexconv/_core.py +0 -832
- {hexconv-0.1.1 → hexconv-0.2.0}/LICENSE +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/MANIFEST.in +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/setup.cfg +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/src/hexconv/py.typed +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/src/hexconv.egg-info/SOURCES.txt +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/src/hexconv.egg-info/dependency_links.txt +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/src/hexconv.egg-info/requires.txt +0 -0
- {hexconv-0.1.1 → hexconv-0.2.0}/src/hexconv.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hexconv
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Pythonic conversion toolkit for bytes, hex, integers, arrays, binary strings, base64, and text.
|
|
5
5
|
Author: hexconv contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,6 +60,72 @@ hx.from_int_array([0x1234, 0x5678], width=2).to_hex_array(width=2)
|
|
|
60
60
|
# ['1234', '5678']
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
## Configurable formats
|
|
64
|
+
|
|
65
|
+
For reusable conversions, construct format specs with options:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
hx.convert("de ad be ef", from_=hx.Hex(), to=hx.Bytes())
|
|
69
|
+
# b'\xde\xad\xbe\xef'
|
|
70
|
+
|
|
71
|
+
hx.convert("data", from_=hx.Text(), to=hx.Hex(prefix=True))
|
|
72
|
+
# '0x64617461'
|
|
73
|
+
|
|
74
|
+
hx.convert("π", from_=hx.Text(encoding="utf-8"), to=hx.Hex())
|
|
75
|
+
# 'cf80'
|
|
76
|
+
|
|
77
|
+
hx.convert("-_8", from_=hx.Base64(urlsafe=True, padding=False), to=hx.Hex())
|
|
78
|
+
# 'fbff'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Old marker-style conversions still work:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
hx.convert("data", from_=hx.Text, to=hx.HexString)
|
|
85
|
+
# '64617461'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Composable pipelines
|
|
89
|
+
|
|
90
|
+
Use `pipeline()` when you want a readable builder:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
conv = (
|
|
94
|
+
hx.pipeline()
|
|
95
|
+
.from_(hx.Hex())
|
|
96
|
+
.chunk(2)
|
|
97
|
+
.to(hx.IntArray(width=2))
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
conv("12345678")
|
|
101
|
+
# [4660, 22136]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Use `>>` when you want compact composition:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
conv = hx.Hex() >> hx.Chunk(2) >> hx.HexArray()
|
|
108
|
+
|
|
109
|
+
conv("12345678")
|
|
110
|
+
# ['1234', '5678']
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Available transforms:
|
|
114
|
+
|
|
115
|
+
- `Chunk(width, strict=True)` / `Group(width, strict=True)` — set downstream grouping.
|
|
116
|
+
- `Pad.left(width=..., byte=0)` / `Pad.right(block_size=..., byte=0)` — pad bytes.
|
|
117
|
+
- `Reverse()` — reverse byte order.
|
|
118
|
+
|
|
119
|
+
Examples:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
(hx.Hex() >> hx.Pad.left(width=4) >> hx.Hex())("dead")
|
|
123
|
+
# '0000dead'
|
|
124
|
+
|
|
125
|
+
(hx.Hex() >> hx.Reverse() >> hx.Hex())("deadbeef")
|
|
126
|
+
# 'efbeadde'
|
|
127
|
+
```
|
|
128
|
+
|
|
63
129
|
## Why explicit source helpers?
|
|
64
130
|
|
|
65
131
|
Some inputs are impossible to infer safely:
|
|
@@ -113,6 +179,67 @@ conv([4660, 22136])
|
|
|
113
179
|
# ['0x1234', '0x5678']
|
|
114
180
|
```
|
|
115
181
|
|
|
182
|
+
## Extra formats
|
|
183
|
+
|
|
184
|
+
Base encodings:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
hx.from_text("data").to(hx.Base32(padding=False))
|
|
188
|
+
# 'MRQXIYI'
|
|
189
|
+
|
|
190
|
+
hx.from_text("data").to(hx.Base85())
|
|
191
|
+
# 'WMOn+'
|
|
192
|
+
|
|
193
|
+
hx.from_text("data").to(hx.Ascii85())
|
|
194
|
+
# 'A79Rg'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Escaped byte strings:
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
hx.from_escaped(r"\xde\xad").hex
|
|
201
|
+
# 'dead'
|
|
202
|
+
|
|
203
|
+
hx.from_hex("dead").to(hx.Escaped())
|
|
204
|
+
# '\\xde\\xad'
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Hexdump:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
dump = hx.from_hex("deadbeef").to(hx.Hexdump(width=2))
|
|
211
|
+
hx.from_hexdump(dump).hex
|
|
212
|
+
# 'deadbeef'
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Python `struct` packing/unpacking:
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
hx.from_struct((0x1234, 0x5678), fmt=">HH").hex
|
|
219
|
+
# '12345678'
|
|
220
|
+
|
|
221
|
+
hx.from_hex("12345678").to(hx.Struct(">HH"))
|
|
222
|
+
# (4660, 22136)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Bits:
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
hx.from_bits([1, 0, 1]).hex
|
|
229
|
+
# '05'
|
|
230
|
+
|
|
231
|
+
hx.from_hex("05").to(hx.Bits())
|
|
232
|
+
# [0, 0, 0, 0, 0, 1, 0, 1]
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Automatic inference with explanations:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
result = hx.infer("0xdead")
|
|
239
|
+
result.format, result.confidence, result.value.hex
|
|
240
|
+
# (<class 'hexconv._core.HexString'>, 0.75, 'dead')
|
|
241
|
+
```
|
|
242
|
+
|
|
116
243
|
## Supported source helpers
|
|
117
244
|
|
|
118
245
|
- `from_bytes(value)`
|
|
@@ -126,7 +253,15 @@ conv([4660, 22136])
|
|
|
126
253
|
- `from_text(value)`
|
|
127
254
|
- `from_binary(value)`
|
|
128
255
|
- `from_base64(value)`
|
|
256
|
+
- `from_base32(value)`
|
|
257
|
+
- `from_base85(value)`
|
|
258
|
+
- `from_ascii85(value)`
|
|
259
|
+
- `from_escaped(value)`
|
|
260
|
+
- `from_hexdump(value)`
|
|
261
|
+
- `from_struct(value, fmt=...)`
|
|
262
|
+
- `from_bits(value)`
|
|
129
263
|
- `from_auto(value)`
|
|
264
|
+
- `infer(value)`
|
|
130
265
|
|
|
131
266
|
## Common output methods
|
|
132
267
|
|
|
@@ -142,4 +277,11 @@ conv([4660, 22136])
|
|
|
142
277
|
- `to_text(encoding="ascii", errors="strict")`
|
|
143
278
|
- `to_binary(sep="")`
|
|
144
279
|
- `to_base64()`
|
|
280
|
+
- `to_base32()`
|
|
281
|
+
- `to_base85()`
|
|
282
|
+
- `to_ascii85()`
|
|
283
|
+
- `to_escaped()`
|
|
284
|
+
- `to_hexdump()`
|
|
285
|
+
- `to_struct(fmt)`
|
|
286
|
+
- `to_bits()`
|
|
145
287
|
- `to(format_marker, **options)`
|
|
@@ -31,6 +31,72 @@ hx.from_int_array([0x1234, 0x5678], width=2).to_hex_array(width=2)
|
|
|
31
31
|
# ['1234', '5678']
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Configurable formats
|
|
35
|
+
|
|
36
|
+
For reusable conversions, construct format specs with options:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
hx.convert("de ad be ef", from_=hx.Hex(), to=hx.Bytes())
|
|
40
|
+
# b'\xde\xad\xbe\xef'
|
|
41
|
+
|
|
42
|
+
hx.convert("data", from_=hx.Text(), to=hx.Hex(prefix=True))
|
|
43
|
+
# '0x64617461'
|
|
44
|
+
|
|
45
|
+
hx.convert("π", from_=hx.Text(encoding="utf-8"), to=hx.Hex())
|
|
46
|
+
# 'cf80'
|
|
47
|
+
|
|
48
|
+
hx.convert("-_8", from_=hx.Base64(urlsafe=True, padding=False), to=hx.Hex())
|
|
49
|
+
# 'fbff'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Old marker-style conversions still work:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
hx.convert("data", from_=hx.Text, to=hx.HexString)
|
|
56
|
+
# '64617461'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Composable pipelines
|
|
60
|
+
|
|
61
|
+
Use `pipeline()` when you want a readable builder:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
conv = (
|
|
65
|
+
hx.pipeline()
|
|
66
|
+
.from_(hx.Hex())
|
|
67
|
+
.chunk(2)
|
|
68
|
+
.to(hx.IntArray(width=2))
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
conv("12345678")
|
|
72
|
+
# [4660, 22136]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use `>>` when you want compact composition:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
conv = hx.Hex() >> hx.Chunk(2) >> hx.HexArray()
|
|
79
|
+
|
|
80
|
+
conv("12345678")
|
|
81
|
+
# ['1234', '5678']
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Available transforms:
|
|
85
|
+
|
|
86
|
+
- `Chunk(width, strict=True)` / `Group(width, strict=True)` — set downstream grouping.
|
|
87
|
+
- `Pad.left(width=..., byte=0)` / `Pad.right(block_size=..., byte=0)` — pad bytes.
|
|
88
|
+
- `Reverse()` — reverse byte order.
|
|
89
|
+
|
|
90
|
+
Examples:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
(hx.Hex() >> hx.Pad.left(width=4) >> hx.Hex())("dead")
|
|
94
|
+
# '0000dead'
|
|
95
|
+
|
|
96
|
+
(hx.Hex() >> hx.Reverse() >> hx.Hex())("deadbeef")
|
|
97
|
+
# 'efbeadde'
|
|
98
|
+
```
|
|
99
|
+
|
|
34
100
|
## Why explicit source helpers?
|
|
35
101
|
|
|
36
102
|
Some inputs are impossible to infer safely:
|
|
@@ -84,6 +150,67 @@ conv([4660, 22136])
|
|
|
84
150
|
# ['0x1234', '0x5678']
|
|
85
151
|
```
|
|
86
152
|
|
|
153
|
+
## Extra formats
|
|
154
|
+
|
|
155
|
+
Base encodings:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
hx.from_text("data").to(hx.Base32(padding=False))
|
|
159
|
+
# 'MRQXIYI'
|
|
160
|
+
|
|
161
|
+
hx.from_text("data").to(hx.Base85())
|
|
162
|
+
# 'WMOn+'
|
|
163
|
+
|
|
164
|
+
hx.from_text("data").to(hx.Ascii85())
|
|
165
|
+
# 'A79Rg'
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Escaped byte strings:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
hx.from_escaped(r"\xde\xad").hex
|
|
172
|
+
# 'dead'
|
|
173
|
+
|
|
174
|
+
hx.from_hex("dead").to(hx.Escaped())
|
|
175
|
+
# '\\xde\\xad'
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Hexdump:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
dump = hx.from_hex("deadbeef").to(hx.Hexdump(width=2))
|
|
182
|
+
hx.from_hexdump(dump).hex
|
|
183
|
+
# 'deadbeef'
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Python `struct` packing/unpacking:
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
hx.from_struct((0x1234, 0x5678), fmt=">HH").hex
|
|
190
|
+
# '12345678'
|
|
191
|
+
|
|
192
|
+
hx.from_hex("12345678").to(hx.Struct(">HH"))
|
|
193
|
+
# (4660, 22136)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Bits:
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
hx.from_bits([1, 0, 1]).hex
|
|
200
|
+
# '05'
|
|
201
|
+
|
|
202
|
+
hx.from_hex("05").to(hx.Bits())
|
|
203
|
+
# [0, 0, 0, 0, 0, 1, 0, 1]
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Automatic inference with explanations:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
result = hx.infer("0xdead")
|
|
210
|
+
result.format, result.confidence, result.value.hex
|
|
211
|
+
# (<class 'hexconv._core.HexString'>, 0.75, 'dead')
|
|
212
|
+
```
|
|
213
|
+
|
|
87
214
|
## Supported source helpers
|
|
88
215
|
|
|
89
216
|
- `from_bytes(value)`
|
|
@@ -97,7 +224,15 @@ conv([4660, 22136])
|
|
|
97
224
|
- `from_text(value)`
|
|
98
225
|
- `from_binary(value)`
|
|
99
226
|
- `from_base64(value)`
|
|
227
|
+
- `from_base32(value)`
|
|
228
|
+
- `from_base85(value)`
|
|
229
|
+
- `from_ascii85(value)`
|
|
230
|
+
- `from_escaped(value)`
|
|
231
|
+
- `from_hexdump(value)`
|
|
232
|
+
- `from_struct(value, fmt=...)`
|
|
233
|
+
- `from_bits(value)`
|
|
100
234
|
- `from_auto(value)`
|
|
235
|
+
- `infer(value)`
|
|
101
236
|
|
|
102
237
|
## Common output methods
|
|
103
238
|
|
|
@@ -113,4 +248,11 @@ conv([4660, 22136])
|
|
|
113
248
|
- `to_text(encoding="ascii", errors="strict")`
|
|
114
249
|
- `to_binary(sep="")`
|
|
115
250
|
- `to_base64()`
|
|
251
|
+
- `to_base32()`
|
|
252
|
+
- `to_base85()`
|
|
253
|
+
- `to_ascii85()`
|
|
254
|
+
- `to_escaped()`
|
|
255
|
+
- `to_hexdump()`
|
|
256
|
+
- `to_struct(fmt)`
|
|
257
|
+
- `to_bits()`
|
|
116
258
|
- `to(format_marker, **options)`
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hexconv"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Pythonic conversion toolkit for bytes, hex, integers, arrays, binary strings, base64, and text."
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -3,73 +3,139 @@
|
|
|
3
3
|
from ._core import (
|
|
4
4
|
ASCIIText,
|
|
5
5
|
Auto,
|
|
6
|
+
AutoResult,
|
|
7
|
+
Ascii85,
|
|
8
|
+
Ascii85String,
|
|
6
9
|
Base64String,
|
|
10
|
+
Base64,
|
|
11
|
+
Base32,
|
|
12
|
+
Base32String,
|
|
13
|
+
Base85,
|
|
14
|
+
Base85String,
|
|
7
15
|
BinaryString,
|
|
16
|
+
Binary,
|
|
17
|
+
BitArray,
|
|
18
|
+
Bits,
|
|
8
19
|
Bytes,
|
|
9
20
|
BytesArray,
|
|
10
21
|
BytesString,
|
|
22
|
+
Chunk,
|
|
11
23
|
Converter,
|
|
12
24
|
DecimalInt,
|
|
13
25
|
DecimalIntArray,
|
|
26
|
+
Escaped,
|
|
27
|
+
EscapedString,
|
|
28
|
+
Group,
|
|
29
|
+
Hex,
|
|
14
30
|
HexArray,
|
|
15
31
|
HexConvError,
|
|
32
|
+
HexDump,
|
|
33
|
+
Hexdump,
|
|
16
34
|
HexInt,
|
|
17
35
|
HexNumbersArray,
|
|
18
36
|
HexString,
|
|
19
37
|
Int,
|
|
20
38
|
IntArray,
|
|
21
39
|
LargeHexNumber,
|
|
40
|
+
Pad,
|
|
41
|
+
Pipeline,
|
|
22
42
|
RawString,
|
|
43
|
+
Reverse,
|
|
44
|
+
Struct,
|
|
45
|
+
StructFormat,
|
|
23
46
|
Text,
|
|
47
|
+
Transform,
|
|
24
48
|
Value,
|
|
25
49
|
convert,
|
|
50
|
+
from_ascii85,
|
|
26
51
|
from_auto,
|
|
52
|
+
from_base32,
|
|
27
53
|
from_base64,
|
|
54
|
+
from_base85,
|
|
28
55
|
from_binary,
|
|
56
|
+
from_bits,
|
|
29
57
|
from_bytes,
|
|
30
58
|
from_bytes_array,
|
|
31
59
|
from_bytes_string,
|
|
60
|
+
from_escaped,
|
|
32
61
|
from_hex,
|
|
33
62
|
from_hex_array,
|
|
34
63
|
from_hex_int,
|
|
64
|
+
from_hexdump,
|
|
35
65
|
from_int,
|
|
36
66
|
from_int_array,
|
|
67
|
+
from_struct,
|
|
37
68
|
from_text,
|
|
69
|
+
infer,
|
|
70
|
+
pipeline,
|
|
38
71
|
)
|
|
39
72
|
|
|
40
73
|
__all__ = [
|
|
41
74
|
"ASCIIText",
|
|
42
75
|
"Auto",
|
|
76
|
+
"AutoResult",
|
|
77
|
+
"Ascii85",
|
|
78
|
+
"Ascii85String",
|
|
79
|
+
"Base32",
|
|
80
|
+
"Base32String",
|
|
43
81
|
"Base64String",
|
|
82
|
+
"Base64",
|
|
83
|
+
"Base85",
|
|
84
|
+
"Base85String",
|
|
85
|
+
"Binary",
|
|
44
86
|
"BinaryString",
|
|
87
|
+
"BitArray",
|
|
88
|
+
"Bits",
|
|
45
89
|
"Bytes",
|
|
46
90
|
"BytesArray",
|
|
47
91
|
"BytesString",
|
|
92
|
+
"Chunk",
|
|
48
93
|
"Converter",
|
|
49
94
|
"DecimalInt",
|
|
50
95
|
"DecimalIntArray",
|
|
96
|
+
"Escaped",
|
|
97
|
+
"EscapedString",
|
|
98
|
+
"Group",
|
|
99
|
+
"Hex",
|
|
51
100
|
"HexArray",
|
|
52
101
|
"HexConvError",
|
|
102
|
+
"HexDump",
|
|
103
|
+
"Hexdump",
|
|
53
104
|
"HexInt",
|
|
54
105
|
"HexNumbersArray",
|
|
55
106
|
"HexString",
|
|
56
107
|
"Int",
|
|
57
108
|
"IntArray",
|
|
58
109
|
"LargeHexNumber",
|
|
110
|
+
"Pad",
|
|
111
|
+
"Pipeline",
|
|
59
112
|
"RawString",
|
|
113
|
+
"Reverse",
|
|
114
|
+
"Struct",
|
|
115
|
+
"StructFormat",
|
|
60
116
|
"Text",
|
|
117
|
+
"Transform",
|
|
61
118
|
"Value",
|
|
62
119
|
"convert",
|
|
120
|
+
"from_ascii85",
|
|
63
121
|
"from_auto",
|
|
122
|
+
"from_base32",
|
|
64
123
|
"from_base64",
|
|
124
|
+
"from_base85",
|
|
65
125
|
"from_binary",
|
|
126
|
+
"from_bits",
|
|
66
127
|
"from_bytes",
|
|
67
128
|
"from_bytes_array",
|
|
68
129
|
"from_bytes_string",
|
|
130
|
+
"from_escaped",
|
|
69
131
|
"from_hex",
|
|
70
132
|
"from_hex_array",
|
|
71
133
|
"from_hex_int",
|
|
134
|
+
"from_hexdump",
|
|
72
135
|
"from_int",
|
|
73
136
|
"from_int_array",
|
|
137
|
+
"from_struct",
|
|
74
138
|
"from_text",
|
|
139
|
+
"infer",
|
|
140
|
+
"pipeline",
|
|
75
141
|
]
|