local function chars(str) local pos = 1 return function() if pos <= #str then local pos_was = pos pos = pos + 1 return str:sub(pos_was, pos_was), pos_was end end end -- from lua users wiki - magic local function unpackbits(num, width) local fl = {} local rem for i = 1,width do num,rem = math.modf(num/2) fl[#fl+1] = rem>=0.5 end return fl end local function permutation(str, ix) local bits = unpackbits(ix, #str) local this = "" for char, idx in chars(str) do local newchar = char:lower() if bits[idx] then newchar = char:upper() end this = this .. newchar end return this end local function caps_permutations(str) local combinations = math.pow(2, #str) - 1 local ret = {} for i = 0, combinations do table.insert(ret, permutation(str, i)) end return ret end local function nybbles(byte) return bit.brshift(bit.band(0xF0, byte), 4), bit.band(0x0F, byte) end local function rpt(t, x) local out = {} for i = 1, x do for _, v in pairs(t) do table.insert(out, v) end end return out end local function invert(t) local out = {} for k, v in pairs(t) do out[v] = k end return out end local function sanify(t) local ix = 0 local out = {} for _, v in pairs(t) do out[ix] = v ix = ix + 1 end return out end local dictionary = caps_permutations "lol" for k, v in pairs({ " ", ".", "?", "!", "#", ",", ";", ":" }) do table.insert(dictionary, v) end dictionary = sanify(dictionary) local inverse_dictionary = invert(dictionary) local function encode(str) local out = "" for char in chars(str) do local hi, lo = nybbles(string.byte(char)) out = out .. dictionary[hi] .. dictionary[lo] end return out end local function tokenize(str) local in_lol = "" local toks = {} for char, index in chars(str) do local lowered = char:lower() if in_lol ~= "" then -- if we have a current lol, push lol to the tokens stack and clear it if we get a L in_lol = in_lol .. char if lowered == "l" then table.insert(toks, in_lol) in_lol = "" elseif lowered == "o" then else error "Invalid character in LOL" end else if lowered == "l" then in_lol = char else table.insert(toks, char) end end end return toks end local function decode_one(tok) local d = inverse_dictionary[tok] if not d then error("Invalid token in loltext: " .. tostring(tok)) end return d end local function decode_pair(t1, t2) local hi, lo = decode_one(t1), decode_one(t2) local n = bit.bor(bit.blshift(hi, 4), lo) return string.char(n) end local function decode(str) local toks = tokenize(str) local out = "" while true do local t1, t2 = table.remove(toks, 1), table.remove(toks, 1) if not t1 or not t2 then break else out = out .. decode_pair(t1, t2) end end return out end local function repeat_function(f, times) return function(data, times_) local times = times_ or times local d = data for i = 1, times do d = f(d) end return d end end return { encode = repeat_function(encode, 1), decode = repeat_function(decode, 1) }