def write_header(self) -> int: """ Writes the coding_table into the output file :return: offset of the byte after written table (in file) to start writing data from """ self.output_file.seek(0) self.output_file.write(bytes(0 for _ in range(5))) table_length_counter = 0 # count of bits in table for coding_entry in self.coding_table: # writing each coding entry first to buffer and then to file fill_deque_from_byte(self.encoding_buffer, coding_entry) entry_bit_repr = self.coding_table[coding_entry] fill_deque_from_byte(self.encoding_buffer, len(entry_bit_repr)) self.encoding_buffer.extend(entry_bit_repr) table_length_counter += 16 + len(entry_bit_repr) if len(self.encoding_buffer) >= OUTPUT_BUFFER_FLUSH_SIZE: # write all buffer's full bytes to the file if it is too large self.output_file.write(bits_to_bytes(self.encoding_buffer)) self.output_file.write(bits_to_bytes(self.encoding_buffer, flush=True)) # flush everything left in buffer to the file self.output_file.flush() curr_pos = self.output_file.tell() self.output_file.seek(1) self.output_file.write(table_length_counter.to_bytes(4, 'little')) # write the size of coding table to the output file self.output_file.seek(curr_pos) return curr_pos
def read_header(self) -> int: """ Read the header of file, parse and save it; :return number of trailing zeros """ self.input_file.seek(0) trailing_zeros = int.from_bytes(self.input_file.read(1), byteorder='little') table_size = int.from_bytes(self.input_file.read(4), byteorder='little') table_bytes = (table_size // 8) + (table_size % 8 > 0) for byte in self.input_file.read(table_bytes): fill_deque_from_byte(self.decoding_buffer, byte) try: for _ in range((table_bytes * 8) - table_size): self.decoding_buffer.pop() while len(self.decoding_buffer) > 16: byte, cipher_len = (int.from_bytes(bits_to_bytes( deque(self.decoding_buffer.popleft() for _ in range(8))), byteorder='little') for _ in range(2)) self.coding_table[BitSequence( self.decoding_buffer.popleft() for _ in range(cipher_len))] = byte except IndexError: raise RuntimeError("Incorrect input file") self.decoding_buffer.clear() return trailing_zeros
def __init__(self, offsets, lut=None, *args, **kwds): ByteOffsetPrototype.__init__(self, offsets, byte_offsets=utils.bits_to_bytes(offsets), lut=lut, *args, **kwds) BitParser.__init__(self, *args, **kwds)
def flush(self) -> int: """ Flush everything from the buffer to the file :return: additional zero bits in the end of file """ result = (8 - (len(self.encoding_buffer) % 8)) % 8 self.output_file.write(bits_to_bytes(self.encoding_buffer, flush=True)) return result
def _encode(self, data: bytes) -> None: """ Encode given bytes to the buffer (flushing it in process if it's too large) :param data: bytes to encode """ for byte in data: self.encoding_buffer.extend(self.coding_table[byte]) if len(self.encoding_buffer) >= OUTPUT_BUFFER_FLUSH_SIZE: self.output_file.write(bits_to_bytes(self.encoding_buffer))
def _encode(self, data: bytes) -> None: """ Encode given bytes to the buffer (flushing it in process if it's too large) :param data: bytes to encode """ for byte in data: # считали байты из файла self.encoding_buffer.extend( self.coding_table[byte] ) # узнаём как шифровать байт и записываем его, используя байт как ключ и вытаскивая биты как значения для этого байта if len( self.encoding_buffer ) >= OUTPUT_BUFFER_FLUSH_SIZE: # если длина буфера превосходит максимальный размер, то скидываем в файлик, переводя биты в байты self.output_file.write(bits_to_bytes(self.encoding_buffer))
def read_header(self) -> int: """ Read the header of file, parse and save it; :return number of trailing zeros """ self.input_file.seek(0) trailing_zeros = int.from_bytes( self.input_file.read(1), byteorder='little') # количество нулей в конце table_size = int.from_bytes( self.input_file.read(4), byteorder='little') # размер таблицы в битах table_bytes = (table_size // 8) + ( table_size % 8 > 0 ) # считаем сколько байтов нужно что бы поместить таблицу for byte in self.input_file.read(table_bytes): fill_deque_from_byte( self.decoding_buffer, byte) # заполняем буффер байтами, которые считали из хедера try: for _ in range((table_bytes * 8) - table_size): self.decoding_buffer.pop( ) # достаём все лишние биты, которые были считаны while len(self.decoding_buffer) > 16: byte, cipher_len = ( int.from_bytes( bits_to_bytes( deque( # считываем первые 2 элемента, символ в двоич. и длину кода в двоич. self.decoding_buffer.popleft() for _ in range(8))), byteorder='little') for _ in range(2)) self.coding_table[BitSequence( self.decoding_buffer.popleft() for _ in range(cipher_len) )] = byte # создаём последовательность битов и присваиваем ей байт который мы считали, таким образом мы создаём таблицу декодирования except IndexError: raise RuntimeError("Incorrect input file") self.decoding_buffer.clear() # очищаем буффер return trailing_zeros # возвращаем количество ноликов в конце файла
byte = byte[::-1] byte = bits_to_num(byte) result += "%02x" % byte if len(result) > 0: print(result + " \\") print(" -tdo 0 \\") print(" -mask 0") else: dev_type = bytes_to_num(data[0:4]) if dev_type == 0x120010: chunk_size = 4 for offset in range(0, len(data), chunk_size): chunk = data[offset:offset+chunk_size] header = [0x02, (count >> 8) & 0xff, count & 0xff, 0x00] chunk = bytearray(header) + chunk bits = bytes_to_bits(chunk) bits.reverse() bytes = bits_to_bytes(bits) str = "".join(["%02x" % a for a in bytes]) emit_prefix(count>0, True) emit_body(len(bits), str) emit_trailer() count += 1 if not sram: emit_prefix(True, True) emit_prefix(True, False)
def __init__(self, subcom_key, offsets, *args, **kwds): SubcomByteOffsetPrototype.__init__(self, subcom_key, offsets, utils.bits_to_bytes(offsets)) BitParser.__init__(self, *args, **kwds)