Merge pull request #2 from Positive07/patch-1

Use BitOp or Bit32 libraries where available
This commit is contained in:
Enrique García 2015-02-09 11:13:46 +01:00
commit b56a8a1e93

289
md5.lua
View File

@ -33,166 +33,175 @@ local md5 = {
local floor, abs, max = math.floor, math.abs, math.max local floor, abs, max = math.floor, math.abs, math.max
local char, byte, format, rep, sub = local char, byte, format, rep, sub =
string.char, string.byte, string.format, string.rep, string.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 function check_int(n) local ok, bit = pcall(require, 'bit')
-- checking not float if not ok then ok, bit = pcall(require, 'bit32') end
if(n - floor(n) > 0) then
error("trying to use bitwise operation on non-integer!")
end
end
local function tbl2number(tbl) if ok then
local n = #tbl bit_or, bit_and, bit_not, bit_xor = bit.bor, bit.band, bit.bnot, bit.bxor
bit_rshift, bit_lshift = bit.rshift, bit.lshift
local rslt = 0 else
local power = 1 local function check_int(n)
for i = 1, n do -- checking not float
rslt = rslt + tbl[i]*power if(n - floor(n) > 0) then
power = power*2 error("trying to use bitwise operation on non-integer!")
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 -- needs to be declared before bit_not
local function bit_not(n)
local tbl = to_bits(n)
local size = max(#tbl, 32)
for i = 1, size do
if(tbl[i] == 1) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
-- defined as local above
to_bits = function (n)
check_int(n)
if(n < 0) then
-- negative
return to_bits(bit_not(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 = 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
end end
return tbl2number(tbl) local function tbl2number(tbl)
end local n = #tbl
local function bit_and(m, n) local rslt = 0
local tbl_m = to_bits(m) local power = 1
local tbl_n = to_bits(n) for i = 1, n do
expand(tbl_m, tbl_n) rslt = rslt + tbl[i]*power
power = power*2
local tbl = {}
local rslt = 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 rslt
end end
return tbl2number(tbl) local function expand(tbl_m, tbl_n)
end local big = {}
local small = {}
local function bit_xor(m, n) if(#tbl_m > #tbl_n) then
local tbl_m = to_bits(m) big = tbl_m
local tbl_n = to_bits(n) small = tbl_n
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i] ~= tbl_n[i]) then
tbl[i] = 1
else else
tbl[i] = 0 big = tbl_n
small = tbl_m
end end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end end
return tbl2number(tbl) local to_bits -- needs to be declared before bit_not
end
local function bit_rshift(n, bits) function bit_not(n)
check_int(n) local tbl = to_bits(n)
local size = max(#tbl, 32)
local high_bit = 0 for i = 1, size do
if(n < 0) then if(tbl[i] == 1) then
-- negative tbl[i] = 0
n = bit_not(abs(n)) + 1 else
high_bit = 2147483648 -- 0x80000000 tbl[i] = 1
end
end
return tbl2number(tbl)
end end
for i=1, bits do -- defined as local above
n = n/2 to_bits = function (n)
n = bit_or(floor(n), high_bit) check_int(n)
end if(n < 0) then
return floor(n) -- negative
end return to_bits(bit_not(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
local function bit_lshift(n, bits) return tbl
check_int(n)
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
end end
for i=1, bits do function bit_or(m, n)
n = n*2 local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = 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 tbl2number(tbl)
end
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 = 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 tbl2number(tbl)
end
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 = 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
return tbl2number(tbl)
end
function bit_rshift(n, bits)
check_int(n)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
high_bit = 2147483648 -- 0x80000000
end
for i=1, bits do
n = n/2
n = bit_or(floor(n), high_bit)
end
return floor(n)
end
function bit_lshift(n, bits)
check_int(n)
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 4294967295) -- 0xFFFFFFFF
end end
return bit_and(n, 4294967295) -- 0xFFFFFFFF
end end
-- convert little-endian 32-bit int to a 4-char string -- convert little-endian 32-bit int to a 4-char string