Hash md5的纯Lua实现

Hash md5的纯Lua实现,hash,lua,md5,Hash,Lua,Md5,是否有md5哈希算法的纯lua实现?一个不依赖任何c或外部库的库?有一些javascript实现不依赖于c或任何东西,因此使用lua应该是可能的。 谢谢 有一个旧的,但它需要bitlib。但它仍然需要一个lib。我结合了前面提到的需要bitlib的lua MD5库,并添加到LuaBit中,使其成为一个纯lua实现 另外一个好处是,它的结构可以在redis lua脚本环境中工作 请注意,与其他非纯基于lua的实现相比,它的速度非常慢 --[[--------------- LuaBit v0.4

是否有md5哈希算法的纯lua实现?一个不依赖任何c或外部库的库?有一些javascript实现不依赖于c或任何东西,因此使用lua应该是可能的。
谢谢

有一个旧的,但它需要bitlib。

但它仍然需要一个lib。

我结合了前面提到的需要bitlib的lua MD5库,并添加到LuaBit中,使其成为一个纯lua实现

另外一个好处是,它的结构可以在redis lua脚本环境中工作

请注意,与其他非纯基于lua的实现相比,它的速度非常慢

--[[---------------
LuaBit v0.4
-------------------
a bitwise operation lib for lua.

http://luaforge.net/projects/bit/

How to use:
-------------------
 bit.bnot(n) -- bitwise not (~n)
 bit.band(m, n) -- bitwise and (m & n)
 bit.bor(m, n) -- bitwise or (m | n)
 bit.bxor(m, n) -- bitwise xor (m ^ n)
 bit.brshift(n, bits) -- right shift (n >> bits)
 bit.blshift(n, bits) -- left shift (n << bits)
 bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>)

Please note that bit.brshift and bit.blshift only support number within
32 bits.

2 utility functions are provided too:
 bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence)
               -- high bits first
 bit.tonumb(bit_tbl) -- convert a bit table into a number 
-------------------

Under the MIT license.

copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
--]]---------------

--do

------------------------
-- bit lib implementions

local function check_int(n)
 -- checking not float
 if(n - math.floor(n) > 0) then
  error("trying to use bitwise operation on non-integer!")
 end
end

local function tbl_to_number(tbl)
 local n = #tbl

 local rslt = 0
 local power = 1
 for i = 1, n do
  rslt = rslt + tbl[i]*power
  power = power*2
 end

 return rslt
end

