From 51febea6c3b617ff80f8bbd4530cfc1998a50dbb Mon Sep 17 00:00:00 2001 From: Pedro Gimeno Date: Sat, 2 Jul 2016 17:31:10 +0200 Subject: [PATCH 1/3] Implement incremental MD5 Two new functions: md5.new(): returns a new MD5 state object with two methods: - MD5State:update(s) - adds the string s to the calculation - MD5State:finish() - returns the final MD5 as a binary string md5.tohex(): converts to hexadecimal the binary string returned by md5.sum() and MD5State:finish() --- md5.lua | 59 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/md5.lua b/md5.lua index 68de32a..4828b53 100644 --- a/md5.lua +++ b/md5.lua @@ -232,15 +232,6 @@ 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 @@ -352,33 +343,53 @@ end ---------------------------------------------------------------- -function md5.sumhexa(s) - local msgLen = #s +local function md5_update(self, s) + self.pos = self.pos + #s + s = self.buf .. s + for ii = 1, #s - 63, 64 do + local X = cut_le_str(sub(s,ii,ii+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! + self.a,self.b,self.c,self.d = transform(self.a,self.b,self.c,self.d,X) + end + self.buf = sub(s, math.floor(#s/64)*64 + 1, #s) +end + +local function md5_finish(self) + local msgLen = self.pos 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) + local s = char(128) .. rep(char(0),padLen-1) .. lei2str(bit_and(8*msgLen, 0xFFFFFFFF)) .. lei2str(math.floor(msgLen/0x20000000)) + md5_update(self, s) - assert(#s % 64 == 0) + assert(self.pos % 64 == 0) + return lei2str(self.a) .. lei2str(self.b) .. lei2str(self.c) .. lei2str(self.d) +end - local t = CONSTS - local a,b,c,d = t[65],t[66],t[67],t[68] +function md5.new() + return { a = CONSTS[65], b = CONSTS[66], c = CONSTS[67], d = CONSTS[68], + pos = 0, + buf = '', + update = md5_update, + finish = md5_finish } +end - for ii=1,#s,64 do - local X = cut_le_str(sub(s,ii,ii+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)) +function md5.tohex(s) + return format("%08x%08x%08x%08x", str2bei(sub(s, 1, 4)), str2bei(sub(s, 5, 8)), str2bei(sub(s, 9, 12)), str2bei(sub(s, 13, 16))) end function md5.sum(s) - return hex2binary(md5.sumhexa(s)) + local state = md5.new() + state:update(s) + return state:finish() +end + +function md5.sumhexa(s) + return md5.tohex(md5.sum(s)) end return md5 From 46b50003f811a70fea82997dd1aa25675225cf47 Mon Sep 17 00:00:00 2001 From: Pedro Gimeno Date: Sat, 2 Jul 2016 17:49:35 +0200 Subject: [PATCH 2/3] Add a simple unit test for the incremental version --- spec/md5_spec.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/md5_spec.lua b/spec/md5_spec.lua index 8425c95..69dde39 100644 --- a/spec/md5_spec.lua +++ b/spec/md5_spec.lua @@ -16,6 +16,10 @@ describe('md5', function() assert.equal(md5.sumhexa(''), 'd41d8cd98f00b204e9800998ecf8427e') assert.equal(md5.sumhexa(('1'):rep(824)), 'a126fd3611ab8d9b7e8a3384e2fa78a0') assert.equal(md5.sumhexa(('1'):rep(1528)), '3750b6a29d923b633e05d6ae76895664') + local state = md5.new() + state:update('Hello') + state:update(', World!') + assert.equal(md5.tohex(state:finish()), '65a8e27d8879283831b664bd8b7f0ad4') end) end) @@ -27,6 +31,10 @@ describe('md5', function() assert.equal(md5.sum(''), hex2bin 'd41d8cd98f00b204e9800998ecf8427e') assert.equal(md5.sum(('1'):rep(824)), hex2bin 'a126fd3611ab8d9b7e8a3384e2fa78a0') assert.equal(md5.sum(('1'):rep(1528)), hex2bin '3750b6a29d923b633e05d6ae76895664') + local state = md5.new() + state:update('Hello') + state:update(', World!') + assert.equal(state:finish(), hex2bin '65a8e27d8879283831b664bd8b7f0ad4') end) end) end) From 86da43dbda40354830d629168c24aade004af2a9 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 15 Jul 2016 01:16:54 +0200 Subject: [PATCH 3/3] makes update return self --- md5.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/md5.lua b/md5.lua index 4828b53..93ae756 100644 --- a/md5.lua +++ b/md5.lua @@ -353,6 +353,7 @@ local function md5_update(self, s) self.a,self.b,self.c,self.d = transform(self.a,self.b,self.c,self.d,X) end self.buf = sub(s, math.floor(#s/64)*64 + 1, #s) + return self end local function md5_finish(self) @@ -370,6 +371,8 @@ local function md5_finish(self) return lei2str(self.a) .. lei2str(self.b) .. lei2str(self.c) .. lei2str(self.d) end +---------------------------------------------------------------- + function md5.new() return { a = CONSTS[65], b = CONSTS[66], c = CONSTS[67], d = CONSTS[68], pos = 0, @@ -383,9 +386,7 @@ function md5.tohex(s) end function md5.sum(s) - local state = md5.new() - state:update(s) - return state:finish() + return md5.new():update(s):finish() end function md5.sumhexa(s)