11import io
22import sys
33
4+
45class BitArray :
56 """
6- Classe para manipular bits como um array
7+ Classe para manipular bits como um array
78 """
9+
810 ENDIAN_TYPE = 'big'
911 bits = []
1012 output = bytearray ()
@@ -21,40 +23,38 @@ def __init__(self, input_data=None, endian='big'):
2123
2224 def append (self , bit ):
2325 """
24- Adiciona um bit à lista
26+ Adiciona um bit à lista
2527 """
2628 self .bits .append (int (bit ))
2729
2830 def fromint (self , value ):
2931 """
30- Converte um inteiro para bits
31- e adiciona-os à lista
32+ Converte um inteiro para bits
33+ e adiciona-os à lista
3234 """
3335 bitstring = '{:08b}' .format (value )
3436 for bit in bitstring :
3537 self .append (int (bit , 2 ))
3638
3739 def frombytes (self , byte ):
3840 """
39- Converte um byte para bits
40- e adiciona-os à lista
41+ Converte um byte para bits
42+ e adiciona-os à lista
4143 """
42- bitstring = "{:08b}" .format (
43- int .from_bytes (byte , self .ENDIAN_TYPE )
44- )
44+ bitstring = "{:08b}" .format (int .from_bytes (byte , self .ENDIAN_TYPE ))
4545 for bit in bitstring :
4646 self .append (int (bit , 2 ))
4747
4848 def dump (self ):
4949 """
50- Transforma à lista com os bits em um
51- bytearray e retorna seu valor
50+ Transforma à lista com os bits em um
51+ bytearray e retorna seu valor
5252 """
5353 self .output = bytearray ()
5454 bits_in_a_byte = 8
5555 for i in range (len (self .bits ) // (bits_in_a_byte )):
5656 bitstring = ''
57- readed_bits = self .bits [i * bits_in_a_byte : i * bits_in_a_byte + 8 ]
57+ readed_bits = self .bits [i * bits_in_a_byte : i * bits_in_a_byte + 8 ]
5858 for bit in readed_bits :
5959 bitstring += str (bit )
6060 byte = int (bitstring , 2 )
@@ -81,29 +81,21 @@ class LZ77:
8181 # Dados de Entrada
8282 data = None
8383
84- def __init__ (
85- self ,
86- window_size = 400 ,
87- lookahed_buffer = 15 ,
88- endian = 'big' ,
89- verbose = True ):
84+ def __init__ (self , window_size = 400 , lookahed_buffer = 15 , endian = 'big' , verbose = True ):
9085 self .MAX_WINDOW_SIZE = window_size
9186 self .MAX_LOOKAHEAD_BUFFER = lookahed_buffer
9287 self .ENDIAN_TYPE = 'big'
9388 self .ENABLE_DEBUG = verbose
9489
9590 def find_longest_match (self ):
9691 """
97- Encontra a maior ocorrência compatível com a cadeia consultada iniciando
98- da posição atual do cursor: current_position; e posteriomente
99- consultando o histórico existente dentro da janela para encontrar
100- uma ocorrência compatível.
92+ Encontra a maior ocorrência compatível com a cadeia consultada iniciando
93+ da posição atual do cursor: current_position; e posteriomente
94+ consultando o histórico existente dentro da janela para encontrar
95+ uma ocorrência compatível.
10196 """
10297 # Define o endereço limite do buffer baseado no cursor atual
103- end_of_buffer = min (
104- self .CURSOR + self .MAX_LOOKAHEAD_BUFFER ,
105- len (self .data ) + 1
106- )
98+ end_of_buffer = min (self .CURSOR + self .MAX_LOOKAHEAD_BUFFER , len (self .data ) + 1 )
10799 # Define a distancia e o tamanho da melhor ocorrencia para seu
108100 # estado inicial (nenhum ocorrencia encontrada)
109101 best_match_distance = - 1
@@ -120,23 +112,22 @@ def find_longest_match(self):
120112 # respeitando o tamanho máximo da janela
121113 start_index = max (0 , self .CURSOR - self .MAX_WINDOW_SIZE )
122114 # Armazena a ocorrencia a ser pesquisada
123- ocurrence = self .data [self .CURSOR : i ]
115+ ocurrence = self .data [self .CURSOR : i ]
124116
125117 # Percorre o arquivo apartir do início da ocorrência
126118 # em busca da maior cadeia compativel existente no arquivo
127119 for j in range (start_index , self .CURSOR ):
128120 compatible_chain_length = len (ocurrence ) // (self .CURSOR - j )
129121 compatible_chain_last = len (ocurrence ) % (self .CURSOR - j )
130- compatible_chain = self .data [j : self .CURSOR ]
122+ compatible_chain = self .data [j : self .CURSOR ]
131123 compatible_chain *= compatible_chain_length
132- compatible_chain += self .data [j : j + compatible_chain_last ]
124+ compatible_chain += self .data [j : j + compatible_chain_last ]
133125
134126 # Se alguma cadeia compativel for encontrada e
135127 # seu tamanho for MAIOR que o do ultimo
136128 # resultado definido como melhor
137129 # então aceita a mesma como sendo a melhor opção.
138- if compatible_chain == ocurrence and len (
139- ocurrence ) > best_match_length :
130+ if compatible_chain == ocurrence and len (ocurrence ) > best_match_length :
140131 best_match_distance = self .CURSOR - j
141132 best_match_length = len (ocurrence )
142133
@@ -148,10 +139,10 @@ def find_longest_match(self):
148139
149140 def decompress (self , input_data ):
150141 """
151- Fornecido um arquivo de entrada comprimido, o seu conteúdo é descomprimido de
152- volta ao seu formato original, e escrito no arquivo de saída caso este seja
153- também fornecido. Se nenhum arquivo de saída for forncedido, os dados
154- descomprimidos são retornados como uma string
142+ Fornecido um arquivo de entrada comprimido, o seu conteúdo é descomprimido de
143+ volta ao seu formato original, e escrito no arquivo de saída caso este seja
144+ também fornecido. Se nenhum arquivo de saída for forncedido, os dados
145+ descomprimidos são retornados como uma string
155146 """
156147 # Define a posição inicial do CURSOR como sendo 0
157148 # ou seja inicio do arquivo
@@ -208,7 +199,7 @@ def decompress(self, input_data):
208199 # Executa o bitshift pra separar os bits
209200 # de distancia dos bits de tamanho
210201 distance = (byte1 << 4 ) | (byte2 >> 4 )
211- length = ( byte2 & 0xf )
202+ length = byte2 & 0xF
212203
213204 # Copia a cadeia indicada para a posição atual
214205 # do cursor na janela de decompressão
@@ -223,18 +214,18 @@ def decompress(self, input_data):
223214
224215 def compress (self , input_data ):
225216 """
226- Fornecido o arquivo de entrada, seu contéudo é comprimido aplicando um algoritmo
227- de compressão LZ77 simples.
228- O formato de compressão tem o seguinte padrão:
229- - bit de valor 0 seguido por 8 bits (1 byte por caracter) quando não existem ocorrências
230- prévias na janela de compressão.
231- - bit de valor 1 seguido pelo ponteiro de 12 bits (distância entre o inicio da ocorrência
232- até a posição atual do cursor) e mais 4 bits (responsaveis pelo tamanho da ocorrência)
233-
234- Se o arquivo de saída for fornecido, os dados comprimidos serão escritos em
235- formato binário dentro do mesmo. Do contrário será retornado um bitarray.
236-
237- Se o parâmetro verbose estiver habilitado, a descrição da compressão é exibida.
217+ Fornecido o arquivo de entrada, seu contéudo é comprimido aplicando um algoritmo
218+ de compressão LZ77 simples.
219+ O formato de compressão tem o seguinte padrão:
220+ - bit de valor 0 seguido por 8 bits (1 byte por caracter) quando não existem ocorrências
221+ prévias na janela de compressão.
222+ - bit de valor 1 seguido pelo ponteiro de 12 bits (distância entre o inicio da ocorrência
223+ até a posição atual do cursor) e mais 4 bits (responsaveis pelo tamanho da ocorrência)
224+
225+ Se o arquivo de saída for fornecido, os dados comprimidos serão escritos em
226+ formato binário dentro do mesmo. Do contrário será retornado um bitarray.
227+
228+ Se o parâmetro verbose estiver habilitado, a descrição da compressão é exibida.
238229 """
239230 # Define a posição inicial do CURSOR como sendo 0
240231 # ou seja inicio do arquivo
@@ -249,7 +240,6 @@ def compress(self, input_data):
249240
250241 # Percorre o arquivo inteiro
251242 while self .CURSOR < len (self .data ):
252-
253243 # Procura pela melhor e maior ocorrência
254244 # compativel com a ocorrência existente
255245 # no cursor atual
@@ -264,8 +254,9 @@ def compress(self, input_data):
264254 x = (best_match_distance >> 0x4 ).to_bytes (1 , self .ENDIAN_TYPE )
265255 # Segundo nibble da distancia acrescido do tamanho
266256 # formando assim o par LZ
267- y = (((best_match_distance & 0xf ) << 4 ) |
268- best_match_length ).to_bytes (1 , self .ENDIAN_TYPE )
257+ y = (((best_match_distance & 0xF ) << 4 ) | best_match_length ).to_bytes (
258+ 1 , self .ENDIAN_TYPE
259+ )
269260
270261 lz_window .append (1 )
271262 lz_window .frombytes (x )
@@ -274,8 +265,11 @@ def compress(self, input_data):
274265 # Se o debug estiver ativo, exibe as informações da cadeia
275266 # encontrada
276267 if self .ENABLE_DEBUG :
277- print ("<COMPRESSED, {}, {}>" .format (
278- best_match_distance , best_match_length ))
268+ print (
269+ "<COMPRESSED, {}, {}>" .format (
270+ best_match_distance , best_match_length
271+ )
272+ )
279273
280274 # Incrementa a posição do cursor
281275 self .CURSOR += best_match_length
@@ -290,8 +284,7 @@ def compress(self, input_data):
290284
291285 # Se o debug estiver ativo, exibe o byte decomprimido
292286 if self .ENABLE_DEBUG :
293- print ("<UNCOMPRESSED, {:c}>" .format (
294- self .data [self .CURSOR ]))
287+ print ("<UNCOMPRESSED, {:c}>" .format (self .data [self .CURSOR ]))
295288
296289 # Incrementa em 1 a posição do cursor
297290 self .CURSOR += 1
0 commit comments