-
Notifications
You must be signed in to change notification settings - Fork 0
/
lz77_compression.sf
72 lines (52 loc) · 1.27 KB
/
lz77_compression.sf
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/ruby
# Implementation of the LZ77 compression algorithm.
define(
CHUNK_SIZE = (1 << 16),
)
func compression (str) {
var rep = []
var la = 0
var prefix = ''
var chars = str.chars
var end = chars.end
while (la <= end) {
var n = 1
var p = 0
var token = chars[la]
while ((n < 255) && (la+n <= end) && ((var tmp = prefix.index(token, p)) >= 0)) {
p = tmp
token += chars[la + n]
++n
}
--n
var c = chars[la + n]
rep << [p, n, c.ord]
la += n+1
prefix += token
}
rep.map {|e| 'SCC'.pack(e...) }.join
}
func decompression (str) {
var ret = ''
var chunk = ''
for slice in (str.slices(4)) {
var (s, l, c) = 'SCC'.unpack(slice)
chunk += (chunk.substr(s, l) + 'C'.pack(c))
if (chunk.len >= CHUNK_SIZE) {
ret += chunk
chunk = ''
}
}
if (chunk != '') {
ret += chunk
}
return ret
}
# How to use:
var compressed = compression('TOBEORNOTTOBEORTOBEORNOT')
say compressed.dump
var decompressed = decompression(compressed)
say decompressed
__END__
"\0\0\0T\0\0\0O\0\0\0B\0\0\0E\1\0\1R\0\0\0N\1\0\1T\0\0\6T\1\0\aT"
TOBEORNOTTOBEORTOBEORNOT