2018-03-19 12:27:30 +11:00
|
|
|
-- This is released into the public domain.
|
|
|
|
-- No warranty is provided, implied or otherwise.
|
|
|
|
|
2018-06-10 09:06:12 +10:00
|
|
|
-- BDIVIDE r5 edition
|
|
|
|
-- Algorithm simplified for smaller implementation and potentially better compression
|
2018-03-19 10:10:54 +11:00
|
|
|
-- format:
|
|
|
|
-- 0-127 for constants
|
2018-06-10 09:06:12 +10:00
|
|
|
-- <128 + (length - 4)>, <position high>, <position low>
|
|
|
|
-- Position is where in the window it was found, minus 1.
|
|
|
|
-- windowSize must be the same between the encoder and decoder,
|
|
|
|
-- and is the amount of data preserved after cropping.
|
2018-03-19 10:10:54 +11:00
|
|
|
|
|
|
|
io.write("\x00") -- initiation character
|
|
|
|
|
2018-06-10 09:06:12 +10:00
|
|
|
local blk = io.read("*a")
|
|
|
|
local windowSize = 0x10000
|
|
|
|
local windowData = ("\x00"):rep(windowSize)
|
|
|
|
|
|
|
|
local function crop(data)
|
|
|
|
windowData = (windowData .. data):sub(-windowSize)
|
2018-03-19 10:10:54 +11:00
|
|
|
end
|
|
|
|
|
2018-06-10 09:06:12 +10:00
|
|
|
while blk ~= "" do
|
|
|
|
local bestData = blk:sub(1, 1)
|
|
|
|
local bestRes = bestData
|
|
|
|
for lm = 0, 127 do
|
|
|
|
local al = lm + 4
|
|
|
|
local pfx = blk:sub(1, al)
|
|
|
|
if #pfx ~= al then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
local p = windowData:find(pfx, 1, true)
|
|
|
|
if not p then
|
|
|
|
break
|
2018-03-19 10:10:54 +11:00
|
|
|
end
|
2018-06-10 09:06:12 +10:00
|
|
|
local pm = p - 1
|
2018-12-24 10:51:30 +11:00
|
|
|
local thirdByte = pm % 256
|
|
|
|
-- anti ']'-corruption helper
|
|
|
|
if thirdByte ~= 93 then
|
|
|
|
bestData = string.char(128 + lm, math.floor(pm / 256), thirdByte)
|
|
|
|
bestRes = pfx
|
|
|
|
end
|
2018-03-19 10:10:54 +11:00
|
|
|
end
|
2018-06-10 09:06:12 +10:00
|
|
|
-- ok, encode!
|
|
|
|
io.write(bestData)
|
|
|
|
crop(bestRes)
|
|
|
|
blk = blk:sub(#bestRes + 1)
|
2018-03-19 10:10:54 +11:00
|
|
|
end
|
|
|
|
|