comparison cutils/util/__init__.py @ 307:64df94bf4659

treesum: Build a little static database of digest sizes. So older Python versions can read and use treesum files produced by newer Python versions and digest algorithms.
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 07 Mar 2025 14:22:22 +0100
parents 44e62e36cad4
children 48430941c18c
comparison
equal deleted inserted replaced
306:ebddfdbc3f7a 307:64df94bf4659
14 "PY35", 14 "PY35",
15 "n", "b", "u", 15 "n", "b", "u",
16 "normalize_filename", 16 "normalize_filename",
17 "argv2algo", 17 "argv2algo",
18 "algotag2algotype", 18 "algotag2algotype",
19 "algotag2digest_size",
19 "get_blake2b", 20 "get_blake2b",
20 "get_blake2b_256", 21 "get_blake2b_256",
21 "get_blake2s", 22 "get_blake2s",
22 "default_algotag", 23 "default_algotag",
23 "fsencode", 24 "fsencode",
216 type/factory of the corresponding algorithm. 217 type/factory of the corresponding algorithm.
217 218
218 :param str s: the tag (i.e. normalized name) or the algorithm 219 :param str s: the tag (i.e. normalized name) or the algorithm
219 :return: the digest type or factory for `s` 220 :return: the digest type or factory for `s`
220 :raises ValueError: on unknown and/or unhandled algorithms 221 :raises ValueError: on unknown and/or unhandled algorithms
222 :raises ImportError: if a module that is required to handle given
223 specifier `s` is not available (e.g. BLAKE2b on
224 Python 2)
221 225
222 All string comparisons are case-sensitive. 226 All string comparisons are case-sensitive.
223 227
224 """ 228 """
225 if s == "SHA1": 229 # Standard in Python2.7
230 if s == "MD5":
231 return hashlib.md5
232 elif s == "SHA1":
226 return hashlib.sha1 233 return hashlib.sha1
227 elif s == "SHA224": 234 elif s == "SHA224":
228 return hashlib.sha224 235 return hashlib.sha224
229 elif s == "SHA256": 236 elif s == "SHA256":
230 return hashlib.sha256 237 return hashlib.sha256
231 elif s == "SHA384": 238 elif s == "SHA384":
232 return hashlib.sha384 239 return hashlib.sha384
233 elif s == "SHA512": 240 elif s == "SHA512":
234 return hashlib.sha512 241 return hashlib.sha512
242 # Available in Python 3.6+
235 elif s == "SHA3-224": 243 elif s == "SHA3-224":
236 return hashlib.sha3_224 244 return hashlib.sha3_224
237 elif s == "SHA3-256": 245 elif s == "SHA3-256":
238 return hashlib.sha3_256 246 return hashlib.sha3_256
239 elif s == "SHA3-384": 247 elif s == "SHA3-384":
240 return hashlib.sha3_384 248 return hashlib.sha3_384
241 elif s == "SHA3-512": 249 elif s == "SHA3-512":
242 return hashlib.sha3_512 250 return hashlib.sha3_512
251 # Available in Python 3.6+ or if pyblake2 is installed
243 elif s in ("BLAKE2b", "BLAKE2b-512", "BLAKE2b512"): # compat for openssl 252 elif s in ("BLAKE2b", "BLAKE2b-512", "BLAKE2b512"): # compat for openssl
244 return get_blake2b() 253 return get_blake2b()
245 elif s in ("BLAKE2s", "BLAKE2s-256", "BLAKE2s256"): # compat for openssl 254 elif s in ("BLAKE2s", "BLAKE2s-256", "BLAKE2s256"): # compat for openssl
246 return get_blake2s() 255 return get_blake2s()
247 elif s in ("BLAKE2b-256", "BLAKE2b256"): # also compat for openssl dgst 256 elif s in ("BLAKE2b-256", "BLAKE2b256"): # also compat for openssl dgst
248 return get_blake2b_256() 257 return get_blake2b_256()
249 elif s == "MD5": 258 # Vendored in cutils.crcmod
250 return hashlib.md5
251 elif s == "CRC-24": 259 elif s == "CRC-24":
252 return get_crc("crc-24") 260 return get_crc("crc-24")
253 elif s == "CRC-32-ISO": 261 elif s == "CRC-32-ISO":
254 return get_crc("crc-32") 262 return get_crc("crc-32")
255 elif s == "CRC-32-POSIX": 263 elif s == "CRC-32-POSIX":
266 return get_crc("crc-64-go") 274 return get_crc("crc-64-go")
267 elif s == "CRC-64-REDIS": 275 elif s == "CRC-64-REDIS":
268 return get_crc("crc-64-redis") 276 return get_crc("crc-64-redis")
269 else: 277 else:
270 raise ValueError("unknown algorithm: {}".format(s)) 278 raise ValueError("unknown algorithm: {}".format(s))
279
280
281 def algotag2digest_size(s):
282 """Get the `digest_size` in bytes from given algorithm specifier `s`.
283
284 Contains a small static database of digest sizes for algorithms that
285 are not available by default in older Python versions.
286
287 :raises ValueError: on unknown and/or unhandled algorithms
288 :raises ImportError: if a module that is required to handle given
289 specifier `s` is not available (e.g. BLAKE2b on
290 Python 2)
291
292 All string comparisons are case-sensitive.
293
294 """
295 try:
296 dgst = algotag2algotype(s)()
297 return dgst.digest_size
298 except ImportError:
299 sz = {
300 "SHA3-224": 28,
301 "SHA3-256": 32,
302 "SHA3-384": 48,
303 "SHA3-512": 64,
304 "BLAKE2b": 64,
305 "BLAKE2b-512": 64,
306 "BLAKE2b512": 64,
307 "BLAKE2b-256": 32,
308 "BLAKE2b256": 32,
309 "BLAKE2s": 32,
310 "BLAKE2s-256": 32,
311 "BLAKE2s256": 32,
312 }.get(s, None)
313 if not sz:
314 raise
315 return sz
271 316
272 317
273 def normalize_filename(filename, strip_dot_slashes=False): 318 def normalize_filename(filename, strip_dot_slashes=False):
274 if isinstance(filename, bytes): 319 if isinstance(filename, bytes):
275 filename = filename.replace(b"\\", b"/") 320 filename = filename.replace(b"\\", b"/")