Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[ first pack last pack need confirm
- local s = parser.encode{
- flags = { --flags:
- fp = true, -- first packet
- lp = true, -- last packet
- ld = true, -- need confirm (request or response for lost packets)
- sm = true -- service message
- },
- id = math.random(999), -- id of message (x32)
- count = 22, -- count of parts in message (x32)
- part = 21, -- current part number (x32)
- window = 4, -- data-travel window size (N msgs per loop)
- hash = 'qwer', -- hash of message
- data = 'yolooooo' -- data of message
- }
- ]]
- local byte = {}
- local insert = table.insert
- function byte.split(str, a, b)
- if type(a) == 'table' then
- local t = {}
- local cursor = 0
- for i = 1, #a do
- t[i] = str:sub(cursor+1, cursor+a[i])
- cursor = cursor + #(t[#t])
- end
- if b then return unpack(t) end
- return t
- end
- a, b = a or 0, b or 1
- return str:sub(a+1, a+b)
- end
- local max_int = 2^8
- function byte.encode(num, len)
- local char = string.char
- if len and num > max_int^len - 1 then
- error('Encode too big number: %d, max is %d', num, max^len)
- end
- local t={}
- while num > 0 do
- local rest = num % 255
- t[#t + 1] = char(rest)
- num = (num - rest) / 255
- end
- if len and #t < len then insert(t, ('\0'):rep(len - #t)) end
- return table.concat(t)
- end
- function byte.decode(c)
- local insert = table.insert
- local n = 0
- c = c:reverse()
- for j = 1, #c do
- n = n + c:sub(j, j):byte()*255^(#c-j)
- end
- return n
- end
- math.randomseed(os.time())
- local parser = {}
- local h_max = 4228250624
- local h_const = 0.6180339887*16
- local floor, ceil = math.floor, math.ceil
- function parser.hash(str, n)
- local sum = 0
- for i = 1, #str, ceil(#str / (n or 30)) do
- sum = sum + str:sub(i, i):byte()
- end
- return floor(h_max * (sum * h_const % 1))
- end
- local encode, decode = byte.encode, byte.decode
- local char, remove, split = string.char, table.remove, byte.split
- local sleep = require'socket'.sleep
- --[[
- encode table {
- flags = {
- fp = true/false
- sp = true/false
- ld = true/false
- sm = true/false
- },
- id = int,
- count = int,
- part = int,
- window = int,
- hash = int,
- data = string
- }
- ]]
- print('DECODE QWER', decode('qwer'))
- local f_mask = {'fp', 'sp', 'ld', 'sm'}
- function parser.encode(m)
- local encode = encode
- local buffer = {}
- local fl, _bit = 0, 128
- for i = 1, #f_mask do
- if m.flags[f_mask[i]] then
- fl = fl + _bit
- end
- _bit = _bit * .5
- end
- buffer[1] = 'R' -- 1
- buffer[2] = string.char(fl) -- 1
- buffer[3] = 'U' -- 1
- buffer[4] = encode(m.id, 4) -- 4
- buffer[5] = encode(m.count, 4) -- 4
- buffer[6] = encode(m.part, 4) -- 4
- buffer[7] = encode(m.window) -- 1
- buffer[8] = 'D' -- 1
- buffer[9] = encode(m.hash, 4) -- 4
- buffer[10] = 'P' -- 1
- buffer[11] = m.data -- data
- return table.concat(buffer)
- end
- local sub = string.sub
- local c_mask = {[1] = 'R', [3] = 'U', [17] = 'D', [22] = 'P'}
- -- checking message as RUDP-packet
- function parser.check(data)
- return data:sub(1,1) == 'R' and data:sub(3,3) == 'U'
- and data:sub(17,17) == 'D' and data:sub(22,22) == 'P'
- and data:sub(2, 2):byte() % 16 == 0
- end
- -- R, U, D and P signs position
- local sign = {10, 8, 3, 1}
- -- order of flags in le-byte
- local d_flags = {'fp', 'sp', 'ld', 'sm'}
- function parser.decode(data, force)
- if not parser.check(data) and not force then return end
- local decode = decode
- local raw = byte.split(data, {1, 1, 1, 4, 4, 4, 1, 1, 4, 1})
- -- remove signature
- remove(raw, 10)
- remove(raw, 8)
- remove(raw, 3)
- remove(raw, 1)
- -- SUPER FLAG EXTRACTOR 6000
- local buffer = {}
- buffer.flags = {}
- local flag, base = decode(raw[1]), 128
- for i, v in ipairs(d_flags) do
- if flag - base >= 0 then
- buffer.flags[v] = true
- flag = flag - base
- end
- base = base * .5
- end
- buffer.id = decode(raw[2])
- buffer.count = decode(raw[3])
- buffer.part = decode(raw[4])
- buffer.window = decode(raw[5])
- buffer.hash = decode(raw[6])
- buffer.data = data:sub(23)
- return buffer
- end
- return parser
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement