|
15 | 15 | __all__ = '''mkCrcFun Crc |
16 | 16 | '''.split() |
17 | 17 |
|
18 | | -from obs.const import IS_PYTHON2 |
19 | | -import struct |
20 | | - |
21 | | - |
22 | | -class Crc: |
23 | | - def __init__(self, poly, initCrc=~0, rev=True, xorOut=0, initialize=True): |
24 | | - if not initialize: |
25 | | - return |
26 | | - |
27 | | - (sizeBits, initCrc, xorOut) = _verifyParams(poly, initCrc, xorOut) |
28 | | - self.digest_size = sizeBits // 8 |
29 | | - self.poly = poly |
30 | | - self.initCrc = initCrc |
31 | | - self.reverse = rev |
32 | | - self.xorOut = xorOut |
33 | | - |
34 | | - (crcfun, table) = _mkCrcFun(poly, sizeBits, initCrc, rev, xorOut) |
35 | | - self.table = table |
36 | | - self._crc = crcfun |
37 | | - |
38 | | - self.crcValue = self.initCrc |
39 | | - |
40 | | - def __str__(self): |
41 | | - lst = [] |
42 | | - lst.append('reverse = %s' % self.reverse) |
43 | | - lst.append('poly = 0x%X' % self.poly) |
44 | | - fmt = '0x%%0%dX' % (self.digest_size * 2) |
45 | | - lst.append('crcValue = %s' % (fmt % self.crcValue)) |
46 | | - lst.append('xorOut = %s' % (fmt % self.xorOut)) |
47 | | - lst.append('initCrc = %s' % (fmt % self.initCrc)) |
48 | | - return '\n'.join(lst) |
49 | | - |
50 | | - def new(self, arg=None): |
51 | | - n = Crc(poly=None, initialize=False) |
52 | | - n._crc = self._crc |
53 | | - n.table = self.table |
54 | | - n.digest_size = self.digest_size |
55 | | - n.reverse = self.reverse |
56 | | - n.initCrc = self.initCrc |
57 | | - n.crcValue = self.initCrc |
58 | | - n.xorOut = self.xorOut |
59 | | - n.poly = self.poly |
60 | | - if arg is not None: |
61 | | - n.update(arg) |
62 | | - return n |
63 | | - |
64 | | - def copy(self): |
65 | | - c = self.new() |
66 | | - c.crcValue = self.crcValue |
67 | | - return c |
68 | | - |
69 | | - def update(self, data): |
70 | | - self.crcValue = self._crc(data, self.crcValue) |
71 | | - |
72 | | - def digest(self): |
73 | | - n = self.digest_size |
74 | | - crc = self.crcValue |
75 | | - lst = [] |
76 | | - while n > 0: |
77 | | - lst.append(crc & 0xFF) |
78 | | - crc = crc >> 8 |
79 | | - n -= 1 |
80 | | - lst.reverse() |
81 | | - return bytes(lst) |
82 | | - |
83 | | - def hexdigest(self): |
84 | | - crc = self.crcValue |
85 | | - n = self.digest_size |
86 | | - lst = [] |
87 | | - while n > 0: |
88 | | - lst.append('%02X' % (crc & 0xFF)) |
89 | | - crc = crc >> 8 |
90 | | - n -= 1 |
91 | | - lst.reverse() |
92 | | - return ''.join(lst) |
93 | | - |
94 | | - |
95 | | -def mkCrcFun(poly, initCrc=~0, rev=True, xorOut=0): |
96 | | - (sizeBits, initCrc, xorOut) = _verifyParams(poly, initCrc, xorOut) |
97 | | - return _mkCrcFun(poly, sizeBits, initCrc, rev, xorOut)[0] |
98 | | - |
99 | | - |
100 | | -def _verifyPoly(poly): |
101 | | - msg = 'The degree of the polynomial must be 64' |
102 | | - n = 64 |
103 | | - low = 1 << n |
104 | | - high = low * 2 |
105 | | - if low <= poly < high: |
106 | | - return n |
107 | | - raise ValueError(msg) |
108 | | - |
109 | | - |
110 | | -def _bitrev(x, n): |
111 | | - y = 0 |
112 | | - for i in range(n): |
113 | | - y = (y << 1) | (x & 1) |
114 | | - x = x >> 1 |
115 | | - return y |
116 | | - |
117 | | - |
118 | | -def _bytecrc(crc, poly, n): |
119 | | - mask = 1 << (n - 1) |
120 | | - for i in range(8): |
121 | | - if crc & mask: |
122 | | - crc = (crc << 1) ^ poly |
123 | | - else: |
124 | | - crc = crc << 1 |
125 | | - mask = (1 << n) - 1 |
126 | | - crc = crc & mask |
127 | | - return crc |
128 | | - |
129 | | - |
130 | | -def _bytecrc_r(crc, poly, n): |
131 | | - for i in range(8): |
132 | | - if crc & 1: |
133 | | - crc = (crc >> 1) ^ poly |
134 | | - else: |
135 | | - crc = crc >> 1 |
136 | | - mask = (1 << n) - 1 |
137 | | - crc = crc & mask |
138 | | - return crc |
139 | | - |
140 | | - |
141 | | -def _mkTable(poly, n): |
142 | | - mask = (1 << n) - 1 |
143 | | - poly = poly & mask |
144 | | - table = [_bytecrc(i << (n - 8), poly, n) for i in range(256)] |
145 | | - return table |
146 | | - |
147 | | - |
148 | | -def _mkTable_r(poly, n): |
149 | | - mask = (1 << n) - 1 |
150 | | - poly = _bitrev(poly & mask, n) |
151 | | - table = [_bytecrc_r(i, poly, n) for i in range(256)] |
152 | | - return table |
153 | | - |
154 | | - |
155 | | -_sizeToTypeCode = {} |
156 | | - |
157 | | -for typeCode in 'B H I L Q'.split(): |
158 | | - size = {1: 8, 2: 16, 4: 32, 8: 64}.get(struct.calcsize(typeCode), None) |
159 | | - if size is not None and size not in _sizeToTypeCode: |
160 | | - _sizeToTypeCode[size] = '256%s' % typeCode |
161 | | - |
162 | | -_sizeToTypeCode[24] = _sizeToTypeCode[32] |
163 | | - |
164 | | -del typeCode, size |
165 | | - |
166 | | - |
167 | | -def _verifyParams(poly, initCrc, xorOut): |
168 | | - sizeBits = _verifyPoly(poly) |
169 | | - mask = (1 << sizeBits) - 1 |
170 | | - initCrc = initCrc & mask |
171 | | - xorOut = xorOut & mask |
172 | | - return (sizeBits, initCrc, xorOut) |
173 | | - |
174 | | - |
175 | | -def _mkCrcFun(poly, sizeBits, initCrc, rev, xorOut): |
176 | | - if rev: |
177 | | - tableList = _mkTable_r(poly, sizeBits) |
178 | | - _fun = _crc64r |
179 | | - else: |
180 | | - tableList = _mkTable(poly, sizeBits) |
181 | | - _fun = _crc64 |
182 | | - |
183 | | - _table = tableList |
184 | | - |
185 | | - if xorOut == 0: |
186 | | - def crcfun(data, crc=initCrc, table=_table, fun=_fun): |
187 | | - return fun(data, crc, table) |
188 | | - else: |
189 | | - def crcfun(data, crc=initCrc, table=_table, fun=_fun): |
190 | | - return xorOut ^ fun(data, xorOut ^ crc, table) |
191 | | - |
192 | | - return crcfun, tableList |
193 | | - |
194 | | - |
195 | | -def _get_buffer_view(in_obj): |
196 | | - if isinstance(in_obj, str): |
197 | | - raise TypeError('Unicode-objects must be encoded before calculating a CRC') |
198 | | - mv = memoryview(in_obj) |
199 | | - if mv.ndim > 1: |
200 | | - raise BufferError('Buffer must be single dimension') |
201 | | - return mv |
202 | | - |
203 | | - |
204 | | -def _crc64(data, crc, table): |
205 | | - crc = crc & 0xFFFFFFFFFFFFFFFF |
206 | | - if IS_PYTHON2: |
207 | | - for x in data: |
208 | | - crc = table[ord(x) ^ (int(crc >> 56) & 0xFF)] ^ ((crc << 8) & 0xFFFFFFFFFFFFFF00) |
209 | | - else: |
210 | | - mv = _get_buffer_view(data) |
211 | | - for x in mv.tobytes(): |
212 | | - crc = table[x ^ ((crc >> 56) & 0xFF)] ^ ((crc << 8) & 0xFFFFFFFFFFFFFF00) |
213 | | - return crc |
214 | | - |
215 | | - |
216 | | -def _crc64r(data, crc, table): |
217 | | - crc = crc & 0xFFFFFFFFFFFFFFFF |
218 | | - if IS_PYTHON2: |
219 | | - for x in data: |
220 | | - crc = table[ord(x) ^ int(crc & 0xFF)] ^ (crc >> 8) |
221 | | - else: |
222 | | - mv = _get_buffer_view(data) |
223 | | - for x in mv.tobytes(): |
224 | | - crc = table[x ^ (crc & 0xFF)] ^ (crc >> 8) |
225 | | - return crc |
226 | | - |
227 | | - |
228 | 18 | import sys |
229 | 19 |
|
230 | 20 | is_py3 = (sys.version_info[0] == 3) |
|
0 commit comments