def __init__(self,
              aes_properties: bytes,
              password: str,
              blocksize: Optional[int] = None) -> None:
     firstbyte = aes_properties[0]
     numcyclespower = firstbyte & 0x3F
     if firstbyte & 0xC0 != 0:
         saltsize = (firstbyte >> 7) & 1
         ivsize = (firstbyte >> 6) & 1
         secondbyte = aes_properties[1]
         saltsize += secondbyte >> 4
         ivsize += secondbyte & 0x0F
         assert len(aes_properties) == 2 + saltsize + ivsize
         salt = aes_properties[2:2 + saltsize]
         iv = aes_properties[2 + saltsize:2 + saltsize + ivsize]
         assert len(salt) == saltsize
         assert len(iv) == ivsize
         assert numcyclespower <= 24
         if ivsize < 16:
             iv += bytes("\x00" * (16 - ivsize), "ascii")
         key = calculate_key(password.encode("utf-16LE"), numcyclespower,
                             salt, "sha256")
         self.cipher = AES.new(key, AES.MODE_CBC, iv)
         if blocksize:
             self.buf = Buffer(size=blocksize + 16)
         else:
             self.buf = Buffer(size=get_default_blocksize() + 16)
     else:
         raise UnsupportedCompressionMethodError
예제 #2
0
파일: compressor.py 프로젝트: miurahr/py7zr
 def __init__(self,
              filters=None,
              password=None,
              blocksize: Optional[int] = None):
     self.filters: List[Dict[str, Any]] = []
     self.chain: List[ISevenZipCompressor] = []
     self.digest = 0
     self.packsize = 0
     self._unpacksizes: List[int] = []
     if blocksize:
         self._block_size = blocksize
     else:
         self._block_size = get_default_blocksize()
     if filters is None:
         self.filters = [{
             "id": lzma.FILTER_LZMA2,
             "preset": 7 | lzma.PRESET_EXTREME
         }]
     else:
         self.filters = filters
     if len(self.filters) > 4:
         raise UnsupportedCompressionMethodError(
             filters, "Maximum cascade of filters is 4 but got {}.".format(
                 len(self.filters)))
     self.methods_map = [
         SupportedMethods.is_native_filter(filter)
         for filter in self.filters
     ]
     self.coders: List[Dict[str, Any]] = []
     if all(self.methods_map) and SupportedMethods.is_compressor(
             self.filters[-1]):  # all native
         self._set_native_compressors_coders(self.filters)
         return
     #
     has_lzma2 = False
     for f in self.filters:
         if f["id"] == FILTER_LZMA2:
             has_lzma2 = True
             break
     if not has_lzma2:
         # when specified other than lzma2, BCJ filters should be alternative
         for i, f in enumerate(self.filters):
             if (f["id"] == FILTER_X86 or f["id"] == FILTER_ARM
                     or f["id"] == FILTER_ARMTHUMB
                     or f["id"] == FILTER_SPARC
                     or f["id"] == FILTER_POWERPC):
                 self.methods_map[i] = False
     #
     if not any(self.methods_map):  # all alternative
         for f in filters:
             self._set_alternate_compressors_coders(f, password)
     elif SupportedMethods.is_crypto_id(self.filters[-1]["id"]) and all(
             self.methods_map[:-1]):
         self._set_native_compressors_coders(self.filters[:-1])
         self._set_alternate_compressors_coders(self.filters[-1], password)
     else:
         raise UnsupportedCompressionMethodError(
             filters, "Unknown combination of methods.")
