| 1 |
-------------------------------------------------------------------------------- |
|---|
| 2 |
-- Title: base64.lua |
|---|
| 3 |
-- Description: Like a square peg in a round hole |
|---|
| 4 |
-- Author: Raphaël Szwarc http://alt.textdrive.com/lua/ |
|---|
| 5 |
-- Creation Date: January 30, 2007 |
|---|
| 6 |
-- Legal: Copyright (C) 2007 Raphaël Szwarc |
|---|
| 7 |
-- Under the terms of the MIT License |
|---|
| 8 |
-- http://www.opensource.org/licenses/mit-license.html |
|---|
| 9 |
-------------------------------------------------------------------------------- |
|---|
| 10 |
|
|---|
| 11 |
-- import dependencies |
|---|
| 12 |
local math = require( 'math' ) |
|---|
| 13 |
local string = require( 'string' ) |
|---|
| 14 |
|
|---|
| 15 |
local getmetatable = getmetatable |
|---|
| 16 |
local setmetatable = setmetatable |
|---|
| 17 |
local tostring = tostring |
|---|
| 18 |
|
|---|
| 19 |
-------------------------------------------------------------------------------- |
|---|
| 20 |
-- base64 |
|---|
| 21 |
-------------------------------------------------------------------------------- |
|---|
| 22 |
|
|---|
| 23 |
module( 'base64' ) |
|---|
| 24 |
_VERSION = '1.0' |
|---|
| 25 |
|
|---|
| 26 |
local self = setmetatable( _M, {} ) |
|---|
| 27 |
local meta = getmetatable( self ) |
|---|
| 28 |
|
|---|
| 29 |
-------------------------------------------------------------------------------- |
|---|
| 30 |
-- Utilities |
|---|
| 31 |
-------------------------------------------------------------------------------- |
|---|
| 32 |
|
|---|
| 33 |
-- working lua base64 codec (c) 2006-2008 by Alex Kloss |
|---|
| 34 |
-- http://www.it-rfc.de |
|---|
| 35 |
-- http://lua-users.org/wiki/BaseSixtyFour |
|---|
| 36 |
|
|---|
| 37 |
-- bitshift functions (<<, >> equivalent) |
|---|
| 38 |
-- shift left |
|---|
| 39 |
local function lsh(value,shift) |
|---|
| 40 |
return (value*(2^shift)) % 256 |
|---|
| 41 |
end |
|---|
| 42 |
|
|---|
| 43 |
-- shift right |
|---|
| 44 |
local function rsh(value,shift) |
|---|
| 45 |
return math.floor(value/2^shift) % 256 |
|---|
| 46 |
end |
|---|
| 47 |
|
|---|
| 48 |
-- return single bit (for OR) |
|---|
| 49 |
local function bit(x,b) |
|---|
| 50 |
return (x % 2^b - x % 2^(b-1) > 0) |
|---|
| 51 |
end |
|---|
| 52 |
|
|---|
| 53 |
-- logic OR for number values |
|---|
| 54 |
local function lor(x,y) |
|---|
| 55 |
result = 0 |
|---|
| 56 |
for p=1,8 do result = result + (((bit(x,p) or bit(y,p)) == true) and 2^(p-1) or 0) end |
|---|
| 57 |
return result |
|---|
| 58 |
end |
|---|
| 59 |
|
|---|
| 60 |
-- encryption table |
|---|
| 61 |
local base64chars = {[0]='A',[1]='B',[2]='C',[3]='D',[4]='E',[5]='F',[6]='G',[7]='H',[8]='I',[9]='J',[10]='K',[11]='L',[12]='M',[13]='N',[14]='O',[15]='P',[16]='Q',[17]='R',[18]='S',[19]='T',[20]='U',[21]='V',[22]='W',[23]='X',[24]='Y',[25]='Z',[26]='a',[27]='b',[28]='c',[29]='d',[30]='e',[31]='f',[32]='g',[33]='h',[34]='i',[35]='j',[36]='k',[37]='l',[38]='m',[39]='n',[40]='o',[41]='p',[42]='q',[43]='r',[44]='s',[45]='t',[46]='u',[47]='v',[48]='w',[49]='x',[50]='y',[51]='z',[52]='0',[53]='1',[54]='2',[55]='3',[56]='4',[57]='5',[58]='6',[59]='7',[60]='8',[61]='9',[62]='-',[63]='_'} |
|---|
| 62 |
|
|---|
| 63 |
-- function encode |
|---|
| 64 |
-- encodes input string to base64. |
|---|
| 65 |
local function enc(data) |
|---|
| 66 |
local bytes = {} |
|---|
| 67 |
local result = "" |
|---|
| 68 |
for spos=0,string.len(data)-1,3 do |
|---|
| 69 |
for byte=1,3 do bytes[byte] = string.byte(string.sub(data,(spos+byte))) or 0 end |
|---|
| 70 |
result = string.format('%s%s%s%s%s',result,base64chars[rsh(bytes[1],2)],base64chars[lor(lsh((bytes[1] % 4),4), rsh(bytes[2],4))] or "=",((#data-spos) > 1) and base64chars[lor(lsh(bytes[2] % 16,2), rsh(bytes[3],6))] or "=",((#data-spos) > 2) and base64chars[(bytes[3] % 64)] or "=") |
|---|
| 71 |
end |
|---|
| 72 |
return result |
|---|
| 73 |
end |
|---|
| 74 |
|
|---|
| 75 |
-- decryption table |
|---|
| 76 |
local base64bytes = {['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,['J']=9,['K']=10,['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['-']=62,['_']=63,['=']=nil} |
|---|
| 77 |
|
|---|
| 78 |
-- function decode |
|---|
| 79 |
-- decode base64 input to string |
|---|
| 80 |
local function dec(data) |
|---|
| 81 |
local chars = {} |
|---|
| 82 |
local result="" |
|---|
| 83 |
for dpos=0,string.len(data)-1,4 do |
|---|
| 84 |
for char=1,4 do chars[char] = base64bytes[(string.sub(data,(dpos+char),(dpos+char)) or "=")] end |
|---|
| 85 |
result = string.format('%s%s%s%s',result,string.char(lor(lsh(chars[1],2), rsh(chars[2],4))),(chars[3] ~= nil) and string.char(lor(lsh(chars[2],4), rsh(chars[3],2))) or "",(chars[4] ~= nil) and string.char(lor(lsh(chars[3],6) % 192, (chars[4]))) or "") |
|---|
| 86 |
end |
|---|
| 87 |
return result |
|---|
| 88 |
end |
|---|
| 89 |
|
|---|
| 90 |
-------------------------------------------------------------------------------- |
|---|
| 91 |
-- Metamethods |
|---|
| 92 |
-------------------------------------------------------------------------------- |
|---|
| 93 |
|
|---|
| 94 |
function meta:__call( aValue, shouldEncode ) |
|---|
| 95 |
aValue = tostring( aValue or '' ) |
|---|
| 96 |
|
|---|
| 97 |
if shouldEncode then |
|---|
| 98 |
return enc( aValue ) |
|---|
| 99 |
end |
|---|
| 100 |
|
|---|
| 101 |
return dec( aValue ) |
|---|
| 102 |
end |
|---|