Page 1 of 1

lua-ibyte [simple, plaintext compression]

Posted: Fri Mar 24, 2017 2:40 pm
by Hikitsune-Red
A few months ago I found myself entertained with breaking down files into binary data, then converting that binary data into an image to look at (for who knows what reason...) comprised of each pixel (either black or white) signifying a binary switch when I noted that for plaintext the image was smaller in filesize than their ".txt" originals.

It then occurred to me that I could lower the pixel count by assigning each pixel a single color but a different alpha value based on its ASCII value, and thus lua-ibyte was born (for - once again - no particular purpose).

While this really isn't much of a library, I thought I'd share it anyway. Utilizing PNG's lossless data compression, one can actually reduce plaintext data to a much smaller size, as well as obfuscating that data in a small way. I'll be using it in the future to compress and obfuscate save data, but all it really is good for is data visualization.

You can find it on github: https://github.com/Hikitsune-Red/lua-ibyte

Re: lua-ibyte [simple, plaintext compression]

Posted: Fri Mar 24, 2017 11:49 pm
by zorg
Hi and welcome to the forums!
Hikitsune-Red wrote: Fri Mar 24, 2017 2:40 pm A few months ago I found myself entertained with breaking down files into binary data, then converting that binary data into an image to look at (for who knows what reason...) comprised of each pixel (either black or white) signifying a binary switch
Data munging like this is always fun. :3
The game Spore also saved data into PNG as well, though in a different way.
Hikitsune-Red wrote: Fri Mar 24, 2017 2:40 pmwhen I noted that for plaintext the image was smaller in filesize than their ".txt" originals.
Yes, because the png format allows lossless (deflate, as in zip) compression.
Hikitsune-Red wrote: Fri Mar 24, 2017 2:40 pmIt then occurred to me that I could lower the pixel count by assigning each pixel a single color but a different alpha value based on its ASCII value, and thus lua-ibyte was born (for - once again - no particular purpose).
Technically, you could lower the pixel count more, if you used all 4 (R,G,B,A) channels to store data.
Hikitsune-Red wrote: Fri Mar 24, 2017 2:40 pmWhile this really isn't much of a library, I thought I'd share it anyway. Utilizing PNG's lossless data compression, one can actually reduce plaintext data to a much smaller size, as well as obfuscating that data in a small way. I'll be using it in the future to compress and obfuscate save data, but all it really is good for is data visualization.
But it is a librarly. :3
Hikitsune-Red wrote: Fri Mar 24, 2017 2:40 pmYou can find it on github: https://github.com/Hikitsune-Red/lua-ibyte
Okay, so i checked the code out, and i believe there may be an issue with it;

Code: Select all

for i, b in pairs(edat) do
The pairs iterator does not have a defined order, so there's very little chance of you getting back the original permutation of the data...
That said, your edat variable holds a numerically indexed table, so you should use ipairs (or just a numeric for, as you're using elsewhere) instead.

That and it can be optimized greatly, if you'd choose to.

Edit: I was bored;

Code: Select all

-- alternate version
local altVer = { }

function altVer.decode(imgData)
	local i, j       = 0, 0
	local r, g, b, a = imgData:getPixel(i, j)
	r = r * 0x1000000
	g = g * 0x10000
	b = b * 0x100
	a = a * 0x1
	local length = r + g + b + a
	local count  = 0
	i = i + 1

	local size  = imgData:getWidth()
	local strData  = {}

    local k  = i
	while k <= (size * size) - 1 do
		r, g, b, a = imgData:getPixel(i, j)

		if count > length then break end
		strData[#strData + 1] = string.char(r)
		count = count + 1

		if count > length then break end
		strData[#strData + 1] = string.char(g)
		count = count + 1

		if count > length then break end
		strData[#strData + 1] = string.char(b)
		count = count + 1

		if count > length then break end
		strData[#strData + 1] = string.char(a)
		count = count + 1

		i = i + 1
		if i >= size then i, j = 0, j + 1 end
		k = k + 1
	end

	return table.concat(strData)
end

function altVer.encode(strData)
	local length  = #strData
	local size    = math.ceil(math.sqrt(math.ceil((4 + length) / 4)))
	local imgData = love.image.newImageData(size, size)
	local i, j    = 0, 0
	local r, g, b, a

	r = math.floor(length / 0x1000000) % 0x100
	g = math.floor(length / 0x10000  ) % 0x100
	b = math.floor(length / 0x100    ) % 0x100
	a = math.floor(length / 0x1      ) % 0x100
	imgData:setPixel(i, j, r, g, b, a)
	i, j = i + 1, j + 1
	r,g,b,a = false, false, false, false

	for c in strData:gmatch(".") do
		if     not r then r = string.byte(c)
		elseif not g then g = string.byte(c)
		elseif not b then b = string.byte(c)
		elseif not a then a = string.byte(c)
		end
		if r and g and b and a then
			imgData:setPixel(i, j, r, g, b, a)
			r,g,b,a = false, false, false, false
		end
		i = i + 1
		if i >= size then i, j = 0, j + 1 end
	end

	if     b then imgData:setPixel(i, j, r, g, b, 0)
	elseif g then imgData:setPixel(i, j, r, g, 0, 0)
	elseif r then imgData:setPixel(i, j, r, 0, 0, 0)
	end

	local k  = (j    * size) + i
	while k <= (size * size) - 1 do
		--imgData:setPixel(x, y, 0, 0, 0, 0)
		imgData:setPixel(x, y,
			love.math.random(0,255), love.math.random(0,255),
			love.math.random(0,255), love.math.random(0,255))
		i = i + 1
		if i >= size then i, j = 0, j + 1 end
		k = k + 1
	end

	return imgData
end

-- altVer.read() would just be "return love.image.newImageData(imgFile)"

function altVer.write(imgData, fileOut)
	if fileOut ~= nil then
		if love.filesystem.exists(fileOut) then
			love.filesystem.remove(fileOut)
		end
		imgData:encode("png", fileOut)
	end
end

return altVer

Re: lua-ibyte [simple, plaintext compression]

Posted: Sat Mar 25, 2017 3:58 am
by raidho36
But LOVE already has data compression engines built in.

Re: lua-ibyte [simple, plaintext compression]

Posted: Sat Mar 25, 2017 4:14 am
by zorg
raidho36 wrote: Sat Mar 25, 2017 3:58 am But LOVE already has data compression engines built in.
This imo was nothing more than fun data obfus-(Also please implement me a lib that supports all existing, obscure, archaic, forgotten, not-yet-invented, not-yet-patent-free already-patent-free patent:"it's complicated" data de/compressors pls : 3)-cation, nothing serious... :v