""" Collection of DIRAC useful adler32 related tools. By default on Error they return None. .. warning:: On error False is returned. .. warning:: All exceptions report to the stdout. """ from __future__ import print_function from __future__ import absolute_import from __future__ import division __RCSID__ = "c59810311 (2021-10-01 10:44:25 +0200) Chris Burr " import six from zlib import adler32 def intAdlerToHex(intAdler): """Change adler32 checksum base from decimal to hex. :param integer intAdler: adler32 checksum :return: 8 digit hex string """ try: # Will always be 8 hex digits made from a positive integer return hex(intAdler & 0xFFFFFFFF).lower().replace("l", "").replace("x", "0000")[-8:] except Exception as error: print(repr(error).replace(",)", ")")) return False def hexAdlerToInt(hexAdler, pos=True): """Change hex base to decimal for adler32 checksum. :param mixed hexAdler: hex based adler32 checksum integer or a string :param boolean pos: flag to determine sign (default True = positive) """ if isinstance(hexAdler, six.integer_types): return hexAdler & 0xFFFFFFFF # First make sure we can parse the hex properly if hexAdler == "False" or hexAdler == "-False": return False hexAdler = hexAdler.lower().replace("l", "") hexAdler = hexAdler[-8:] hexAdler = hexAdler.replace("x", "0") if not pos: hexAdler = "-%s" % hexAdler try: # Will always try to return the positive integer value of the provided hex return int(hexAdler, 16) & 0xFFFFFFFF except Exception as error: print(repr(error).replace(",)", ")")) return False def compareAdler(adler1, adler2): """Check equality between two adler32 checksums. :param adler1: 1st checksum :param adler2: 2nd checksum :return: True (False) if cheksums are (not) equal """ adler1s = [hexAdlerToInt(adler1), hexAdlerToInt(adler1, False)] if False in adler1s: adler1s.remove(False) adler2s = [hexAdlerToInt(adler2), hexAdlerToInt(adler2, False)] if False in adler2s: adler2s.remove(False) for adler1 in adler1s: if adler1 in adler2s: return True return False def fileAdler(fileName): """Calculate alder32 checksum of the supplied file. :param str fileName: path to file """ def readChunk(fd, size=1048576): """Return data from file descriptor in chunk of size size. :param fd: file descriptor :param integer size: size of data chunk in bytes (default 1024 * 1024 = 1048576) """ while True: data = fd.read(size) if not data: break yield data try: with open(fileName, "rb") as inputFile: myAdler = 1 for data in readChunk(inputFile): myAdler = adler32(data, myAdler) return intAdlerToHex(myAdler) except Exception as error: print(repr(error).replace(",)", ")")) return False def stringAdler(string): """Calculate adler32 of the supplied string. :param str string: data """ try: intAdler = adler32(string.encode()) return intAdlerToHex(intAdler) except Exception as error: print(repr(error).replace(",)", ")")) return False if __name__ == "__main__": import sys for p in sys.argv[1:]: print("%s : %s" % (p, fileAdler(p)))