local function expand(tbl_m, tbl_n)
 local big = {}
 local small = {}
 if(#tbl_m > #tbl_n) then
  big = tbl_m
  small = tbl_n
 else
  big = tbl_n
  small = tbl_m
 end
 -- expand small
 for i = #small + 1, #big do
  small[i] = 0
 end

end

local to_bits = function () end

local function bit_not(n)
 local tbl = to_bits(n)
 local size = math.max(#tbl, 32)
 for i = 1, size do
  if(tbl[i] == 1) then
   tbl[i] = 0
  else
   tbl[i] = 1
  end
 end
 return tbl_to_number(tbl)
end


to_bits = function (n)
 check_int(n)
 if(n < 0) then
  -- negative
  return to_bits(bit_not(math.abs(n)) + 1)
 end
 -- to bits table
 local tbl = {}
 local cnt = 1
 while (n > 0) do
  local last = math.mod(n,2)
  if(last == 1) then
   tbl[cnt] = 1
  else
   tbl[cnt] = 0
  end
  n = (n-last)/2
  cnt = cnt + 1
 end

 return tbl
end


local function bit_or(m, n)
 local tbl_m = to_bits(m)
 local tbl_n = to_bits(n)
 expand(tbl_m, tbl_n)

 local tbl = {}
 local rslt = math.max(#tbl_m, #tbl_n)
 for i = 1, rslt do
  if(tbl_m[i]== 0 and tbl_n[i] == 0) then
   tbl[i] = 0
  else
   tbl[i] = 1
  end
 end

 return tbl_to_number(tbl)
end

local function bit_and(m, n)
 local tbl_m = to_bits(m)
 local tbl_n = to_bits(n)
 expand(tbl_m, tbl_n) 

 local tbl = {}
 local rslt = math.max(#tbl_m, #tbl_n)
 for i = 1, rslt do
  if(tbl_m[i]== 0 or tbl_n[i] == 0) then
   tbl[i] = 0
  else
   tbl[i] = 1
  end
 end

 return tbl_to_number(tbl)
end

local function bit_xor(m, n)
 local tbl_m = to_bits(m)
 local tbl_n = to_bits(n)
 expand(tbl_m, tbl_n) 

 local tbl = {}
 local rslt = math.max(#tbl_m, #tbl_n)
 for i = 1, rslt do
  if(tbl_m[i] ~= tbl_n[i]) then
   tbl[i] = 1
  else
   tbl[i] = 0
  end
 end

 --table.foreach(tbl, print)

 return tbl_to_number(tbl)
end

local function bit_rshift(n, bits)
 check_int(n)

 local high_bit = 0
 if(n < 0) then
  -- negative
  n = bit_not(math.abs(n)) + 1
  high_bit = 2147483648 -- 0x80000000
 end

 for i=1, bits do
  n = n/2
  n = bit_or(math.floor(n), high_bit)
 end
 return math.floor(n)
end

-- logic rightshift assures zero filling shift
local function bit_logic_rshift(n, bits)
 check_int(n)
 if(n < 0) then
  -- negative
  n = bit_not(math.abs(n)) + 1
 end
 for i=1, bits do
  n = n/2
 end
 return math.floor(n)
end

local function bit_lshift(n, bits)
 check_int(n)

 if(n < 0) then
  -- negative
  n = bit_not(math.abs(n)) + 1
 end

 for i=1, bits do
  n = n*2
 end
 return bit_and(n, 4294967295) -- 0xFFFFFFFF
end

local function bit_xor2(m, n)
 local rhs = bit_or(bit_not(m), bit_not(n))
 local lhs = bit_or(m, n)
 local rslt = bit_and(lhs, rhs)
 return rslt
end

-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
-- 10/02/2001 jcw@equi4.com

local md5={ff=tonumber('ffffffff',16),consts={}}

string.gsub([[ d76aa478 e8c7b756 242070db c1bdceee
    f57c0faf 4787c62a a8304613 fd469501
    698098d8 8b44f7af ffff5bb1 895cd7be
    6b901122 fd987193 a679438e 49b40821
    f61e2562 c040b340 265e5a51 e9b6c7aa
    d62f105d 02441453 d8a1e681 e7d3fbc8
    21e1cde6 c33707d6 f4d50d87 455a14ed
    a9e3e905 fcefa3f8 676f02d9 8d2a4c8a
    fffa3942 8771f681 6d9d6122 fde5380c
    a4beea44 4bdecfa9 f6bb4b60 bebfbc70
    289b7ec6 eaa127fa d4ef3085 04881d05
    d9d4d039 e6db99e5 1fa27cf8 c4ac5665
    f4292244 432aff97 ab9423a7 fc93a039
    655b59c3 8f0ccc92 ffeff47d 85845dd1
    6fa87e4f fe2ce6e0 a3014314 4e0811a1
    f7537e82 bd3af235 2ad7d2bb eb86d391
    67452301 efcdab89 98badcfe 10325476 ]],"(%w+)", function (s) table.insert(md5.consts, tonumber(s,16)) end)
    --67452301 efcdab89 98badcfe 10325476 ]],"(%w+)", function (s) tinsert(md5.consts,tonumber(s,16)) end)

function md5.transform(A,B,C,D,X)
  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,md5.ff)
        -- be *very* careful that left shift does not cause rounding!
        return bit_or(bit_lshift(bit_and(a,bit_rshift(md5.ff,s)),s),bit_rshift(a,32-s))+b
      end
  local a,b,c,d=A,B,C,D
  local t=md5.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

-- convert little-endian 32-bit int to a 4-char string
local function leIstr(i)
  local f=function (s) return string.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 beInt(s)
    local v=0
    for i=1,string.len(s) do v=v*256+string.byte(s,i) end
    return v
  end
  -- convert raw string to little-endian int
  local function leInt(s)
    local v=0
    for i=string.len(s),1,-1 do v=v*256+string.byte(s,i) end
    return v
  end
  -- cut up a string in little-endian ints of given size
  local function leStrCuts(s,...)
    local o,r=1,{}
    for i=1,#arg do
      table.insert(r,leInt(string.sub(s,o,o+arg[i]-1)))
      o=o+arg[i]
    end
    return r
  end

function md5.Calc(s)
  local msgLen=string.len(s)
  local padLen=56- msgLen % 64
  if msgLen % 64 > 56 then padLen=padLen+64 end
  if padLen==0 then padLen=64 end
  s=s..string.char(128)..string.rep(string.char(0),padLen-1)
  s=s..leIstr(8*msgLen)..leIstr(0)
  assert(string.len(s) % 64 ==0)
  local t=md5.consts
  local a,b,c,d=t[65],t[66],t[67],t[68]
  for i=1,string.len(s),64 do
    local X=leStrCuts(string.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=md5.transform(a,b,c,d,X)
  end
  local swap=function (w) return beInt(leIstr(w)) end
  return string.format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d))
end

return md5.Calc("asdf"); -- 912ec803b2ce49e4a541068d495ab570
--[[---------------
LuaBit v0.4
-------------------
lua的按位操作库。
http://luaforge.net/projects/bit/
如何使用:
-------------------
bit.bnot(n)--按位not(~n)
位带(m,n)——按位and(m&n)
bit.bor(m,n)——按位or(m | n)
位bxor(m,n)——按位异或(m^n)
bit.brshift(n,位)--右移位(n>>位)
blshift位(n,位)--左移位(n>>)
请注意,bit.brshift和bit.blshift仅支持
32位。
还提供了2个实用功能:
tobits(n)--将n转换为位表(1/0序列)
--高位优先
bit.tonumb(bit_tbl)——将位表转换为数字
-------------------
根据麻省理工学院的许可证。
版权所有(c)2006~2007韩照(abrash)_han@hotmail.com)
--]]---------------
--做
------------------------
--位库实现
局部函数检查(n)
--检查不浮动
如果(n-数学楼层(n)>0),则
错误(“尝试对非整数使用位运算!”)
结束
结束
本地功能tbl_至_编号(tbl)
本地n=#待定
本地rslt=0
本地功率=1
对于i=1,n do
rslt=rslt+tbl[i]*功率
功率=功率*2
结束
返回rslt
结束
本地功能扩展(待定,待定)
本地大={}
局部小={}
如果(#tbl_m>#tbl_n)那么
大=待定
小=待定
其他的
大=待定
小=待定
结束
--小张
对于i=#小+1,#大做
小[i]=0
结束
结束
本地到_位=函数()结束
本地功能位\u非(n)
本地tbl=至_位(n)
本地大小=数学最大值(待定,32)
对于i=1,大小为
如果(tbl[i]==1),则
tbl[i]=0
其他的
tbl[i]=1
结束
结束
将tbl_返回到_编号(tbl)
结束
to_位=函数(n)
校验输入(n)
如果(n<0),则
--否定的
返回到_位(位_非(math.abs(n))+1)
结束
--到比特表
本地tbl={}
局部cnt=1
而(n>0)呢
本地last=math.mod(n,2)
如果(last==1),则
tbl[cnt]=1
其他的
tbl[cnt]=0
结束
n=(n-last)/2
cnt=cnt+1
结束
返回tbl
结束
本地功能位_或(m,n)
本地tbl_m=到位(m)
本地tbl\u n=到\u位(n)
扩展(待定,待定)
本地tbl={}
本地rslt=math.max(#tbl_m,#tbl_n)
对于i=1,rslt do
如果(tbl_m[i]==0和tbl_n[i]==0),那么
tbl[i]=0
其他的
tbl[i]=1
结束
结束
将tbl_返回到_编号(tbl)
结束
本地功能位_和(m,n)
本地tbl_m=到位(m)
本地tbl\u n=到\u位(n)
扩展(待定,待定)
本地tbl={}
本地rslt=math.max(#tbl_m,#tbl_n)
对于i=1,rslt do
如果(tbl_m[i]==0或tbl_n[i]==0),则
tbl[i]=0
其他的
tbl[i]=1
结束
结束
将tbl_返回到_编号(tbl)
结束
局部函数位异或(m,n)
本地tbl_m=到位(m)
本地tbl\u n=到\u位(n)
扩展(待定,待定)
本地tbl={}
本地rslt=math.max(#tbl_m,#tbl_n)
对于i=1,rslt do
如果(tbl_m[i]~=tbl_n[i]),那么
tbl[i]=1
其他的
tbl[i]=0
结束
结束
--表.foreach(待定,打印)
将tbl_返回到_编号(tbl)
结束
本地功能位移位(n位)
校验输入(n)
本地高\u位=0
如果(n<0),则
--否定的
n=位_非(数学abs(n))+1
高位=2147483648--0x8000000
结束
对于i=1,位可以
n=n/2
n=位或(数学地板(n),高位)
结束
返回数学楼层(n)
结束
--逻辑右移确保零填充移位
本地功能位逻辑移位(n位)
校验输入(n)
如果(n<0),则
--否定的
n=位_非(数学abs(n))+1
结束
对于i=1,位可以
n=n/2
结束
返回数学楼层(n)
结束
本地功能位移位(n,位)
校验输入(n)
如果(n<0),则
--否定的
n=位_非(数学abs(n))+1
结束
对于i=1,位可以
n=n*2
结束
返回位_和(n,4294967295)——0xFFFFFFFF
结束
局部函数位xor2(m,n)
本地rhs=位或(位不(m),位不(n))
本地lhs=位_或(m,n)
本地rslt=位_和(左、右)
返回rslt
结束
--Lua中的MD5实现需要bitlib(黑客从上面攻击使用LuaBit,呃)
-- 10/02/2001 jcw@equi4.com
本地md5={ff=tonumber('ffffffff',16),consts={}
string.gsub([[d76aa478 e8c7b756 242070db c1bdceee
f57c0faf 4787c62a a8304613 fd469501
698098d8 8b44f7af FF5BB1 895cd7be
6b901122 fd987193 a679438e 49b40821
f61e2562 c040b340 265e5a51 e9b6c7aa
d62f105d 02441453 d8a1e681 e7d3fbc8
21e1cde6 c33707d6 f4d50d87 455a14ed
a9e3e905 fcefa3f8 676f02d9 8d2a4c8a
fffa3942 8771f681 6d9d6122 fde5380c
a4beea44 4bdecfa9 f6bb4b60 bebfbc70
289b7ec6 eaa127fa d4ef3085 04881d05
d9d4d039 e6db99e5 1fa27cf8 c4ac5665
f4292244 432AF97 ab9423a7 fc93a039
655b59c3 8f0ccc92 FFEF47D 85845dd1
6fa87e4f fe2ce6e0 A301431A4 E0811A1
f7537e82 bd3af235 2ad7d2bb eb86d391
67452301 efcdab89 98badcfe 10325476],“(%w+”,函数表。插入(md5.consts,tonumber(s,16))结束)
--67452301 efcdab89 98badcfe 10325476],“(%w+”,函数tinsert(md5.consts,tonumber(s,16))结束)
函数md5.变换(A、B、C、D、X)
局部f=函数(x,y,z)返回位_或(位_和(x,y),位_和(-x-1,z))结束
局部g=函数(x,y,z)返回位_或(位_和(x,z),位_和(y,-z-1))结束
局部h=函数(x,y,z)返回位xor(x,位xor(y,z))结束
局部i=函数(x,y,z)返回位xor(y,位或(x,-z-1))结束
局部z=函数(f、a、b、c、d、x、s、ac)
a=位_和(a+f(b,c,d)+x+ac,md5.ff)
--小心左移不会导致四舍五入!
返回位或(位移位(位和(a,位移位(md5.ff,s)),