do not normalize luajit functions

This commit is contained in:
kikito 2015-04-06 20:44:11 +02:00
parent 686c18c49e
commit 9fcb45d9f2
1 changed files with 146 additions and 142 deletions

288
md5.lua
View File

@ -35,177 +35,181 @@ local char, byte, format, rep, sub =
local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift
local ok, bit = pcall(require, 'bit') local ok, bit = pcall(require, 'bit')
if not ok then ok, bit = pcall(require, 'bit32') end
if ok then if ok then
bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift = bit.bor, bit.band, bit.bnot, bit.xor, bit.rshift, bit.lshift
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 else
ok, bit = pcall(require, 'bit32')
local function tbl2number(tbl) if ok then
local result = 0
local power = 1 bit_not = bit.bnot
for i = 1, #tbl do
result = result + tbl[i] * power local tobit = function(n)
power = power * 2 return n <= 0x7fffffff and n or -(bit_not(n) + 1)
end end
return result
end
local function expand(t1, t2) local normalize = function(f)
local big, small = t1, t2 return function(a,b) return tobit(f(tobit(a), tobit(b))) end
if(#big < #small) then
big, small = small, big
end end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end
local to_bits -- needs to be declared before bit_not 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)
bit_not = function(n) else
local tbl = to_bits(n)
local size = math.max(#tbl, 32) local function tbl2number(tbl)
for i = 1, size do local result = 0
if(tbl[i] == 1) then local power = 1
tbl[i] = 0 for i = 1, #tbl do
else result = result + tbl[i] * power
tbl[i] = 1 power = power * 2
end end
end return result
return tbl2number(tbl)
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 end
return tbl local function expand(t1, t2)
end local big, small = t1, t2
if(#big < #small) then
bit_or = function(m, n) big, small = small, big
local tbl_m = to_bits(m) end
local tbl_n = to_bits(n) -- expand small
expand(tbl_m, tbl_n) for i = #small + 1, #big do
small[i] = 0
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
end end
return tbl2number(tbl) local to_bits -- needs to be declared before bit_not
end
bit_and = function(m, n) bit_not = function(n)
local tbl_m = to_bits(m) local tbl = to_bits(n)
local tbl_n = to_bits(n) local size = math.max(#tbl, 32)
expand(tbl_m, tbl_n) for i = 1, size do
if(tbl[i] == 1) then
local tbl = {} tbl[i] = 0
for i = 1, #tbl_m do else
if(tbl_m[i]== 0 or tbl_n[i] == 0) then tbl[i] = 1
tbl[i] = 0 end
else
tbl[i] = 1
end end
return tbl2number(tbl)
end end
return tbl2number(tbl) -- defined as local above
end to_bits = function (n)
if(n < 0) then
bit_xor = function(m, n) -- negative
local tbl_m = to_bits(m) return to_bits(bit_not(math.abs(n)) + 1)
local tbl_n = to_bits(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
-- 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 end
return tbl2number(tbl) bit_or = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(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 tbl2number(tbl)
end
bit_and = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(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 tbl2number(tbl)
end
bit_xor = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(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 tbl2number(tbl)
end
bit_rshift = function(n, bits)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
high_bit = 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
-- negative
n = bit_not(math.abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 0xFFFFFFFF)
end
end end
bit_rshift = function(n, bits) -- convert little-endian 32-bit int to a 4-char string
local high_bit = 0 local function lei2str(i)
if(n < 0) then local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
-- negative return f(0)..f(8)..f(16)..f(24)
n = bit_not(math.abs(n)) + 1
high_bit = 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 end
bit_lshift = function(n, bits) -- convert raw string to big-endian int
if(n < 0) then local function str2bei(s)
-- negative local v=0
n = bit_not(math.abs(n)) + 1 for i=1, #s do
v = v * 256 + byte(s, i)
end end
return v
for i=1, bits do
n = n*2
end
return bit_and(n, 0xFFFFFFFF)
end end
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 -- convert raw string to little-endian int
local function str2lei(s) local function str2lei(s)
local v=0 local v=0