yohanbohan

Base64 Lua

Apr 1st, 2024
8
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.00 KB | None | 0 0
  1. local base64 = {}
  2.  
  3. local extract = _G.bit32 and _G.bit32.extract -- Lua 5.2/Lua 5.3 in compatibility mode
  4. if not extract then
  5. if _G.bit then -- LuaJIT
  6. local shl, shr, band = _G.bit.lshift, _G.bit.rshift, _G.bit.band
  7. extract = function( v, from, width )
  8. return band( shr( v, from ), shl( 1, width ) - 1 )
  9. end
  10. elseif _G._VERSION == "Lua 5.1" then
  11. extract = function( v, from, width )
  12. local w = 0
  13. local flag = 2^from
  14. for i = 0, width-1 do
  15. local flag2 = flag + flag
  16. if v % flag2 >= flag then
  17. w = w + 2^i
  18. end
  19. flag = flag2
  20. end
  21. return w
  22. end
  23. else -- Lua 5.3+
  24. extract = load[[return function( v, from, width )
  25. return ( v >> from ) & ((1 << width) - 1)
  26. end]]()
  27. end
  28. end
  29.  
  30.  
  31. function base64.makeencoder( s62, s63, spad )
  32. local encoder = {}
  33. for b64code, char in pairs{[0]='A','B','C','D','E','F','G','H','I','J',
  34. 'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',
  35. 'Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
  36. 'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2',
  37. '3','4','5','6','7','8','9',s62 or '+',s63 or'/',spad or'='} do
  38. encoder[b64code] = char:byte()
  39. end
  40. return encoder
  41. end
  42.  
  43. function base64.makedecoder( s62, s63, spad )
  44. local decoder = {}
  45. for b64code, charcode in pairs( base64.makeencoder( s62, s63, spad )) do
  46. decoder[charcode] = b64code
  47. end
  48. return decoder
  49. end
  50.  
  51. local DEFAULT_ENCODER = base64.makeencoder()
  52. local DEFAULT_DECODER = base64.makedecoder()
  53.  
  54. local char, concat = string.char, table.concat
  55.  
  56. function base64.encode( str, encoder, usecaching )
  57. encoder = encoder or DEFAULT_ENCODER
  58. local t, k, n = {}, 1, #str
  59. local lastn = n % 3
  60. local cache = {}
  61. for i = 1, n-lastn, 3 do
  62. local a, b, c = str:byte( i, i+2 )
  63. local v = a*0x10000 + b*0x100 + c
  64. local s
  65. if usecaching then
  66. s = cache[v]
  67. if not s then
  68. s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
  69. cache[v] = s
  70. end
  71. else
  72. s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
  73. end
  74. t[k] = s
  75. k = k + 1
  76. end
  77. if lastn == 2 then
  78. local a, b = str:byte( n-1, n )
  79. local v = a*0x10000 + b*0x100
  80. t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[64])
  81. elseif lastn == 1 then
  82. local v = str:byte( n )*0x10000
  83. t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[64], encoder[64])
  84. end
  85. return concat( t )
  86. end
  87.  
  88. function base64.decode( b64, decoder, usecaching )
  89. decoder = decoder or DEFAULT_DECODER
  90. local pattern = '[^%w%+%/%=]'
  91. if decoder then
  92. local s62, s63
  93. for charcode, b64code in pairs( decoder ) do
  94. if b64code == 62 then s62 = charcode
  95. elseif b64code == 63 then s63 = charcode
  96. end
  97. end
  98. pattern = ('[^%%w%%%s%%%s%%=]'):format( char(s62), char(s63) )
  99. end
  100. b64 = b64:gsub( pattern, '' )
  101. local cache = usecaching and {}
  102. local t, k = {}, 1
  103. local n = #b64
  104. local padding = b64:sub(-2) == '==' and 2 or b64:sub(-1) == '=' and 1 or 0
  105. for i = 1, padding > 0 and n-4 or n, 4 do
  106. local a, b, c, d = b64:byte( i, i+3 )
  107. local s
  108. if usecaching then
  109. local v0 = a*0x1000000 + b*0x10000 + c*0x100 + d
  110. s = cache[v0]
  111. if not s then
  112. local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
  113. s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
  114. cache[v0] = s
  115. end
  116. else
  117. local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
  118. s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
  119. end
  120. t[k] = s
  121. k = k + 1
  122. end
  123. if padding == 1 then
  124. local a, b, c = b64:byte( n-3, n-1 )
  125. local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40
  126. t[k] = char( extract(v,16,8), extract(v,8,8))
  127. elseif padding == 2 then
  128. local a, b = b64:byte( n-3, n-2 )
  129. local v = decoder[a]*0x40000 + decoder[b]*0x1000
  130. t[k] = char( extract(v,16,8))
  131. end
  132. return concat( t )
  133. end
  134.  
  135. return base64local base64 = {}
  136.  
  137. local extract = _G.bit32 and _G.bit32.extract -- Lua 5.2/Lua 5.3 in compatibility mode
  138. if not extract then
  139. if _G.bit then -- LuaJIT
  140. local shl, shr, band = _G.bit.lshift, _G.bit.rshift, _G.bit.band
  141. extract = function( v, from, width )
  142. return band( shr( v, from ), shl( 1, width ) - 1 )
  143. end
  144. elseif _G._VERSION == "Lua 5.1" then
  145. extract = function( v, from, width )
  146. local w = 0
  147. local flag = 2^from
  148. for i = 0, width-1 do
  149. local flag2 = flag + flag
  150. if v % flag2 >= flag then
  151. w = w + 2^i
  152. end
  153. flag = flag2
  154. end
  155. return w
  156. end
  157. else -- Lua 5.3+
  158. extract = load[[return function( v, from, width )
  159. return ( v >> from ) & ((1 << width) - 1)
  160. end]]()
  161. end
  162. end
  163.  
  164.  
  165. function base64.makeencoder( s62, s63, spad )
  166. local encoder = {}
  167. for b64code, char in pairs{[0]='A','B','C','D','E','F','G','H','I','J',
  168. 'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',
  169. 'Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
  170. 'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2',
  171. '3','4','5','6','7','8','9',s62 or '+',s63 or'/',spad or'='} do
  172. encoder[b64code] = char:byte()
  173. end
  174. return encoder
  175. end
  176.  
  177. function base64.makedecoder( s62, s63, spad )
  178. local decoder = {}
  179. for b64code, charcode in pairs( base64.makeencoder( s62, s63, spad )) do
  180. decoder[charcode] = b64code
  181. end
  182. return decoder
  183. end
  184.  
  185. local DEFAULT_ENCODER = base64.makeencoder()
  186. local DEFAULT_DECODER = base64.makedecoder()
  187.  
  188. local char, concat = string.char, table.concat
  189.  
  190. function base64.encode( str, encoder, usecaching )
  191. encoder = encoder or DEFAULT_ENCODER
  192. local t, k, n = {}, 1, #str
  193. local lastn = n % 3
  194. local cache = {}
  195. for i = 1, n-lastn, 3 do
  196. local a, b, c = str:byte( i, i+2 )
  197. local v = a*0x10000 + b*0x100 + c
  198. local s
  199. if usecaching then
  200. s = cache[v]
  201. if not s then
  202. s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
  203. cache[v] = s
  204. end
  205. else
  206. s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
  207. end
  208. t[k] = s
  209. k = k + 1
  210. end
  211. if lastn == 2 then
  212. local a, b = str:byte( n-1, n )
  213. local v = a*0x10000 + b*0x100
  214. t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[64])
  215. elseif lastn == 1 then
  216. local v = str:byte( n )*0x10000
  217. t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[64], encoder[64])
  218. end
  219. return concat( t )
  220. end
  221.  
  222. function base64.decode( b64, decoder, usecaching )
  223. decoder = decoder or DEFAULT_DECODER
  224. local pattern = '[^%w%+%/%=]'
  225. if decoder then
  226. local s62, s63
  227. for charcode, b64code in pairs( decoder ) do
  228. if b64code == 62 then s62 = charcode
  229. elseif b64code == 63 then s63 = charcode
  230. end
  231. end
  232. pattern = ('[^%%w%%%s%%%s%%=]'):format( char(s62), char(s63) )
  233. end
  234. b64 = b64:gsub( pattern, '' )
  235. local cache = usecaching and {}
  236. local t, k = {}, 1
  237. local n = #b64
  238. local padding = b64:sub(-2) == '==' and 2 or b64:sub(-1) == '=' and 1 or 0
  239. for i = 1, padding > 0 and n-4 or n, 4 do
  240. local a, b, c, d = b64:byte( i, i+3 )
  241. local s
  242. if usecaching then
  243. local v0 = a*0x1000000 + b*0x10000 + c*0x100 + d
  244. s = cache[v0]
  245. if not s then
  246. local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
  247. s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
  248. cache[v0] = s
  249. end
  250. else
  251. local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
  252. s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
  253. end
  254. t[k] = s
  255. k = k + 1
  256. end
  257. if padding == 1 then
  258. local a, b, c = b64:byte( n-3, n-1 )
  259. local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40
  260. t[k] = char( extract(v,16,8), extract(v,8,8))
  261. elseif padding == 2 then
  262. local a, b = b64:byte( n-3, n-2 )
  263. local v = decoder[a]*0x40000 + decoder[b]*0x1000
  264. t[k] = char( extract(v,16,8))
  265. end
  266. return concat( t )
  267. end
  268.  
  269. return base64
Add Comment
Please, Sign In to add comment