jerome@65: local M, plat, bin = {}, require("casc.platform"), require("casc.bin") jerome@65: jerome@65: local rot, xor, uint32_le, to_le32 = plat.rol, plat.bxor, bin.uint32_le, bin.to_le32 jerome@65: jerome@65: function M.hash(k) jerome@65: assert(type(k) == "string", 'Syntax: casc.jenkins96.hash("key")') jerome@65: jerome@65: if #k == 0 then return 0xdeadbeef, 0xdeadbeef end jerome@65: local a = 0xdeadbeef + #k jerome@65: local b, c, k = a, a, k .. (k ~= "" and ("\0"):rep((12 - #k % 12) % 12) or "") jerome@65: for i=0, #k-13, 12 do jerome@65: a, b, c = a + uint32_le(k, i), b + uint32_le(k, i+4), c + uint32_le(k, i+8) jerome@65: a = xor(a-c, rot(c, 4)); c = c + b jerome@65: b = xor(b-a, rot(a, 6)); a = a + c jerome@65: c = xor(c-b, rot(b, 8)); b = b + a jerome@65: a = xor(a-c, rot(c,16)); c = c + b jerome@65: b = xor(b-a, rot(a,19)); a = a + c jerome@65: c = xor(c-b, rot(b, 4)); b = b + a jerome@65: end jerome@65: local i = #k - 12 jerome@65: a, b, c = a + uint32_le(k, i), b + uint32_le(k, i+4), c + uint32_le(k, i+8) jerome@65: c = xor(c, b) - rot(b,14) jerome@65: a = xor(a, c) - rot(c,11) jerome@65: b = xor(b, a) - rot(a,25) jerome@65: c = xor(c, b) - rot(b,16) jerome@65: a = xor(a, c) - rot(c,04) jerome@65: b = xor(b, a) - rot(a,14) jerome@65: c = xor(c, b) - rot(b,24) jerome@65: return c, b jerome@65: end jerome@65: jerome@65: function M.hash_path(path) jerome@65: assert(type(path) == "string", 'Syntax: casc.jenkins96.hash_path("path")') jerome@65: local c, b = M.hash((path:upper():gsub('/', '\\'))) jerome@65: return to_le32(b) .. to_le32(c) jerome@65: end jerome@65: jerome@65: return M