#!/usr/local/bin/lua -- http://lua-users.org/wiki/BaseSixtyFour -- working lua base64 codec (c) 2006-2008 by Alex Kloss -- compatible with lua 5.1 -- http://www.it-rfc.de -- licensed under the terms of the LGPL2 -- bitshift functions (<<, >> equivalent) -- shift left function lsh(value,shift) return (value*(2^shift)) % 256 end -- shift right function rsh(value,shift) return math.floor(value/2^shift) % 256 end -- return single bit (for OR) function bit(x,b) return (x % 2^b - x % 2^(b-1) > 0) end -- logic OR for number values function lor(x,y) result = 0 for p=1,8 do result = result + (((bit(x,p) or bit(y,p)) == true) and 2^(p-1) or 0) end return result end -- encryption table 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]='_' } -- function encode -- encodes input string to base64. function enc(data) local bytes = {} local result = "" for spos=0,string.len(data)-1,3 do for byte=1,3 do bytes[byte] = string.byte(string.sub(data,(spos+byte))) or 0 end 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 "=") end return result end -- decryption table 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 } -- function decode -- decode base64 input to string function dec(data) local chars = {} local result="" for dpos=0,string.len(data)-1,4 do for char=1,4 do chars[char] = base64bytes[(string.sub(data,(dpos+char),(dpos+char)) or "=")] end 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 "" ) end return result end -- command line if not called as library if (arg ~= nil) then local func = 'enc' for n,v in ipairs(arg) do if (n > 0) then if (v == "-h") then print "base64.lua [-e] [-d] text/data" break elseif (v == "-e") then func = 'enc' elseif (v == "-d") then func = 'dec' else print(_G[func](v)) end end end else module('base64',package.seeall) end