Advertisement
Alakazard12

base64

Mar 25th, 2014
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.34 KB | None | 0 0
  1.  
  2. -- Make some functions easier to write
  3. local floor = math.floor
  4. local sub = string.sub
  5. local gsub = string.gsub
  6. local rem = table.remove
  7.  
  8. -- Our base64 value table
  9. local base64 = { ['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,
  10.                 ['J']=9,['K']=10,['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,
  11.                 ['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,
  12.                 ['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,
  13.                 ['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,
  14.                 ['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,
  15.                 ['x']=49,['y']=50,['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,
  16.                 ['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['+']=62,['/']=63,['=']=nil}
  17.  
  18. -- Decimal values for binary digits
  19. local bin ={}
  20. local mult = 1
  21. for i = 1,40 do
  22.     bin[i] = mult
  23.     mult = mult*2
  24. end
  25.  
  26. -- A buffer we will use to process the bits
  27. local buffer = 0
  28. local pos = 0
  29. local function clearBuffer()
  30.     buffer = 0
  31.     pos = 1
  32. end
  33.  
  34. -- Shift all of the bits up in the buffer and put the base64 number on the bottom
  35. local function pushBase64(n)
  36.     if base64[n] == nil then return end
  37.     buffer = buffer * bin[7] + base64[n]
  38.     pos = pos + 6
  39. end
  40.  
  41. -- Get an int out of the buffer. This is tricky. The byte order is in little endian so we're going
  42. -- to have to isolate and cut the bytes out and then move them around.
  43. local function getInt()
  44.     -- If our buffer isn't filled all the way then fill it with zeros
  45.     while pos < 33 do
  46.         buffer = buffer * bin[2]
  47.         pos = pos + 1
  48.     end
  49.     -- Move the buffer position to just below the integer.
  50.     pos = pos - 32
  51.    
  52.     -- Swap the first and forth byte and then the second and third.
  53.     local tmp = floor((buffer%bin[33+pos-1])/bin[25+pos-1]) +
  54.                 floor((buffer%bin[25+pos-1])/bin[17+pos-1])*bin[9] +
  55.                 floor((buffer%bin[17+pos-1])/bin[9+pos-1])*bin[17] +
  56.                 floor((buffer%bin[9+pos-1])/bin[pos])*bin[25]
  57.    
  58.     -- We've got our integer so let's cut that portion out of the buffer
  59.     buffer = buffer % bin[pos]
  60.     -- Return the int
  61.     return  tmp
  62. end
  63.  
  64. -- Get a byte out of the buffer
  65. local function getByte()
  66.     -- If our buffer isn't filled all the way then fill it with zeros
  67.     while pos < 9 do
  68.         buffer = buffer * bin[2]
  69.         pos = pos + 1
  70.     end
  71.     -- Move the buffer position to just below the byte.
  72.     pos = pos - 8
  73.     -- Cut out the byte
  74.     local tmp = floor((buffer%bin[9+pos-1])/bin[pos])
  75.     -- Delete the byte from the buffer
  76.     buffer = buffer % bin[pos]
  77.     -- Return the byte
  78.     return tmp
  79. end
  80.  
  81. -- Glues together an integer from four bytes. Little endian
  82. local function glueInt(b1, b2, b3, b4)
  83.     return b1%bin[9] + b2%bin[9]*bin[9] + b3%bin[9]*bin[17] + b4%bin[9]*bin[25]
  84. end
  85.  
  86. -- A Lua set that will filter out characters that aren't in the base64 table
  87. local set = "[^%a%d%+%/%=]"
  88.  
  89. -- Decodes a base64 string into the given type
  90. local function decode(mode, raw)
  91.  
  92.     -- Make sure the mode is supported
  93.     assert(mode=="string" or mode=="int" or mode=="byte", "Base64 decode - Invalid mode: " .. mode)
  94.  
  95.     -- Clear the buffer
  96.     clearBuffer()
  97.    
  98.     -- Filters undefined characters out of the string
  99.     raw = gsub(raw, set, "")
  100.    
  101.     local size = 0          -- Size of the returned type in bits
  102.     local val = {}          -- A table containing the data to be returned
  103.     local raw_pos = 1       -- The position of the progress through the raw base64 string
  104.     local raw_size = #raw   -- The size of the base64 string
  105.     local char = ""         -- The current base64 character to be processed
  106.    
  107.     -- If we're expected to return an int then the bit size is 32, otherwise it's 8
  108.     if mode == "int" then size = 32 else size = 8 end
  109.    
  110.     -- While we still have input
  111.     while raw_pos <= raw_size do
  112.         -- Fill the buffer until we have enough bits
  113.         while pos <= size and raw_pos <= raw_size do
  114.             char = sub(raw,raw_pos,raw_pos)
  115.             pushBase64( char )
  116.             raw_pos = raw_pos + 1
  117.         end
  118.         -- If a nil character is encountered the end the loop
  119.         if char == "=" then break end
  120.         -- Get data from the buffer depending on the type
  121.         if mode == "string" then val[#val+1] = string.char( getByte() ) end
  122.         if mode == "byte" then val[#val+1] = getByte() end
  123.         if mode == "int" then val[#val+1] = getInt() end
  124.     end
  125.    
  126.     if mode == "string" then return table.concat(val) end
  127.     return val
  128. end
  129.  
  130. -- Returns the functions
  131. return {decode = decode, glueInt = glueInt, base64 = base64}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement