local md5 = { _VERSION = "md5.lua 1.0.0", _DESCRIPTION = "MD5 computation in Lua (5.1-3, LuaJIT)", _URL = "https://github.com/kikito/md5.lua", _LICENSE = [[ MIT LICENSE Copyright (c) 2013 Enrique GarcĂ­a Cota + Adam Baldwin + hanzao + Equi 4 Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] } -- bit lib implementions local char, byte, format, rep, sub = string.char, string.byte, string.format, string.rep, string.sub local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift local ok, bit = pcall(require, 'bit') if not ok then ok, bit = pcall(require, 'bit32') end if ok then bit_not = bit.bnot local tobit = function(n) return n <= 0x7fffffff and n or -(bit_not(n) + 1) end local normalize = function(f) return function(a,b) return tobit(f(tobit(a), tobit(b))) end end bit_or, bit_and, bit_xor = normalize(bit.bor), normalize(bit.band), normalize(bit.bxor) bit_rshift, bit_lshift = normalize(bit.rshift), normalize(bit.lshift) else local function tbl2number(tbl) local result = 0 local power = 1 for i = 1, #tbl do result = result + tbl[i] * power power = power * 2 end return result end local function expand(t1, t2) local big, small = t1, t2 if(#big < #small) then big, small = small, big end -- expand small for i = #small + 1, #big do small[i] = 0 end end local bits_not, bits_or, bits_and, bits_not, bits_xor local to_bits -- needs to be declared before bit_not bits_not = function(tbl) for i=1, math.max(#tbl, 32) do if tbl[i] == 1 then tbl[i] = 0 else tbl[i] = 1 end end return tbl end bit_not = function(n) return tbl2number(bits_not(to_bits(n))) end -- defined as local above to_bits = function (n) if n < 0 then -- negative return to_bits(bit_not(math.abs(n)) + 1) end -- to bits table local tbl = {} local cnt = 1 local last while n > 0 do last = n % 2 tbl[cnt] = last n = (n-last)/2 cnt = cnt + 1 end return tbl end bits_or = function(tbl_m, tbl_n) expand(tbl_m, tbl_n) local tbl = {} for i = 1, #tbl_m do if(tbl_m[i] == 0 and tbl_n[i] == 0) then tbl[i] = 0 else tbl[i] = 1 end end return tbl end bit_or = function(m, n) return tbl2number(bits_or(tobits(m), tobits(n))) end bits_and = function(tbl_m, tbl_n) expand(tbl_m, tbl_n) local tbl = {} for i = 1, #tbl_m do if tbl_m[i] == 0 or tbl_n[i] == 0 then tbl[i] = 0 else tbl[i] = 1 end end return tbl end bit_and = function(m, n) return tbl2number(bits_and(tobits(m), tobits(n))) end bits_xor = function(tbl_m, tbl_n) expand(tbl_m, tbl_n) local tbl = {} for i = 1, #tbl_m do if tbl_m[i] ~= tbl_n[i] then tbl[i] = 1 else tbl[i] = 0 end end return tbl end bit_xor = function(m, n) return tbl2number(bits_xor(tobits(m), tobits(n))) end bit_rshift = function(n, bits) local high_bit = 0 if n < 0 then n = bit_not(math.abs(n)) + 1 high_bit = 2147483648 -- 0x80000000 end local floor = math.floor for i=1, bits do n = n/2 n = bit_or(floor(n), high_bit) end return floor(n) end bit_lshift = function(n, bits) if n < 0 then n = bit_not(math.abs(n)) + 1 end for i=1, bits do n = n*2 end return bit_and(n, 4294967295) -- 0xFFFFFFFF end end -- convert little-endian 32-bit int to a 4-char string local function lei2str(i) local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end return f(0)..f(8)..f(16)..f(24) end -- convert raw string to big-endian int local function str2bei(s) local v=0 for i=1, #s do v = v * 256 + byte(s, i) end return v end -- convert raw string to little-endian int local function str2lei(s) local v=0 for i = #s,1,-1 do v = v*256 + byte(s, i) end return v end -- cut up a string in little-endian ints of given size local function cut_le_str(s,...) local o, r = 1, {} local args = {...} for i=1, #args do table.insert(r, str2lei(sub(s, o, o + args[i] - 1))) o = o + args[i] end return r end local swap = function (w) return str2bei(lei2str(w)) end local function hex2binaryaux(hexval) return char(tonumber(hexval, 16)) end local function hex2binary(hex) local result, _ = hex:gsub('..', hex2binaryaux) return result end -- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh) -- 10/02/2001 jcw@equi4.com local FF = 0xffffffff local CONSTS = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 } local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end local z=function (f,a,b,c,d,x,s,ac) a=bit_and(a+f(b,c,d)+x+ac,FF) -- be *very* careful that left shift does not cause rounding! return bit_or(bit_lshift(bit_and(a,bit_rshift(FF,s)),s),bit_rshift(a,32-s))+b end local function transform(A,B,C,D,X) local a,b,c,d=A,B,C,D local t=CONSTS a=z(f,a,b,c,d,X[ 0], 7,t[ 1]) d=z(f,d,a,b,c,X[ 1],12,t[ 2]) c=z(f,c,d,a,b,X[ 2],17,t[ 3]) b=z(f,b,c,d,a,X[ 3],22,t[ 4]) a=z(f,a,b,c,d,X[ 4], 7,t[ 5]) d=z(f,d,a,b,c,X[ 5],12,t[ 6]) c=z(f,c,d,a,b,X[ 6],17,t[ 7]) b=z(f,b,c,d,a,X[ 7],22,t[ 8]) a=z(f,a,b,c,d,X[ 8], 7,t[ 9]) d=z(f,d,a,b,c,X[ 9],12,t[10]) c=z(f,c,d,a,b,X[10],17,t[11]) b=z(f,b,c,d,a,X[11],22,t[12]) a=z(f,a,b,c,d,X[12], 7,t[13]) d=z(f,d,a,b,c,X[13],12,t[14]) c=z(f,c,d,a,b,X[14],17,t[15]) b=z(f,b,c,d,a,X[15],22,t[16]) a=z(g,a,b,c,d,X[ 1], 5,t[17]) d=z(g,d,a,b,c,X[ 6], 9,t[18]) c=z(g,c,d,a,b,X[11],14,t[19]) b=z(g,b,c,d,a,X[ 0],20,t[20]) a=z(g,a,b,c,d,X[ 5], 5,t[21]) d=z(g,d,a,b,c,X[10], 9,t[22]) c=z(g,c,d,a,b,X[15],14,t[23]) b=z(g,b,c,d,a,X[ 4],20,t[24]) a=z(g,a,b,c,d,X[ 9], 5,t[25]) d=z(g,d,a,b,c,X[14], 9,t[26]) c=z(g,c,d,a,b,X[ 3],14,t[27]) b=z(g,b,c,d,a,X[ 8],20,t[28]) a=z(g,a,b,c,d,X[13], 5,t[29]) d=z(g,d,a,b,c,X[ 2], 9,t[30]) c=z(g,c,d,a,b,X[ 7],14,t[31]) b=z(g,b,c,d,a,X[12],20,t[32]) a=z(h,a,b,c,d,X[ 5], 4,t[33]) d=z(h,d,a,b,c,X[ 8],11,t[34]) c=z(h,c,d,a,b,X[11],16,t[35]) b=z(h,b,c,d,a,X[14],23,t[36]) a=z(h,a,b,c,d,X[ 1], 4,t[37]) d=z(h,d,a,b,c,X[ 4],11,t[38]) c=z(h,c,d,a,b,X[ 7],16,t[39]) b=z(h,b,c,d,a,X[10],23,t[40]) a=z(h,a,b,c,d,X[13], 4,t[41]) d=z(h,d,a,b,c,X[ 0],11,t[42]) c=z(h,c,d,a,b,X[ 3],16,t[43]) b=z(h,b,c,d,a,X[ 6],23,t[44]) a=z(h,a,b,c,d,X[ 9], 4,t[45]) d=z(h,d,a,b,c,X[12],11,t[46]) c=z(h,c,d,a,b,X[15],16,t[47]) b=z(h,b,c,d,a,X[ 2],23,t[48]) a=z(i,a,b,c,d,X[ 0], 6,t[49]) d=z(i,d,a,b,c,X[ 7],10,t[50]) c=z(i,c,d,a,b,X[14],15,t[51]) b=z(i,b,c,d,a,X[ 5],21,t[52]) a=z(i,a,b,c,d,X[12], 6,t[53]) d=z(i,d,a,b,c,X[ 3],10,t[54]) c=z(i,c,d,a,b,X[10],15,t[55]) b=z(i,b,c,d,a,X[ 1],21,t[56]) a=z(i,a,b,c,d,X[ 8], 6,t[57]) d=z(i,d,a,b,c,X[15],10,t[58]) c=z(i,c,d,a,b,X[ 6],15,t[59]) b=z(i,b,c,d,a,X[13],21,t[60]) a=z(i,a,b,c,d,X[ 4], 6,t[61]) d=z(i,d,a,b,c,X[11],10,t[62]) c=z(i,c,d,a,b,X[ 2],15,t[63]) b=z(i,b,c,d,a,X[ 9],21,t[64]) return A+a,B+b,C+c,D+d end ---------------------------------------------------------------- function md5.sumhexa(s) local msgLen = #s local padLen = 56 - msgLen % 64 if msgLen % 64 > 56 then padLen = padLen + 64 end if padLen == 0 then padLen = 64 end s = s .. char(128) .. rep(char(0),padLen-1) .. lei2str(8*msgLen) .. lei2str(0) assert(#s % 64 == 0) local t = CONSTS local a,b,c,d = t[65],t[66],t[67],t[68] for i=1,#s,64 do local X = cut_le_str(sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4) assert(#X == 16) X[0] = table.remove(X,1) -- zero based! a,b,c,d = transform(a,b,c,d,X) end return format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d)) end function md5.sum(s) return hex2binary(md5.sumhexa(s)) end return md5