예제 #3
0
 def _split_file(self, filepath, size):
     chapters = 0
     written = [0, 0]
     total_size = filepath.stat().st_size
     block_size = get_default_blocksize()
     with filepath.open("rb") as src:
         while written[0] <= total_size:
             with open(str(filepath) + ".%03d" % chapters, "wb") as tgt:
                 written[1] = 0
                 while written[1] < size:
                     read_size = min(block_size, size - written[1])
                     tgt.write(src.read(read_size))
                     written[1] += read_size
                     written[0] += read_size
             chapters += 1
 def __init__(self,
              filters=None,
              password=None,
              blocksize: Optional[int] = None):
     self.filters: List[Dict[str, Any]] = []
     self.chain: List[ISevenZipCompressor] = []
     self.digest = 0
     self.packsize = 0
     self._unpacksizes: List[int] = []
     if blocksize:
         self._block_size = blocksize
     else:
         self._block_size = get_default_blocksize()
     if filters is None:
         self.filters = [{
             "id": lzma.FILTER_LZMA2,
             "preset": 7 | lzma.PRESET_EXTREME
         }]
     else:
         self.filters = filters
     if len(self.filters) > 4:
         raise UnsupportedCompressionMethodError(
             "Maximum cascade of filters is 4 but got {}.".format(
                 len(self.filters)))
     self.methods_map = [
         SupportedMethods.is_native_filter(filter)
         for filter in self.filters
     ]
     self.coders: List[Dict[str, Any]] = []
     if all(self.methods_map) and SupportedMethods.is_compressor(
             self.filters[-1]):  # all native
         self._set_native_compressors_coders(self.filters)
         return
     #
     for i, f in enumerate(self.filters):
         if f["id"] == FILTER_X86:
             self.methods_map[i] = False
     #
     if not any(self.methods_map):  # all alternative
         for f in filters:
             self._set_alternate_compressors_coders(f, password)
     elif SupportedMethods.is_crypto_id(self.filters[-1]["id"]) and all(
             self.methods_map[:-1]):
         self._set_native_compressors_coders(self.filters[:-1])
         self._set_alternate_compressors_coders(self.filters[-1], password)
     else:
         raise UnsupportedCompressionMethodError
 def __init__(self, password: str, blocksize: Optional[int] = None) -> None:
     self.cycles = 19  # as same as p7zip
     self.iv = get_random_bytes(16)
     self.salt = b""
     self.method = CompressionMethod.CRYPT_AES256_SHA256
     key = calculate_key(password.encode("utf-16LE"), self.cycles,
                         self.salt, "sha256")
     self.iv += bytes(
         self.AES_CBC_BLOCKSIZE -
         len(self.iv))  # zero padding if iv < AES_CBC_BLOCKSIZE
     self.cipher = AES.new(key, AES.MODE_CBC, self.iv)
     self.flushed = False
     if blocksize:
         self.buf = Buffer(size=blocksize + self.AES_CBC_BLOCKSIZE * 2)
     else:
         self.buf = Buffer(size=get_default_blocksize() +
                           self.AES_CBC_BLOCKSIZE * 2)
 def __init__(self, properties: bytes, blocksize: Optional[int] = None):
     if not isinstance(properties, bytes):
         raise UnsupportedCompressionMethodError
     if len(properties) == 5:
         level, mem = struct.unpack("<BL", properties)
     elif len(properties) == 7:
         level, mem, _, _ = struct.unpack("<BLBB", properties)
     else:
         raise UnsupportedCompressionMethodError
     if blocksize:
         self.block_size = blocksize
     else:
         self.block_size = get_default_blocksize()
     self._buf = BufferedRW(self.block_size)
     self._buf = BufferedRW()
     self.decoder = None
     self.level = level
     self.mem = mem
     self.initialized = False
 def __init__(
     self,
     coders: List[Dict[str, Any]],
     packsize: int,
     unpacksizes: List[int],
     crc: Optional[int],
     password: Optional[str] = None,
     blocksize: Optional[int] = None,
 ) -> None:
     self.input_size = packsize
     self.unpacksizes = unpacksizes
     self.consumed: int = 0
     self.crc = crc
     self.digest: int = 0
     if blocksize:
         self.block_size: int = blocksize
     else:
         self.block_size = get_default_blocksize()
     if len(coders) > 4:
         raise UnsupportedCompressionMethodError(
             "Maximum cascade of filters is 4 but got {}.".format(
                 len(coders)))
     self.methods_map = [
         SupportedMethods.is_native_coder(coder) for coder in coders
     ]  # type: List[bool]
     # Check if password given for encrypted archive
     if SupportedMethods.needs_password(coders) and password is None:
         raise PasswordRequired(
             "Password is required for extracting given archive.")
     # Check filters combination and required parameters
     if len(coders) >= 2:
         target_compressor = False
         has_bcj = False
         bcj_index = -1
         for i, coder in enumerate(coders):
             filter_id = SupportedMethods.get_filter_id(coder)
             if SupportedMethods.is_compressor_id(
                     filter_id) and filter_id != FILTER_LZMA2:
                 target_compressor = True
             if filter_id in [
                     FILTER_X86,
                     FILTER_ARM,
                     FILTER_ARMTHUMB,
                     FILTER_POWERPC,
                     FILTER_SPARC,
             ]:
                 has_bcj = True
                 bcj_index = i
             # hack for LZMA1+BCJ which should be native+alternative
             if target_compressor and has_bcj:
                 self.methods_map[bcj_index] = False
                 break
     self.chain = [
     ]  # type: List[Union[bz2.BZ2Decompressor, lzma.LZMADecompressor, ISevenZipDecompressor]]
     self._unpacksizes = []  # type: List[int]
     self.input_size = self.input_size
     shift = 0
     prev = False
     for i, r in enumerate(self.methods_map):
         shift += 1 if r and prev else 0
         prev = r
         self._unpacksizes.append(unpacksizes[i - shift])
     self._unpacked = [0 for _ in range(len(self._unpacksizes))]
     self.consumed = 0
     self._unused = bytearray()
     self._buf = bytearray()
     self._pos = 0
     # ---
     if all(self.methods_map):
         decompressor = self._get_lzma_decompressor(coders, unpacksizes[-1])
         self.chain.append(decompressor)
     elif not any(self.methods_map):
         for i in range(len(coders)):
             self.chain.append(
                 self._get_alternative_decompressor(coders[i],
                                                    unpacksizes[i],
                                                    password))
     elif any(self.methods_map):
         for i in range(len(coders)):
             if (not any(self.methods_map[:i])) and all(
                     self.methods_map[i:]):
                 for j in range(i):
                     self.chain.append(
                         self._get_alternative_decompressor(
                             coders[j], unpacksizes[j], password))
                 self.chain.append(
                     self._get_lzma_decompressor(coders[i:],
                                                 unpacksizes[i]))
                 break
         else:
             for i in range(len(coders)):
                 if self.methods_map[i]:
                     self.chain.append(
                         self._get_lzma_decompressor([coders[i]],
                                                     unpacksizes[i]))
                 else:
                     self.chain.append(
                         self._get_alternative_decompressor(
                             coders[i], unpacksizes[i], password))
     else:
         raise UnsupportedCompressionMethodError