crcmod-plus 2.0.0__tar.gz → 2.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.
- {crcmod-plus-2.0.0/src/crcmod_plus.egg-info → crcmod_plus-2.2.0}/PKG-INFO +9 -4
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/lib/_crcfunext.c +5 -1
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/pyproject.toml +15 -10
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/setup.py +11 -1
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod/_crcfunpy.py +15 -11
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod/_version.py +1 -1
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod/crcmod.py +73 -33
- crcmod_plus-2.2.0/src/crcmod/predefined.py +189 -0
- crcmod_plus-2.2.0/src/crcmod/py.typed +0 -0
- crcmod_plus-2.2.0/src/crcmod/types.py +46 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0/src/crcmod_plus.egg-info}/PKG-INFO +9 -4
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod_plus.egg-info/SOURCES.txt +2 -0
- crcmod_plus-2.2.0/src/crcmod_plus.egg-info/requires.txt +6 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/tests/test_crcmod.py +1 -2
- crcmod-plus-2.0.0/src/crcmod/predefined.py +0 -182
- crcmod-plus-2.0.0/src/crcmod_plus.egg-info/requires.txt +0 -3
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/LICENSE.txt +0 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/README.md +0 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/setup.cfg +0 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod/__init__.py +0 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod_plus.egg-info/dependency_links.txt +0 -0
- {crcmod-plus-2.0.0 → crcmod_plus-2.2.0}/src/crcmod_plus.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: crcmod-plus
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: CRC generator - modernized
|
|
5
5
|
Author-email: Ray Buvel <rlbuvel@gmail.com>
|
|
6
6
|
Maintainer-email: Tamas Nepusz <tamas@sxd.hu>
|
|
@@ -27,8 +27,10 @@ License: -----------------------------------------------------------------------
|
|
|
27
27
|
SOFTWARE.
|
|
28
28
|
----------------------------------------------------------------------------
|
|
29
29
|
|
|
30
|
-
Project-URL: Repository, https://github.com/ntamas/crcmod-plus
|
|
31
30
|
Project-URL: Changelog, https://github.com/ntamas/crcmod-plus/blob/main/CHANGELOG.md
|
|
31
|
+
Project-URL: Documentation, https://github.com/ntamas/crcmod-plus#readme
|
|
32
|
+
Project-URL: Issues, https://github.com/ntamas/crcmod-plus/issues
|
|
33
|
+
Project-URL: Source, https://github.com/ntamas/crcmod-plus
|
|
32
34
|
Classifier: Development Status :: 5 - Production/Stable
|
|
33
35
|
Classifier: Intended Audience :: Developers
|
|
34
36
|
Classifier: Intended Audience :: Education
|
|
@@ -52,8 +54,11 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
52
54
|
Classifier: Topic :: Utilities
|
|
53
55
|
Requires-Python: >=3.7
|
|
54
56
|
Description-Content-Type: text/markdown
|
|
55
|
-
Provides-Extra: dev
|
|
56
57
|
License-File: LICENSE.txt
|
|
58
|
+
Requires-Dist: typing_extensions; python_version < "3.8"
|
|
59
|
+
Provides-Extra: dev
|
|
60
|
+
Requires-Dist: pytest; extra == "dev"
|
|
61
|
+
Dynamic: license-file
|
|
57
62
|
|
|
58
63
|
[](https://github.com/ntamas/crcmod-plus/actions/workflows/build.yml)
|
|
59
64
|
|
|
@@ -604,5 +604,9 @@ PyInit__crcfunext(void)
|
|
|
604
604
|
Py_FatalError("crcfunext: One of the data types is invalid");
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
-
|
|
607
|
+
PyObject* mod = PyModule_Create(&moduleDef);
|
|
608
|
+
#ifdef Py_GIL_DISABLED
|
|
609
|
+
PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED);
|
|
610
|
+
#endif
|
|
611
|
+
return mod;
|
|
608
612
|
}
|
|
@@ -4,17 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "crcmod-plus"
|
|
7
|
-
version = "2.
|
|
8
|
-
authors = [
|
|
9
|
-
{name = "Ray Buvel", email = "rlbuvel@gmail.com"}
|
|
10
|
-
]
|
|
7
|
+
version = "2.2.0"
|
|
8
|
+
authors = [{ name = "Ray Buvel", email = "rlbuvel@gmail.com" }]
|
|
11
9
|
description = "CRC generator - modernized"
|
|
12
10
|
readme = "README.md"
|
|
13
11
|
requires-python = ">=3.7"
|
|
14
|
-
maintainers = [
|
|
15
|
-
|
|
16
|
-
]
|
|
17
|
-
license = {file = "LICENSE.txt"}
|
|
12
|
+
maintainers = [{ name = "Tamas Nepusz", email = "tamas@sxd.hu" }]
|
|
13
|
+
license = { file = "LICENSE.txt" }
|
|
18
14
|
classifiers = [
|
|
19
15
|
"Development Status :: 5 - Production/Stable",
|
|
20
16
|
"Intended Audience :: Developers",
|
|
@@ -38,20 +34,29 @@ classifiers = [
|
|
|
38
34
|
"Topic :: Scientific/Engineering :: Mathematics",
|
|
39
35
|
"Topic :: Utilities",
|
|
40
36
|
]
|
|
37
|
+
dependencies = ["typing_extensions; python_version < '3.8'"]
|
|
41
38
|
|
|
42
39
|
[project.urls]
|
|
43
|
-
Repository = "https://github.com/ntamas/crcmod-plus"
|
|
44
40
|
Changelog = "https://github.com/ntamas/crcmod-plus/blob/main/CHANGELOG.md"
|
|
41
|
+
Documentation = "https://github.com/ntamas/crcmod-plus#readme"
|
|
42
|
+
Issues = "https://github.com/ntamas/crcmod-plus/issues"
|
|
43
|
+
Source = "https://github.com/ntamas/crcmod-plus"
|
|
45
44
|
|
|
46
45
|
[project.optional-dependencies]
|
|
47
46
|
dev = ["pytest"]
|
|
48
47
|
|
|
49
|
-
[tool.
|
|
48
|
+
[tool.cibuildwheel]
|
|
49
|
+
enable = ["cpython-freethreading", "pypy"]
|
|
50
|
+
|
|
51
|
+
[tool.ruff.lint.extend-per-file-ignores]
|
|
50
52
|
"predefined.py" = ["E501"]
|
|
51
53
|
|
|
52
54
|
[tool.setuptools.packages.find]
|
|
53
55
|
where = ["src"]
|
|
54
56
|
|
|
57
|
+
[tool.setuptools.package-data]
|
|
58
|
+
crcmod = ["py.typed"]
|
|
59
|
+
|
|
55
60
|
[tool.tox]
|
|
56
61
|
legacy_tox_ini = """
|
|
57
62
|
[tox]
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
from platform import python_implementation
|
|
2
2
|
from setuptools import setup, Extension
|
|
3
3
|
from sys import version_info
|
|
4
|
+
import sysconfig
|
|
4
5
|
from wheel.bdist_wheel import bdist_wheel
|
|
5
6
|
|
|
7
|
+
|
|
8
|
+
def is_freethread():
|
|
9
|
+
if sysconfig.get_config_var("Py_GIL_DISABLED"):
|
|
10
|
+
return True
|
|
11
|
+
return False
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# fmt: off
|
|
7
15
|
can_use_limited_api = (
|
|
8
16
|
python_implementation() == "CPython" and
|
|
9
|
-
version_info >= (3, 11, 0)
|
|
17
|
+
version_info >= (3, 11, 0) and
|
|
18
|
+
not is_freethread()
|
|
10
19
|
)
|
|
11
20
|
# fmt: on
|
|
12
21
|
|
|
@@ -32,6 +41,7 @@ setup_args = dict(
|
|
|
32
41
|
ext_modules=[
|
|
33
42
|
Extension("crcmod._crcfunext", ["lib/_crcfunext.c"], **extension_kwargs)
|
|
34
43
|
],
|
|
44
|
+
package_dir={"": "src"},
|
|
35
45
|
cmdclass={"bdist_wheel": bdist_wheel_abi3},
|
|
36
46
|
)
|
|
37
47
|
|
|
@@ -26,8 +26,12 @@
|
|
|
26
26
|
# SOFTWARE.
|
|
27
27
|
# -----------------------------------------------------------------------------
|
|
28
28
|
|
|
29
|
+
from typing import Sequence
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
from .types import Buffer
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _get_buffer_view(in_obj: Buffer) -> memoryview:
|
|
31
35
|
if isinstance(in_obj, str):
|
|
32
36
|
raise TypeError("Unicode-objects must be encoded before calculating a CRC")
|
|
33
37
|
mv = memoryview(in_obj)
|
|
@@ -36,7 +40,7 @@ def _get_buffer_view(in_obj):
|
|
|
36
40
|
return mv
|
|
37
41
|
|
|
38
42
|
|
|
39
|
-
def _crc8(data, crc, table):
|
|
43
|
+
def _crc8(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
40
44
|
mv = _get_buffer_view(data)
|
|
41
45
|
crc = crc & 0xFF
|
|
42
46
|
for x in mv.tobytes():
|
|
@@ -44,7 +48,7 @@ def _crc8(data, crc, table):
|
|
|
44
48
|
return crc
|
|
45
49
|
|
|
46
50
|
|
|
47
|
-
def _crc8r(data, crc, table):
|
|
51
|
+
def _crc8r(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
48
52
|
mv = _get_buffer_view(data)
|
|
49
53
|
crc = crc & 0xFF
|
|
50
54
|
for x in mv.tobytes():
|
|
@@ -52,7 +56,7 @@ def _crc8r(data, crc, table):
|
|
|
52
56
|
return crc
|
|
53
57
|
|
|
54
58
|
|
|
55
|
-
def _crc16(data, crc, table):
|
|
59
|
+
def _crc16(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
56
60
|
mv = _get_buffer_view(data)
|
|
57
61
|
crc = crc & 0xFFFF
|
|
58
62
|
for x in mv.tobytes():
|
|
@@ -60,7 +64,7 @@ def _crc16(data, crc, table):
|
|
|
60
64
|
return crc
|
|
61
65
|
|
|
62
66
|
|
|
63
|
-
def _crc16r(data, crc, table):
|
|
67
|
+
def _crc16r(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
64
68
|
mv = _get_buffer_view(data)
|
|
65
69
|
crc = crc & 0xFFFF
|
|
66
70
|
for x in mv.tobytes():
|
|
@@ -68,7 +72,7 @@ def _crc16r(data, crc, table):
|
|
|
68
72
|
return crc
|
|
69
73
|
|
|
70
74
|
|
|
71
|
-
def _crc24(data, crc, table):
|
|
75
|
+
def _crc24(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
72
76
|
mv = _get_buffer_view(data)
|
|
73
77
|
crc = crc & 0xFFFFFF
|
|
74
78
|
for x in mv.tobytes():
|
|
@@ -76,7 +80,7 @@ def _crc24(data, crc, table):
|
|
|
76
80
|
return crc
|
|
77
81
|
|
|
78
82
|
|
|
79
|
-
def _crc24r(data, crc, table):
|
|
83
|
+
def _crc24r(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
80
84
|
mv = _get_buffer_view(data)
|
|
81
85
|
crc = crc & 0xFFFFFF
|
|
82
86
|
for x in mv.tobytes():
|
|
@@ -84,7 +88,7 @@ def _crc24r(data, crc, table):
|
|
|
84
88
|
return crc
|
|
85
89
|
|
|
86
90
|
|
|
87
|
-
def _crc32(data, crc, table):
|
|
91
|
+
def _crc32(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
88
92
|
mv = _get_buffer_view(data)
|
|
89
93
|
crc = crc & 0xFFFFFFFF
|
|
90
94
|
for x in mv.tobytes():
|
|
@@ -92,7 +96,7 @@ def _crc32(data, crc, table):
|
|
|
92
96
|
return crc
|
|
93
97
|
|
|
94
98
|
|
|
95
|
-
def _crc32r(data, crc, table):
|
|
99
|
+
def _crc32r(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
96
100
|
mv = _get_buffer_view(data)
|
|
97
101
|
crc = crc & 0xFFFFFFFF
|
|
98
102
|
for x in mv.tobytes():
|
|
@@ -100,7 +104,7 @@ def _crc32r(data, crc, table):
|
|
|
100
104
|
return crc
|
|
101
105
|
|
|
102
106
|
|
|
103
|
-
def _crc64(data, crc, table):
|
|
107
|
+
def _crc64(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
104
108
|
mv = _get_buffer_view(data)
|
|
105
109
|
crc = crc & 0xFFFFFFFFFFFFFFFF
|
|
106
110
|
for x in mv.tobytes():
|
|
@@ -108,7 +112,7 @@ def _crc64(data, crc, table):
|
|
|
108
112
|
return crc
|
|
109
113
|
|
|
110
114
|
|
|
111
|
-
def _crc64r(data, crc, table):
|
|
115
|
+
def _crc64r(data: Buffer, crc: int, table: Sequence[int]) -> int:
|
|
112
116
|
mv = _get_buffer_view(data)
|
|
113
117
|
crc = crc & 0xFFFFFFFFFFFFFFFF
|
|
114
118
|
for x in mv.tobytes():
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version_tuple__ = (2,
|
|
1
|
+
__version_tuple__ = (2, 2, 0)
|
|
2
2
|
__version__ = ".".join(map(str, __version_tuple__))
|
|
@@ -37,6 +37,10 @@ except ImportError:
|
|
|
37
37
|
|
|
38
38
|
import struct
|
|
39
39
|
|
|
40
|
+
from typing import Dict, IO, List, Optional, Sequence, Tuple
|
|
41
|
+
|
|
42
|
+
from .types import Buffer, CrcFun, CrcFunNoDefaultArgs
|
|
43
|
+
|
|
40
44
|
|
|
41
45
|
# -----------------------------------------------------------------------------
|
|
42
46
|
class Crc:
|
|
@@ -75,7 +79,25 @@ class Crc:
|
|
|
75
79
|
CRC algorithms. Defaults to zero.
|
|
76
80
|
"""
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
digest_size: int
|
|
83
|
+
initCrc: int
|
|
84
|
+
poly: int
|
|
85
|
+
reverse: bool
|
|
86
|
+
xorOut: int
|
|
87
|
+
|
|
88
|
+
crcValue: int
|
|
89
|
+
|
|
90
|
+
_crc: CrcFun
|
|
91
|
+
table: List[int]
|
|
92
|
+
|
|
93
|
+
def __init__(
|
|
94
|
+
self,
|
|
95
|
+
poly: int,
|
|
96
|
+
initCrc: int = ~0,
|
|
97
|
+
rev: bool = True,
|
|
98
|
+
xorOut: int = 0,
|
|
99
|
+
initialize: bool = True,
|
|
100
|
+
):
|
|
79
101
|
if not initialize:
|
|
80
102
|
# Don't want to perform the initialization when using new or copy
|
|
81
103
|
# to create a new instance.
|
|
@@ -95,8 +117,8 @@ class Crc:
|
|
|
95
117
|
|
|
96
118
|
self.crcValue = self.initCrc
|
|
97
119
|
|
|
98
|
-
def __str__(self):
|
|
99
|
-
lst = []
|
|
120
|
+
def __str__(self) -> str:
|
|
121
|
+
lst: List[str] = []
|
|
100
122
|
lst.append("poly = 0x%X" % self.poly)
|
|
101
123
|
lst.append("reverse = %s" % self.reverse)
|
|
102
124
|
fmt = "0x%%0%dX" % (self.digest_size * 2)
|
|
@@ -105,13 +127,13 @@ class Crc:
|
|
|
105
127
|
lst.append("crcValue = %s" % (fmt % self.crcValue))
|
|
106
128
|
return "\n".join(lst)
|
|
107
129
|
|
|
108
|
-
def new(self, arg=None):
|
|
130
|
+
def new(self, arg: Optional[Buffer] = None) -> "Crc":
|
|
109
131
|
"""Create a new instance of the Crc class initialized to the same
|
|
110
132
|
values as the original instance. The current CRC is set to the initial
|
|
111
133
|
value. If a string is provided in the optional arg parameter, it is
|
|
112
134
|
passed to the update method.
|
|
113
135
|
"""
|
|
114
|
-
n = Crc(poly=None, initialize=False)
|
|
136
|
+
n = Crc(poly=None, initialize=False) # type: ignore
|
|
115
137
|
n._crc = self._crc
|
|
116
138
|
n.digest_size = self.digest_size
|
|
117
139
|
n.initCrc = self.initCrc
|
|
@@ -124,7 +146,7 @@ class Crc:
|
|
|
124
146
|
n.update(arg)
|
|
125
147
|
return n
|
|
126
148
|
|
|
127
|
-
def copy(self):
|
|
149
|
+
def copy(self) -> "Crc":
|
|
128
150
|
"""Create a new instance of the Crc class initialized to the same
|
|
129
151
|
values as the original instance. The current CRC is set to the current
|
|
130
152
|
value. This allows multiple CRC calculations using a common initial
|
|
@@ -134,19 +156,19 @@ class Crc:
|
|
|
134
156
|
c.crcValue = self.crcValue
|
|
135
157
|
return c
|
|
136
158
|
|
|
137
|
-
def update(self, data):
|
|
159
|
+
def update(self, data: Buffer) -> None:
|
|
138
160
|
"""Update the current CRC value using the string specified as the data
|
|
139
161
|
parameter.
|
|
140
162
|
"""
|
|
141
|
-
self.crcValue = self._crc(data, self.crcValue)
|
|
163
|
+
self.crcValue = self._crc(data, self.crcValue) # type: ignore
|
|
142
164
|
|
|
143
|
-
def digest(self):
|
|
165
|
+
def digest(self) -> bytes:
|
|
144
166
|
"""Return the current CRC value as a string of bytes. The length of
|
|
145
167
|
this string is specified in the digest_size attribute.
|
|
146
168
|
"""
|
|
147
169
|
n = self.digest_size
|
|
148
170
|
crc = self.crcValue
|
|
149
|
-
lst = []
|
|
171
|
+
lst: List[int] = []
|
|
150
172
|
while n > 0:
|
|
151
173
|
lst.append(crc & 0xFF)
|
|
152
174
|
crc = crc >> 8
|
|
@@ -154,13 +176,13 @@ class Crc:
|
|
|
154
176
|
lst.reverse()
|
|
155
177
|
return bytes(lst)
|
|
156
178
|
|
|
157
|
-
def hexdigest(self):
|
|
179
|
+
def hexdigest(self) -> str:
|
|
158
180
|
"""Return the current CRC value as a string of hex digits. The length
|
|
159
181
|
of this string is twice the digest_size attribute.
|
|
160
182
|
"""
|
|
161
183
|
n = self.digest_size
|
|
162
184
|
crc = self.crcValue
|
|
163
|
-
lst = []
|
|
185
|
+
lst: List[str] = []
|
|
164
186
|
while n > 0:
|
|
165
187
|
lst.append("%02X" % (crc & 0xFF))
|
|
166
188
|
crc = crc >> 8
|
|
@@ -168,7 +190,13 @@ class Crc:
|
|
|
168
190
|
lst.reverse()
|
|
169
191
|
return "".join(lst)
|
|
170
192
|
|
|
171
|
-
def generateCode(
|
|
193
|
+
def generateCode(
|
|
194
|
+
self,
|
|
195
|
+
functionName: str,
|
|
196
|
+
out: IO[str],
|
|
197
|
+
dataType: Optional[str] = None,
|
|
198
|
+
crcType: Optional[str] = None,
|
|
199
|
+
) -> None:
|
|
172
200
|
"""Generate a C/C++ function.
|
|
173
201
|
|
|
174
202
|
functionName -- String specifying the name of the function.
|
|
@@ -215,7 +243,7 @@ class Crc:
|
|
|
215
243
|
# Select the number of entries per row in the output code.
|
|
216
244
|
n = {1: 8, 2: 8, 3: 4, 4: 4, 8: 2}[self.digest_size]
|
|
217
245
|
|
|
218
|
-
lst = []
|
|
246
|
+
lst: List[str] = []
|
|
219
247
|
for i, val in enumerate(self.table):
|
|
220
248
|
if (i % n) == 0:
|
|
221
249
|
lst.append("\n ")
|
|
@@ -255,7 +283,7 @@ class Crc:
|
|
|
255
283
|
|
|
256
284
|
|
|
257
285
|
# -----------------------------------------------------------------------------
|
|
258
|
-
def mkCrcFun(poly, initCrc
|
|
286
|
+
def mkCrcFun(poly: int, initCrc: int = ~0, rev: bool = True, xorOut: int = 0) -> CrcFun:
|
|
259
287
|
"""Return a function that computes the CRC using the specified polynomial.
|
|
260
288
|
|
|
261
289
|
poly -- integer representation of the generator polynomial
|
|
@@ -283,7 +311,7 @@ def mkCrcFun(poly, initCrc=~0, rev=True, xorOut=0):
|
|
|
283
311
|
# of bits in the CRC.
|
|
284
312
|
|
|
285
313
|
|
|
286
|
-
def _verifyPoly(poly):
|
|
314
|
+
def _verifyPoly(poly: int) -> int:
|
|
287
315
|
msg = "The degree of the polynomial must be 8, 16, 24, 32 or 64"
|
|
288
316
|
for n in (8, 16, 24, 32, 64):
|
|
289
317
|
low = 1 << n
|
|
@@ -297,7 +325,7 @@ def _verifyPoly(poly):
|
|
|
297
325
|
# Bit reverse the input value.
|
|
298
326
|
|
|
299
327
|
|
|
300
|
-
def _bitrev(x, n):
|
|
328
|
+
def _bitrev(x: int, n: int) -> int:
|
|
301
329
|
y = 0
|
|
302
330
|
for i in range(n):
|
|
303
331
|
y = (y << 1) | (x & 1)
|
|
@@ -311,7 +339,7 @@ def _bitrev(x, n):
|
|
|
311
339
|
# bit of the polynomial has been stripped off.
|
|
312
340
|
|
|
313
341
|
|
|
314
|
-
def _bytecrc(crc, poly, n):
|
|
342
|
+
def _bytecrc(crc: int, poly: int, n: int) -> int:
|
|
315
343
|
mask = 1 << (n - 1)
|
|
316
344
|
for i in range(8):
|
|
317
345
|
if crc & mask:
|
|
@@ -323,7 +351,7 @@ def _bytecrc(crc, poly, n):
|
|
|
323
351
|
return crc
|
|
324
352
|
|
|
325
353
|
|
|
326
|
-
def _bytecrc_r(crc, poly, n):
|
|
354
|
+
def _bytecrc_r(crc: int, poly: int, n: int) -> int:
|
|
327
355
|
for i in range(8):
|
|
328
356
|
if crc & 1:
|
|
329
357
|
crc = (crc >> 1) ^ poly
|
|
@@ -343,14 +371,14 @@ def _bytecrc_r(crc, poly, n):
|
|
|
343
371
|
# have been checked for validity by the caller.
|
|
344
372
|
|
|
345
373
|
|
|
346
|
-
def _mkTable(poly, n):
|
|
374
|
+
def _mkTable(poly: int, n: int) -> List[int]:
|
|
347
375
|
mask = (1 << n) - 1
|
|
348
376
|
poly = poly & mask
|
|
349
377
|
table = [_bytecrc(i << (n - 8), poly, n) for i in range(256)]
|
|
350
378
|
return table
|
|
351
379
|
|
|
352
380
|
|
|
353
|
-
def _mkTable_r(poly, n):
|
|
381
|
+
def _mkTable_r(poly: int, n: int) -> List[int]:
|
|
354
382
|
mask = (1 << n) - 1
|
|
355
383
|
poly = _bitrev(poly & mask, n)
|
|
356
384
|
table = [_bytecrc_r(i, poly, n) for i in range(256)]
|
|
@@ -360,12 +388,12 @@ def _mkTable_r(poly, n):
|
|
|
360
388
|
# -----------------------------------------------------------------------------
|
|
361
389
|
# Map the CRC size onto the functions that handle these sizes.
|
|
362
390
|
|
|
363
|
-
_sizeMap = {
|
|
364
|
-
8:
|
|
365
|
-
16:
|
|
366
|
-
24:
|
|
367
|
-
32:
|
|
368
|
-
64:
|
|
391
|
+
_sizeMap: Dict[int, Tuple[CrcFunNoDefaultArgs, CrcFunNoDefaultArgs]] = {
|
|
392
|
+
8: (_crcfun._crc8, _crcfun._crc8r),
|
|
393
|
+
16: (_crcfun._crc16, _crcfun._crc16r),
|
|
394
|
+
24: (_crcfun._crc24, _crcfun._crc24r),
|
|
395
|
+
32: (_crcfun._crc32, _crcfun._crc32r),
|
|
396
|
+
64: (_crcfun._crc64, _crcfun._crc64r),
|
|
369
397
|
}
|
|
370
398
|
|
|
371
399
|
# -----------------------------------------------------------------------------
|
|
@@ -374,7 +402,7 @@ _sizeMap = {
|
|
|
374
402
|
# code to use for the platform we are running on. This should properly adapt
|
|
375
403
|
# to 32 and 64 bit machines.
|
|
376
404
|
|
|
377
|
-
_sizeToTypeCode = {}
|
|
405
|
+
_sizeToTypeCode: Dict[int, str] = {}
|
|
378
406
|
|
|
379
407
|
for typeCode in "B H I L Q".split():
|
|
380
408
|
size = {1: 8, 2: 16, 4: 32, 8: 64}.get(struct.calcsize(typeCode), None)
|
|
@@ -391,7 +419,7 @@ del typeCode, size # type: ignore
|
|
|
391
419
|
# It returns the size of the CRC (in bits), and "sanitized" initial/final XOR values.
|
|
392
420
|
|
|
393
421
|
|
|
394
|
-
def _verifyParams(poly, initCrc, xorOut):
|
|
422
|
+
def _verifyParams(poly: int, initCrc: int, xorOut: int) -> Tuple[int, int, int]:
|
|
395
423
|
sizeBits = _verifyPoly(poly)
|
|
396
424
|
|
|
397
425
|
mask = (1 << sizeBits) - 1
|
|
@@ -418,7 +446,9 @@ def _verifyParams(poly, initCrc, xorOut):
|
|
|
418
446
|
# In addition to this function, a list containing the CRC table is returned.
|
|
419
447
|
|
|
420
448
|
|
|
421
|
-
def _mkCrcFun(
|
|
449
|
+
def _mkCrcFun(
|
|
450
|
+
poly: int, sizeBits: int, initCrc: int, rev: bool, xorOut: int
|
|
451
|
+
) -> Tuple[CrcFun, List[int]]:
|
|
422
452
|
if rev:
|
|
423
453
|
tableList = _mkTable_r(poly, sizeBits)
|
|
424
454
|
_fun = _sizeMap[sizeBits][1]
|
|
@@ -426,18 +456,28 @@ def _mkCrcFun(poly, sizeBits, initCrc, rev, xorOut):
|
|
|
426
456
|
tableList = _mkTable(poly, sizeBits)
|
|
427
457
|
_fun = _sizeMap[sizeBits][0]
|
|
428
458
|
|
|
429
|
-
_table = tableList
|
|
459
|
+
_table: Sequence[int] = tableList
|
|
430
460
|
if _usingExtension:
|
|
431
461
|
_table = struct.pack(_sizeToTypeCode[sizeBits], *tableList)
|
|
432
462
|
|
|
433
463
|
if xorOut == 0:
|
|
434
464
|
|
|
435
|
-
def crcfun(
|
|
465
|
+
def crcfun(
|
|
466
|
+
data: Buffer,
|
|
467
|
+
crc: int = initCrc,
|
|
468
|
+
table: Sequence[int] = _table,
|
|
469
|
+
fun: CrcFunNoDefaultArgs = _fun,
|
|
470
|
+
) -> int:
|
|
436
471
|
return fun(data, crc, table)
|
|
437
472
|
|
|
438
473
|
else:
|
|
439
474
|
|
|
440
|
-
def crcfun(
|
|
475
|
+
def crcfun(
|
|
476
|
+
data: Buffer,
|
|
477
|
+
crc: int = initCrc,
|
|
478
|
+
table: Sequence[int] = _table,
|
|
479
|
+
fun: CrcFunNoDefaultArgs = _fun,
|
|
480
|
+
) -> int:
|
|
441
481
|
return xorOut ^ fun(data, xorOut ^ crc, table)
|
|
442
482
|
|
|
443
483
|
return crcfun, tableList
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2010 Craig McQueen
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
# SOFTWARE.
|
|
21
|
+
# -----------------------------------------------------------------------------
|
|
22
|
+
"""
|
|
23
|
+
crcmod.predefined defines some well-known CRC algorithms.
|
|
24
|
+
|
|
25
|
+
To use it, e.g.:
|
|
26
|
+
import crcmod.predefined
|
|
27
|
+
|
|
28
|
+
crc32func = crcmod.predefined.mkPredefinedCrcFun("crc-32")
|
|
29
|
+
crc32class = crcmod.predefined.PredefinedCrc("crc-32")
|
|
30
|
+
|
|
31
|
+
crcmod.predefined.Crc is an alias for crcmod.predefined.PredefinedCrc
|
|
32
|
+
But if doing 'from crc.predefined import *', only PredefinedCrc is imported.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
# local imports
|
|
36
|
+
import crcmod
|
|
37
|
+
|
|
38
|
+
from typing import Any, Dict, List, Tuple
|
|
39
|
+
|
|
40
|
+
from .types import CrcFun
|
|
41
|
+
|
|
42
|
+
__all__ = (
|
|
43
|
+
"PredefinedCrc",
|
|
44
|
+
"mkPredefinedCrcFun",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
REVERSE = True
|
|
48
|
+
NON_REVERSE = False
|
|
49
|
+
|
|
50
|
+
# TODO(ntamas): migrate to TypedDict when we drop support for Python 3.7
|
|
51
|
+
Definition = Dict[str, Any]
|
|
52
|
+
|
|
53
|
+
# The following table defines the parameters of well-known CRC algorithms.
|
|
54
|
+
# The "Check" value is the CRC for the ASCII byte sequence b"123456789". It
|
|
55
|
+
# can be used for unit tests.
|
|
56
|
+
# fmt: off
|
|
57
|
+
_crc_definitions_table: List[Tuple[str, str, int, bool, int, int, int]] = [
|
|
58
|
+
# Name Identifier-name, Poly Reverse Init-value XOR-out Check
|
|
59
|
+
( 'crc-8', 'Crc8', 0x107, NON_REVERSE, 0x00, 0x00, 0xF4, ),
|
|
60
|
+
( 'crc-8-darc', 'Crc8Darc', 0x139, REVERSE, 0x00, 0x00, 0x15, ),
|
|
61
|
+
( 'crc-8-i-code', 'Crc8ICode', 0x11D, NON_REVERSE, 0xFD, 0x00, 0x7E, ),
|
|
62
|
+
( 'crc-8-itu', 'Crc8Itu', 0x107, NON_REVERSE, 0x55, 0x55, 0xA1, ),
|
|
63
|
+
( 'crc-8-maxim', 'Crc8Maxim', 0x131, REVERSE, 0x00, 0x00, 0xA1, ),
|
|
64
|
+
( 'crc-8-rohc', 'Crc8Rohc', 0x107, REVERSE, 0xFF, 0x00, 0xD0, ),
|
|
65
|
+
( 'crc-8-wcdma', 'Crc8Wcdma', 0x19B, REVERSE, 0x00, 0x00, 0x25, ),
|
|
66
|
+
|
|
67
|
+
( 'crc-16', 'Crc16', 0x18005, REVERSE, 0x0000, 0x0000, 0xBB3D, ),
|
|
68
|
+
( 'crc-16-buypass', 'Crc16Buypass', 0x18005, NON_REVERSE, 0x0000, 0x0000, 0xFEE8, ),
|
|
69
|
+
( 'crc-16-dds-110', 'Crc16Dds110', 0x18005, NON_REVERSE, 0x800D, 0x0000, 0x9ECF, ),
|
|
70
|
+
( 'crc-16-dect', 'Crc16Dect', 0x10589, NON_REVERSE, 0x0001, 0x0001, 0x007E, ),
|
|
71
|
+
( 'crc-16-dnp', 'Crc16Dnp', 0x13D65, REVERSE, 0xFFFF, 0xFFFF, 0xEA82, ),
|
|
72
|
+
( 'crc-16-en-13757', 'Crc16En13757', 0x13D65, NON_REVERSE, 0xFFFF, 0xFFFF, 0xC2B7, ),
|
|
73
|
+
( 'crc-16-genibus', 'Crc16Genibus', 0x11021, NON_REVERSE, 0x0000, 0xFFFF, 0xD64E, ),
|
|
74
|
+
( 'crc-16-maxim', 'Crc16Maxim', 0x18005, REVERSE, 0xFFFF, 0xFFFF, 0x44C2, ),
|
|
75
|
+
( 'crc-16-mcrf4xx', 'Crc16Mcrf4xx', 0x11021, REVERSE, 0xFFFF, 0x0000, 0x6F91, ),
|
|
76
|
+
( 'crc-16-riello', 'Crc16Riello', 0x11021, REVERSE, 0x554D, 0x0000, 0x63D0, ),
|
|
77
|
+
( 'crc-16-t10-dif', 'Crc16T10Dif', 0x18BB7, NON_REVERSE, 0x0000, 0x0000, 0xD0DB, ),
|
|
78
|
+
( 'crc-16-teledisk', 'Crc16Teledisk', 0x1A097, NON_REVERSE, 0x0000, 0x0000, 0x0FB3, ),
|
|
79
|
+
( 'crc-16-usb', 'Crc16Usb', 0x18005, REVERSE, 0x0000, 0xFFFF, 0xB4C8, ),
|
|
80
|
+
( 'x-25', 'CrcX25', 0x11021, REVERSE, 0x0000, 0xFFFF, 0x906E, ),
|
|
81
|
+
( 'xmodem', 'CrcXmodem', 0x11021, NON_REVERSE, 0x0000, 0x0000, 0x31C3, ),
|
|
82
|
+
( 'modbus', 'CrcModbus', 0x18005, REVERSE, 0xFFFF, 0x0000, 0x4B37, ),
|
|
83
|
+
|
|
84
|
+
# Note definitions of CCITT are disputable. See:
|
|
85
|
+
# http://homepages.tesco.net/~rainstorm/crc-catalogue.htm
|
|
86
|
+
# http://web.archive.org/web/20071229021252/http://www.joegeluso.com/software/articles/ccitt.htm
|
|
87
|
+
( 'kermit', 'CrcKermit', 0x11021, REVERSE, 0x0000, 0x0000, 0x2189, ),
|
|
88
|
+
( 'crc-ccitt-false', 'CrcCcittFalse', 0x11021, NON_REVERSE, 0xFFFF, 0x0000, 0x29B1, ),
|
|
89
|
+
( 'crc-aug-ccitt', 'CrcAugCcitt', 0x11021, NON_REVERSE, 0x1D0F, 0x0000, 0xE5CC, ),
|
|
90
|
+
|
|
91
|
+
( 'crc-24', 'Crc24', 0x1864CFB, NON_REVERSE, 0xB704CE, 0x000000, 0x21CF02, ),
|
|
92
|
+
( 'crc-24-flexray-a', 'Crc24FlexrayA', 0x15D6DCB, NON_REVERSE, 0xFEDCBA, 0x000000, 0x7979BD, ),
|
|
93
|
+
( 'crc-24-flexray-b', 'Crc24FlexrayB', 0x15D6DCB, NON_REVERSE, 0xABCDEF, 0x000000, 0x1F23B8, ),
|
|
94
|
+
|
|
95
|
+
( 'crc-32', 'Crc32', 0x104C11DB7, REVERSE, 0x00000000, 0xFFFFFFFF, 0xCBF43926, ),
|
|
96
|
+
( 'crc-32-bzip2', 'Crc32Bzip2', 0x104C11DB7, NON_REVERSE, 0x00000000, 0xFFFFFFFF, 0xFC891918, ),
|
|
97
|
+
( 'crc-32c', 'Crc32C', 0x11EDC6F41, REVERSE, 0x00000000, 0xFFFFFFFF, 0xE3069283, ),
|
|
98
|
+
( 'crc-32d', 'Crc32D', 0x1A833982B, REVERSE, 0x00000000, 0xFFFFFFFF, 0x87315576, ),
|
|
99
|
+
( 'crc-32-mpeg', 'Crc32Mpeg', 0x104C11DB7, NON_REVERSE, 0xFFFFFFFF, 0x00000000, 0x0376E6E7, ),
|
|
100
|
+
( 'posix', 'CrcPosix', 0x104C11DB7, NON_REVERSE, 0xFFFFFFFF, 0xFFFFFFFF, 0x765E7680, ),
|
|
101
|
+
( 'crc-32q', 'Crc32Q', 0x1814141AB, NON_REVERSE, 0x00000000, 0x00000000, 0x3010BF7F, ),
|
|
102
|
+
( 'jamcrc', 'CrcJamCrc', 0x104C11DB7, REVERSE, 0xFFFFFFFF, 0x00000000, 0x340BC6D9, ),
|
|
103
|
+
( 'xfer', 'CrcXfer', 0x1000000AF, NON_REVERSE, 0x00000000, 0x00000000, 0xBD0BE338, ),
|
|
104
|
+
|
|
105
|
+
# 64-bit
|
|
106
|
+
# Name Identifier-name, Poly Reverse Init-value XOR-out Check
|
|
107
|
+
( 'crc-64', 'Crc64', 0x1000000000000001B, REVERSE, 0x0000000000000000, 0x0000000000000000, 0x46A5A9388A5BEFFE, ),
|
|
108
|
+
( 'crc-64-we', 'Crc64We', 0x142F0E1EBA9EA3693, NON_REVERSE, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x62EC59E3F1A4F00A, ),
|
|
109
|
+
( 'crc-64-jones', 'Crc64Jones', 0x1AD93D23594C935A9, REVERSE, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xCAA717168609F281, ),
|
|
110
|
+
]
|
|
111
|
+
# fmt: on
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _simplify_name(name: str) -> str:
|
|
115
|
+
"""
|
|
116
|
+
Reduce CRC definition name to a simplified form:
|
|
117
|
+
* lowercase
|
|
118
|
+
* dashes removed
|
|
119
|
+
* spaces removed
|
|
120
|
+
* any initial "CRC" string removed
|
|
121
|
+
"""
|
|
122
|
+
name = name.lower()
|
|
123
|
+
name = name.replace("-", "")
|
|
124
|
+
name = name.replace(" ", "")
|
|
125
|
+
if name.startswith("crc"):
|
|
126
|
+
name = name[len("crc") :]
|
|
127
|
+
return name
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
_crc_definitions_by_name: Dict[str, Definition] = {}
|
|
131
|
+
_crc_definitions_by_identifier: Dict[str, Definition] = {}
|
|
132
|
+
_crc_definitions: List[Definition] = []
|
|
133
|
+
|
|
134
|
+
_crc_table_headings: List[str] = [
|
|
135
|
+
"name",
|
|
136
|
+
"identifier",
|
|
137
|
+
"poly",
|
|
138
|
+
"reverse",
|
|
139
|
+
"init",
|
|
140
|
+
"xor_out",
|
|
141
|
+
"check",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
for table_entry in _crc_definitions_table:
|
|
145
|
+
crc_definition: Definition = dict(zip(_crc_table_headings, table_entry))
|
|
146
|
+
_crc_definitions.append(crc_definition)
|
|
147
|
+
name = _simplify_name(table_entry[0])
|
|
148
|
+
if name in _crc_definitions_by_name:
|
|
149
|
+
raise Exception("Duplicate entry for '{0}' in CRC table".format(name))
|
|
150
|
+
_crc_definitions_by_name[name] = crc_definition
|
|
151
|
+
_crc_definitions_by_identifier[table_entry[1]] = crc_definition
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _get_definition_by_name(crc_name: str) -> Definition:
|
|
155
|
+
definition = _crc_definitions_by_name.get(_simplify_name(crc_name), None)
|
|
156
|
+
if not definition:
|
|
157
|
+
definition = _crc_definitions_by_identifier.get(crc_name, None)
|
|
158
|
+
if not definition:
|
|
159
|
+
raise KeyError("Unkown CRC name '{0}'".format(crc_name))
|
|
160
|
+
return definition
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class PredefinedCrc(crcmod.Crc):
|
|
164
|
+
def __init__(self, crc_name: str):
|
|
165
|
+
definition = _get_definition_by_name(crc_name)
|
|
166
|
+
super().__init__(
|
|
167
|
+
poly=definition["poly"],
|
|
168
|
+
initCrc=definition["init"],
|
|
169
|
+
rev=definition["reverse"],
|
|
170
|
+
xorOut=definition["xor_out"],
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# crcmod.predefined.Crc is an alias for crcmod.predefined.PredefinedCrc
|
|
175
|
+
Crc = PredefinedCrc
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def mkPredefinedCrcFun(crc_name: str) -> CrcFun:
|
|
179
|
+
definition = _get_definition_by_name(crc_name)
|
|
180
|
+
return crcmod.mkCrcFun(
|
|
181
|
+
poly=definition["poly"],
|
|
182
|
+
initCrc=definition["init"],
|
|
183
|
+
rev=definition["reverse"],
|
|
184
|
+
xorOut=definition["xor_out"],
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
# crcmod.predefined.mkCrcFun is an alias for crcmod.predefined.mkPredefinedCrcFun
|
|
189
|
+
mkCrcFun = mkPredefinedCrcFun
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2023 Tamas Nepusz
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
# SOFTWARE.
|
|
21
|
+
# -----------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
from array import array
|
|
24
|
+
from typing import Callable, Sequence, Union
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
from typing import Protocol
|
|
28
|
+
except ImportError:
|
|
29
|
+
from typing_extensions import Protocol # type: ignore
|
|
30
|
+
|
|
31
|
+
__all__ = ("Buffer",)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Buffer = Union[str, bytes, bytearray, memoryview, array]
|
|
35
|
+
"""Type alias for objects supported by the CRC functions as inputs."""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CrcFun(Protocol):
|
|
39
|
+
"""Type alias for CRC calculator functions created by this module."""
|
|
40
|
+
|
|
41
|
+
def __call__(
|
|
42
|
+
self, data: Buffer, crc: int = ..., table: Sequence[int] = ...
|
|
43
|
+
) -> int: ...
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
CrcFunNoDefaultArgs = Callable[[Buffer, int, Sequence[int]], int]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: crcmod-plus
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: CRC generator - modernized
|
|
5
5
|
Author-email: Ray Buvel <rlbuvel@gmail.com>
|
|
6
6
|
Maintainer-email: Tamas Nepusz <tamas@sxd.hu>
|
|
@@ -27,8 +27,10 @@ License: -----------------------------------------------------------------------
|
|
|
27
27
|
SOFTWARE.
|
|
28
28
|
----------------------------------------------------------------------------
|
|
29
29
|
|
|
30
|
-
Project-URL: Repository, https://github.com/ntamas/crcmod-plus
|
|
31
30
|
Project-URL: Changelog, https://github.com/ntamas/crcmod-plus/blob/main/CHANGELOG.md
|
|
31
|
+
Project-URL: Documentation, https://github.com/ntamas/crcmod-plus#readme
|
|
32
|
+
Project-URL: Issues, https://github.com/ntamas/crcmod-plus/issues
|
|
33
|
+
Project-URL: Source, https://github.com/ntamas/crcmod-plus
|
|
32
34
|
Classifier: Development Status :: 5 - Production/Stable
|
|
33
35
|
Classifier: Intended Audience :: Developers
|
|
34
36
|
Classifier: Intended Audience :: Education
|
|
@@ -52,8 +54,11 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
52
54
|
Classifier: Topic :: Utilities
|
|
53
55
|
Requires-Python: >=3.7
|
|
54
56
|
Description-Content-Type: text/markdown
|
|
55
|
-
Provides-Extra: dev
|
|
56
57
|
License-File: LICENSE.txt
|
|
58
|
+
Requires-Dist: typing_extensions; python_version < "3.8"
|
|
59
|
+
Provides-Extra: dev
|
|
60
|
+
Requires-Dist: pytest; extra == "dev"
|
|
61
|
+
Dynamic: license-file
|
|
57
62
|
|
|
58
63
|
[](https://github.com/ntamas/crcmod-plus/actions/workflows/build.yml)
|
|
59
64
|
|
|
@@ -8,6 +8,8 @@ src/crcmod/_crcfunpy.py
|
|
|
8
8
|
src/crcmod/_version.py
|
|
9
9
|
src/crcmod/crcmod.py
|
|
10
10
|
src/crcmod/predefined.py
|
|
11
|
+
src/crcmod/py.typed
|
|
12
|
+
src/crcmod/types.py
|
|
11
13
|
src/crcmod_plus.egg-info/PKG-INFO
|
|
12
14
|
src/crcmod_plus.egg-info/SOURCES.txt
|
|
13
15
|
src/crcmod_plus.egg-info/dependency_links.txt
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
# -----------------------------------------------------------------------------
|
|
23
23
|
"""Unit tests for crcmod functionality"""
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
import unittest
|
|
27
26
|
|
|
28
27
|
from array import array
|
|
@@ -442,7 +441,7 @@ class CompareReferenceCrcTest(unittest.TestCase):
|
|
|
442
441
|
that of binascii.crc32."""
|
|
443
442
|
# The following function should produce the same result as
|
|
444
443
|
# self.reference_crc32 which is derived from binascii.crc32.
|
|
445
|
-
crc32 = mkCrcFun(g32, 0,
|
|
444
|
+
crc32 = mkCrcFun(g32, 0, True, 0xFFFFFFFF)
|
|
446
445
|
|
|
447
446
|
for msg in self.test_messages:
|
|
448
447
|
self.assertEqual(crc32(msg), self.reference_crc32(msg))
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
# -----------------------------------------------------------------------------
|
|
2
|
-
# Copyright (c) 2010 Craig McQueen
|
|
3
|
-
#
|
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
-
# in the Software without restriction, including without limitation the rights
|
|
7
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
-
# furnished to do so, subject to the following conditions:
|
|
10
|
-
#
|
|
11
|
-
# The above copyright notice and this permission notice shall be included in
|
|
12
|
-
# all copies or substantial portions of the Software.
|
|
13
|
-
#
|
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
-
# SOFTWARE.
|
|
21
|
-
# -----------------------------------------------------------------------------
|
|
22
|
-
"""
|
|
23
|
-
crcmod.predefined defines some well-known CRC algorithms.
|
|
24
|
-
|
|
25
|
-
To use it, e.g.:
|
|
26
|
-
import crcmod.predefined
|
|
27
|
-
|
|
28
|
-
crc32func = crcmod.predefined.mkPredefinedCrcFun("crc-32")
|
|
29
|
-
crc32class = crcmod.predefined.PredefinedCrc("crc-32")
|
|
30
|
-
|
|
31
|
-
crcmod.predefined.Crc is an alias for crcmod.predefined.PredefinedCrc
|
|
32
|
-
But if doing 'from crc.predefined import *', only PredefinedCrc is imported.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
# local imports
|
|
36
|
-
import crcmod
|
|
37
|
-
|
|
38
|
-
__all__ = [
|
|
39
|
-
"PredefinedCrc",
|
|
40
|
-
"mkPredefinedCrcFun",
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
REVERSE = True
|
|
44
|
-
NON_REVERSE = False
|
|
45
|
-
|
|
46
|
-
# The following table defines the parameters of well-known CRC algorithms.
|
|
47
|
-
# The "Check" value is the CRC for the ASCII byte sequence b"123456789". It
|
|
48
|
-
# can be used for unit tests.
|
|
49
|
-
# fmt: off
|
|
50
|
-
_crc_definitions_table = [
|
|
51
|
-
# Name Identifier-name, Poly Reverse Init-value XOR-out Check
|
|
52
|
-
[ 'crc-8', 'Crc8', 0x107, NON_REVERSE, 0x00, 0x00, 0xF4, ],
|
|
53
|
-
[ 'crc-8-darc', 'Crc8Darc', 0x139, REVERSE, 0x00, 0x00, 0x15, ],
|
|
54
|
-
[ 'crc-8-i-code', 'Crc8ICode', 0x11D, NON_REVERSE, 0xFD, 0x00, 0x7E, ],
|
|
55
|
-
[ 'crc-8-itu', 'Crc8Itu', 0x107, NON_REVERSE, 0x55, 0x55, 0xA1, ],
|
|
56
|
-
[ 'crc-8-maxim', 'Crc8Maxim', 0x131, REVERSE, 0x00, 0x00, 0xA1, ],
|
|
57
|
-
[ 'crc-8-rohc', 'Crc8Rohc', 0x107, REVERSE, 0xFF, 0x00, 0xD0, ],
|
|
58
|
-
[ 'crc-8-wcdma', 'Crc8Wcdma', 0x19B, REVERSE, 0x00, 0x00, 0x25, ],
|
|
59
|
-
|
|
60
|
-
[ 'crc-16', 'Crc16', 0x18005, REVERSE, 0x0000, 0x0000, 0xBB3D, ],
|
|
61
|
-
[ 'crc-16-buypass', 'Crc16Buypass', 0x18005, NON_REVERSE, 0x0000, 0x0000, 0xFEE8, ],
|
|
62
|
-
[ 'crc-16-dds-110', 'Crc16Dds110', 0x18005, NON_REVERSE, 0x800D, 0x0000, 0x9ECF, ],
|
|
63
|
-
[ 'crc-16-dect', 'Crc16Dect', 0x10589, NON_REVERSE, 0x0001, 0x0001, 0x007E, ],
|
|
64
|
-
[ 'crc-16-dnp', 'Crc16Dnp', 0x13D65, REVERSE, 0xFFFF, 0xFFFF, 0xEA82, ],
|
|
65
|
-
[ 'crc-16-en-13757', 'Crc16En13757', 0x13D65, NON_REVERSE, 0xFFFF, 0xFFFF, 0xC2B7, ],
|
|
66
|
-
[ 'crc-16-genibus', 'Crc16Genibus', 0x11021, NON_REVERSE, 0x0000, 0xFFFF, 0xD64E, ],
|
|
67
|
-
[ 'crc-16-maxim', 'Crc16Maxim', 0x18005, REVERSE, 0xFFFF, 0xFFFF, 0x44C2, ],
|
|
68
|
-
[ 'crc-16-mcrf4xx', 'Crc16Mcrf4xx', 0x11021, REVERSE, 0xFFFF, 0x0000, 0x6F91, ],
|
|
69
|
-
[ 'crc-16-riello', 'Crc16Riello', 0x11021, REVERSE, 0x554D, 0x0000, 0x63D0, ],
|
|
70
|
-
[ 'crc-16-t10-dif', 'Crc16T10Dif', 0x18BB7, NON_REVERSE, 0x0000, 0x0000, 0xD0DB, ],
|
|
71
|
-
[ 'crc-16-teledisk', 'Crc16Teledisk', 0x1A097, NON_REVERSE, 0x0000, 0x0000, 0x0FB3, ],
|
|
72
|
-
[ 'crc-16-usb', 'Crc16Usb', 0x18005, REVERSE, 0x0000, 0xFFFF, 0xB4C8, ],
|
|
73
|
-
[ 'x-25', 'CrcX25', 0x11021, REVERSE, 0x0000, 0xFFFF, 0x906E, ],
|
|
74
|
-
[ 'xmodem', 'CrcXmodem', 0x11021, NON_REVERSE, 0x0000, 0x0000, 0x31C3, ],
|
|
75
|
-
[ 'modbus', 'CrcModbus', 0x18005, REVERSE, 0xFFFF, 0x0000, 0x4B37, ],
|
|
76
|
-
|
|
77
|
-
# Note definitions of CCITT are disputable. See:
|
|
78
|
-
# http://homepages.tesco.net/~rainstorm/crc-catalogue.htm
|
|
79
|
-
# http://web.archive.org/web/20071229021252/http://www.joegeluso.com/software/articles/ccitt.htm
|
|
80
|
-
[ 'kermit', 'CrcKermit', 0x11021, REVERSE, 0x0000, 0x0000, 0x2189, ],
|
|
81
|
-
[ 'crc-ccitt-false', 'CrcCcittFalse', 0x11021, NON_REVERSE, 0xFFFF, 0x0000, 0x29B1, ],
|
|
82
|
-
[ 'crc-aug-ccitt', 'CrcAugCcitt', 0x11021, NON_REVERSE, 0x1D0F, 0x0000, 0xE5CC, ],
|
|
83
|
-
|
|
84
|
-
[ 'crc-24', 'Crc24', 0x1864CFB, NON_REVERSE, 0xB704CE, 0x000000, 0x21CF02, ],
|
|
85
|
-
[ 'crc-24-flexray-a', 'Crc24FlexrayA', 0x15D6DCB, NON_REVERSE, 0xFEDCBA, 0x000000, 0x7979BD, ],
|
|
86
|
-
[ 'crc-24-flexray-b', 'Crc24FlexrayB', 0x15D6DCB, NON_REVERSE, 0xABCDEF, 0x000000, 0x1F23B8, ],
|
|
87
|
-
|
|
88
|
-
[ 'crc-32', 'Crc32', 0x104C11DB7, REVERSE, 0x00000000, 0xFFFFFFFF, 0xCBF43926, ],
|
|
89
|
-
[ 'crc-32-bzip2', 'Crc32Bzip2', 0x104C11DB7, NON_REVERSE, 0x00000000, 0xFFFFFFFF, 0xFC891918, ],
|
|
90
|
-
[ 'crc-32c', 'Crc32C', 0x11EDC6F41, REVERSE, 0x00000000, 0xFFFFFFFF, 0xE3069283, ],
|
|
91
|
-
[ 'crc-32d', 'Crc32D', 0x1A833982B, REVERSE, 0x00000000, 0xFFFFFFFF, 0x87315576, ],
|
|
92
|
-
[ 'crc-32-mpeg', 'Crc32Mpeg', 0x104C11DB7, NON_REVERSE, 0xFFFFFFFF, 0x00000000, 0x0376E6E7, ],
|
|
93
|
-
[ 'posix', 'CrcPosix', 0x104C11DB7, NON_REVERSE, 0xFFFFFFFF, 0xFFFFFFFF, 0x765E7680, ],
|
|
94
|
-
[ 'crc-32q', 'Crc32Q', 0x1814141AB, NON_REVERSE, 0x00000000, 0x00000000, 0x3010BF7F, ],
|
|
95
|
-
[ 'jamcrc', 'CrcJamCrc', 0x104C11DB7, REVERSE, 0xFFFFFFFF, 0x00000000, 0x340BC6D9, ],
|
|
96
|
-
[ 'xfer', 'CrcXfer', 0x1000000AF, NON_REVERSE, 0x00000000, 0x00000000, 0xBD0BE338, ],
|
|
97
|
-
|
|
98
|
-
# 64-bit
|
|
99
|
-
# Name Identifier-name, Poly Reverse Init-value XOR-out Check
|
|
100
|
-
[ 'crc-64', 'Crc64', 0x1000000000000001B, REVERSE, 0x0000000000000000, 0x0000000000000000, 0x46A5A9388A5BEFFE, ],
|
|
101
|
-
[ 'crc-64-we', 'Crc64We', 0x142F0E1EBA9EA3693, NON_REVERSE, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x62EC59E3F1A4F00A, ],
|
|
102
|
-
[ 'crc-64-jones', 'Crc64Jones', 0x1AD93D23594C935A9, REVERSE, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xCAA717168609F281, ],
|
|
103
|
-
]
|
|
104
|
-
# fmt: on
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def _simplify_name(name):
|
|
108
|
-
"""
|
|
109
|
-
Reduce CRC definition name to a simplified form:
|
|
110
|
-
* lowercase
|
|
111
|
-
* dashes removed
|
|
112
|
-
* spaces removed
|
|
113
|
-
* any initial "CRC" string removed
|
|
114
|
-
"""
|
|
115
|
-
name = name.lower()
|
|
116
|
-
name = name.replace("-", "")
|
|
117
|
-
name = name.replace(" ", "")
|
|
118
|
-
if name.startswith("crc"):
|
|
119
|
-
name = name[len("crc") :]
|
|
120
|
-
return name
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
_crc_definitions_by_name = {}
|
|
124
|
-
_crc_definitions_by_identifier = {}
|
|
125
|
-
_crc_definitions = []
|
|
126
|
-
|
|
127
|
-
_crc_table_headings = [
|
|
128
|
-
"name",
|
|
129
|
-
"identifier",
|
|
130
|
-
"poly",
|
|
131
|
-
"reverse",
|
|
132
|
-
"init",
|
|
133
|
-
"xor_out",
|
|
134
|
-
"check",
|
|
135
|
-
]
|
|
136
|
-
|
|
137
|
-
for table_entry in _crc_definitions_table:
|
|
138
|
-
crc_definition = dict(zip(_crc_table_headings, table_entry))
|
|
139
|
-
_crc_definitions.append(crc_definition)
|
|
140
|
-
name = _simplify_name(table_entry[0])
|
|
141
|
-
if name in _crc_definitions_by_name:
|
|
142
|
-
raise Exception("Duplicate entry for '{0}' in CRC table".format(name))
|
|
143
|
-
_crc_definitions_by_name[name] = crc_definition
|
|
144
|
-
_crc_definitions_by_identifier[table_entry[1]] = crc_definition
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def _get_definition_by_name(crc_name):
|
|
148
|
-
definition = _crc_definitions_by_name.get(_simplify_name(crc_name), None)
|
|
149
|
-
if not definition:
|
|
150
|
-
definition = _crc_definitions_by_identifier.get(crc_name, None)
|
|
151
|
-
if not definition:
|
|
152
|
-
raise KeyError("Unkown CRC name '{0}'".format(crc_name))
|
|
153
|
-
return definition
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
class PredefinedCrc(crcmod.Crc):
|
|
157
|
-
def __init__(self, crc_name):
|
|
158
|
-
definition = _get_definition_by_name(crc_name)
|
|
159
|
-
super().__init__(
|
|
160
|
-
poly=definition["poly"],
|
|
161
|
-
initCrc=definition["init"],
|
|
162
|
-
rev=definition["reverse"],
|
|
163
|
-
xorOut=definition["xor_out"],
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
# crcmod.predefined.Crc is an alias for crcmod.predefined.PredefinedCrc
|
|
168
|
-
Crc = PredefinedCrc
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def mkPredefinedCrcFun(crc_name):
|
|
172
|
-
definition = _get_definition_by_name(crc_name)
|
|
173
|
-
return crcmod.mkCrcFun(
|
|
174
|
-
poly=definition["poly"],
|
|
175
|
-
initCrc=definition["init"],
|
|
176
|
-
rev=definition["reverse"],
|
|
177
|
-
xorOut=definition["xor_out"],
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
# crcmod.predefined.mkCrcFun is an alias for crcmod.predefined.mkPredefinedCrcFun
|
|
182
|
-
mkCrcFun = mkPredefinedCrcFun
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|