-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlz77.py
More file actions
43 lines (39 loc) · 1.35 KB
/
lz77.py
File metadata and controls
43 lines (39 loc) · 1.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
"""
Compress and decompress data with lz77 algorithm
"""
def compress(text: str, buffer_limit=10) -> tuple[int, int, str]:
"""
compress text with lz77 algorithm
:param text: str text to compress
:param buffer_limit: int optional, max length for buffer, default=10
:return: tuple( (offset, lenght, next symbol) )
"""
result = []
i = 0
while True:
offset, length = 0, 0
buffer = text[max(0, i-buffer_limit): i]
# iterate and find offset that gives the biggest length
for j in range(1, len(buffer)+1):
for k in range(i, len(text)):
# compare buffer's and text's following letters
if buffer[-j + (k-i) % j] != text[k]:
break
if k-i > length:
offset, length = j, k-i
i += length + 1
result.append((offset, length, text[i-1] if i!= len(text) + 1 else ''))
if i >= len(text):
return result
def decompress(sequence: tuple[int, int, str]):
"""
decompress text from lz77 compression
:param sequence: tuple[offset, lenght, next symbol]
:return: string with decompressed text
"""
result = []
for a, b, symbol in sequence:
if a != 0:
result += result[-a:]*(b//a) + result[-a: -a + b%a]
result.append(symbol)
return ''.join(result)