Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---------------------------------------------------------------------------------------------------------------------
- -- Pack Functions
- ---------------------------------------------------------------------------------------------------------------------
- local MAX_PACK_VALUE = 2 ^ 53 -- Beyond this value, doubles have a consecutive gap of 2.
- local function createByteReader(buffer)
- local read = buffer:gmatch(".")
- return function ()
- local char = read()
- if char then
- return char:byte()
- end
- end
- end
- local function packInt(value)
- assert(math.abs(value) < MAX_PACK_VALUE, "packInt - Cannot pack values above 2^53 reliably!")
- local pack = ""
- local sign = value / math.abs(value)
- local value = math.floor(value * sign)
- while value > 0 do
- pack = pack .. string.char(value % 256)
- value = math.floor(value / 256)
- end
- local flags = #pack
- if sign < 0 then
- flags = flags + 16
- end
- return string.char(flags) .. pack
- end
- local function packInts(ints)
- if #ints > 255 then
- error("packInts - Too many ints to pack!")
- end
- local packed = string.char(#ints)
- for _,value in pairs(ints) do
- packed = packed .. packInt(value)
- end
- return packed
- end
- local function unpackInt(input)
- local readByte
- if type(input) == "function" then
- readByte = input
- elseif type(input) == "string" then
- readByte = createByteReader(packed)
- else
- error("unpackInt - Argument #1 should be either an iterator function or a packed int string.")
- end
- local value = 0
- local flags = readByte()
- local length = flags % 16
- local negate = math.floor(flags / 16)
- for i = 0, length - 1 do
- local byte = readByte()
- local layer = 2 ^ (8 * i)
- value = value + (byte * layer)
- end
- if negate > 0 then
- value = -value
- end
- return value
- end
- local function unpackInts(packed)
- local readByte = createByteReader(packed)
- local numInts = readByte()
- local values = {}
- for i = 1, numInts do
- local value = unpackInt(readByte)
- table.insert(values, value)
- end
- return values
- end
- ---------------------------------------------------------------------------------------------------------------------
- -- Generate Ints
- ---------------------------------------------------------------------------------------------------------------------
- local values = {}
- local strings = {}
- for i = 1,200 do
- local lower = math.random(8, 36)
- local upper = math.random(8, 36)
- local value = math.random(-2 ^ lower, 2 ^ upper)
- local str = string.format("%i", value)
- table.insert(values, value)
- table.insert(strings, str)
- end
- ---------------------------------------------------------------------------------------------------------------------
- -- Prepare Output
- ---------------------------------------------------------------------------------------------------------------------
- local packBuffer = packInts(values)
- local readable = packBuffer:gsub(".", function (char)
- return string.format("%02X ", char:byte())
- end)
- local div = '\n' .. string.rep('-', 120) .. '\n'
- ---------------------------------------------------------------------------------------------------------------------
- -- Write Output
- ---------------------------------------------------------------------------------------------------------------------
- print(div)
- print("Values:\n\n" .. table.concat(strings, ", ") .. '\n')
- print("Bytes: " .. (#values * 8))
- print(div)
- print("Packed:\n\n" .. readable .. ‘\n’)
- print("Bytes: " .. #packBuffer)
- print(div)
- ---------------------------------------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement