Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 / verify

.py
Скачиваний:
0
Добавлен:
27.12.2025
Размер:
4.16 Кб
Скачать
import os
import time

class BitReader:
    """Класс для чтения бит из файла (Оптимизированный)."""
    def __init__(self, filepath):
        with open(filepath, 'rb') as f:
            self.data = f.read()
        self.byte_index = 0
        self.bit_buffer = 0
        self.bits_in_buffer = 0

    def read_bits(self, num_bits):
        """Читает num_bits и возвращает число. Возвращает None, если биты кончились."""
        # Заполняем буфер, пока в нем меньше бит, чем нужно
        while self.bits_in_buffer < num_bits:
            if self.byte_index >= len(self.data):
                # Если данных больше нет и в буфере не хватает бит — это конец
                return None
            
            byte = self.data[self.byte_index]
            self.byte_index += 1
            
            # Добавляем байт в буфер
            self.bit_buffer = (self.bit_buffer << 8) | byte
            self.bits_in_buffer += 8
        
        # Извлекаем нужное количество бит из "верхушки" буфера
        shift = self.bits_in_buffer - num_bits
        value = (self.bit_buffer >> shift) & ((1 << num_bits) - 1)
        
        # Убираем прочитанное из счетчика
        self.bits_in_buffer -= num_bits
        
        # Очищаем буфер от старых бит
        mask = (1 << self.bits_in_buffer) - 1
        self.bit_buffer &= mask
        
        return value

def decompress_rle(input_path, output_path):
    reader = BitReader(input_path)
    
    # Читаем заголовок
    bits_for_length = reader.read_bits(8)
    if bits_for_length is None:
        print("Ошибка: пустой файл")
        return b""

    decoded_data = bytearray()
    
    count_iterations = 0
    
    while True:
        char_byte = reader.read_bits(8)
        if char_byte is None:
            break 
        
        count = reader.read_bits(bits_for_length)
        if count is None:
            break
            
        # Восстанавливаем серию
        for _ in range(count):
            decoded_data.append(char_byte)
        
        count_iterations += 1
        if count_iterations % 50000 == 0:
            print(f"Обработано {count_iterations} записей...", end='\r')
            
    with open(output_path, 'wb') as f:
        f.write(decoded_data)
        
    print(f"Всего обработано {count_iterations} записей. Готово.")
    return decoded_data

def main():
    original_file = 'poem.txt'
    encoded_file = 'poem.var1'
    decoded_file = 'poem_decoded.txt'
    
    print(f"--- Проверка декодирования ---")
    
    start_time = time.time()
    print(f"Распаковываем {encoded_file}...")
    
    start_time = time.time()
    
    decoded_bytes = decompress_rle(encoded_file, decoded_file)
    
    end_time = time.time()
    duration = end_time - start_time
    print(f"Время распаковки: {duration:.6f} сек")
    
    end_time = time.time()
    print(f"Распаковка заняла: {end_time - start_time:.4f} сек")

    # Сравниваем исходник и результат
    if not os.path.exists(original_file):
        print("Нет исходного файла для сравнения!")
        return

    with open(original_file, 'rb') as f:
        original_bytes = f.read()
        
    print(f"Размер оригинала: {len(original_bytes)} байт")
    print(f"Размер после распаковки: {len(decoded_bytes)} байт")
    
    if original_bytes == decoded_bytes:
        print("\nУСПЕХ! Файлы полностью идентичны.")
    else:
        print("\nОШИБКА! Файлы различаются.")

if __name__ == "__main__":
    main()
Соседние файлы в папке 2