Advertisement
Doob

swab

Jan 20th, 2017
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.24 KB | None | 0 0
  1. --[[
  2. функция более требовательная к памяти, но менее к месту на диске
  3. если убрать лишнее, то 205 байт против 252
  4. local function df(s, x, n, c, u)
  5.   local f, r, a, b = "", ""
  6.   for i = 1, #s do
  7.     a, b = "", s:sub(i, i):byte()
  8.     for o = 0, x do
  9.       a = bit32.extract(b, o)..a
  10.     end
  11.     f = f..a
  12.     if #f == n then
  13.       for j = 1, #f, c do
  14.         r = r..string.char(tonumber(f:sub(j, j+u), 2))
  15.       end
  16.       f = ""
  17.     end
  18.   end
  19.   return r
  20. end
  21. ]]
  22.  
  23. --local str = "007qEUayuZKoyazpd0I53MuM5669ijgRTRAovkcgAWAhtgaa61bqIWjzAQWwrNSH79sboFJ7Y1xx4Dh3bjHcqyFIaYkeJLSq2qoORQ6TyILw00"
  24. local d, o, k, l, tl, tlm = {}
  25.  
  26. local function df(s, x, n, c, u) -- преобразование в стандартную 7b таблицу и обратно
  27.   local f, r, i, a, b = "", "", 1
  28.   while i <= #s do
  29.     if i == 1 then
  30.       a = ""
  31.       if n ~= 56 then -- получить код символа или индекс в словаре
  32.         b = string.byte(d[s:sub(i, i)])
  33.       else
  34.         b = s:sub(i, i):byte()
  35.       end
  36.       for o = 0, x do
  37.         a = bit32.extract(b, o)..a -- преобразовать в двоичный вид с границей "x"
  38.       end
  39.       f = f..a -- добавить к битовому потоку
  40.       if #f == n then -- если поток заполнен до значения "n"
  41.         for j = 1, #f, c do -- пройти по байтам, указанного размера
  42.           r = r..string.char(tonumber(f:sub(j, j+u), 2))
  43.           -- добавить готовый символ в выходную строку
  44.         end
  45.         f = ""
  46.       end
  47.       s = s:sub(2, #s)
  48.       i = i - 1
  49.     end
  50.     i = i + 1
  51.   end
  52.   return r
  53. end
  54.  
  55. local function encode() -- адаптивное кодирование
  56.   -- возвращает размер словаря + количество добавочных символов + закодированный текст
  57.   for i = 1, #str do -- составление таблицы символов
  58.     o = str:sub(i, i)
  59.     if not d[o] then -- добавление нового символа в таблицу
  60.       d[o] = true
  61.       table.insert(d, o)
  62.       if o:byte() > 126 then -- если сивол вне стандартной 7b таблицы
  63.         k = true -- пометить
  64.       end
  65.     end
  66.     if #d > 127 then print("ERROR: dictonary overflow") return end
  67.     -- если словарь переполнен - прервать программу
  68.   end
  69.   if not k then -- если входная строка может быть преобразованна в 7b
  70.     l = 56-math.fmod(#str, 56) -- рассчет количества недостающих символов
  71.     if l ~= 0 and l ~= 56 then
  72.       for i = 1, l do
  73.         str = str.." " -- добавление недостающих символов
  74.       end
  75.     end
  76.     return string.char(0, l)..df(str, 6, 56, 8, 7)
  77.     -- преобразование кодировки, добавление числа добавочных символов
  78.   else -- кодирование с новой таблицей
  79.     if #d < 17 then -- 5b кодировка
  80.       tlm, tl = 40, 4 -- битность*8, битность-1
  81.     elseif #d < 33 then -- 6b
  82.       tlm, tl = 48, 5
  83.     elseif #d < 65 then -- 7b
  84.       tlm, tl = 56, 6
  85.     end
  86.     l = tlm-math.fmod(#str, tlm)
  87.     if l ~= 0 and l ~= tlm then
  88.       for i = 1, l do
  89.         str = str.." "
  90.       end
  91.     end
  92.     return string.char(#d, l)..df(str, tl, tlm, 8, tl+2)
  93.   end
  94. end
  95.  
  96. local function decode()
  97.   tl, tlm = str:sub(1, 1):byte(), str:sub(2, 2):byte()
  98.  
  99.   if tl == 0 then -- декодирование в 8 бит из стандартной 7b
  100.     res = df(str, 7, 56, 7, 6)
  101.   else
  102.     for i = 1, tl do -- восстановление словаря
  103.       table.insert(d, str:sub(i, i))
  104.     end
  105.     if #d < 17 then
  106.       l = 40
  107.     elseif #d < 33 then
  108.       l = 48
  109.     elseif #d < 65 then
  110.       l = 56
  111.     end
  112.     str = str:sub(tl+1)
  113.     res = df(str, 7, l, 7, 6)
  114.   end
  115.   return res:sub(-tlm)
  116. end
  117.  
  118. print(str)
  119. ololo = encode()
  120. print(ololo)
  121. lolol = decode()
  122. print(lolol)
  123. print(#str, #ololo, #lolol)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement