util/python2/alibabacloud_oss_util/verify_stream.py (83 lines of code) (raw):

import hashlib import base64 import os import sys from _io import BytesIO from Tea.stream import BaseStream from Tea.converter import py2 class CRC64(object): POLY = (0xC96C5795 << 32) | 0xD7870F42 def __init__(self): self.value = 0 @property def _table(self): table = [] for n in range(256): crc = n for j in range(8): if crc & True: crc = (crc >> 1) & ~(0x8 << 60) ^ self.POLY else: crc = (crc >> 1) & ~(0x8 << 60) table.append(crc) return table def get_value(self): return str(self.value) def update(self, bt): for b in bt: if py2: b = ord(b) self.value = ~self.value self.value = self._table[(self.value ^ b) & 0xff] ^ (self.value >> 8) & ~(0xff << 56) self.value = ~self.value class VerifyStream(BaseStream): MAX_SIZE = 2147483647 def __init__(self, file, res, size=1024): super(VerifyStream, self).__init__(size) self.file = file self.size = size self.crc = CRC64() self.ref = res self.md5 = hashlib.md5() if isinstance(file, BytesIO): self.file_size = len(file.getvalue()) else: self.file_size = os.path.getsize(file.name) self._file_size = self.file_size def __len__(self): return self.file_size def __iter__(self): return self def next(self): return self.read(size=self.size, loop=True) def read(self, size=None, loop=False): if size is None: size = self.MAX_SIZE res = self.file.read(size) if size <= self._file_size: self.crc.update(res) self.md5.update(res) else: self.ref['md5'] = base64.b64encode(self.md5.digest()) self.ref['crc'] = self.crc.get_value() if not res: self.refresh() if loop: raise StopIteration else: return res if size == sys.maxsize or size >= self.file_size: self.crc.update(res) self.md5.update(res) self.ref['md5'] = base64.b64encode(self.md5.digest()) self.ref['crc'] = self.crc.get_value() return res self._file_size -= len(res) return res def refresh(self): self.crc = CRC64() self.md5 = hashlib.md5() self.file.seek(0, 0) self._file_size = self.file_size def close(self): self.file.close()