Anavrins

MD5

Mar 22nd, 2016
113
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- MD5 hash function in ComputerCraft (Unsafe, for educational/legacy uses only)
  2. -- By Anavrins
  3. -- MIT License
  4. -- Pastebin: https://pastebin.com/6PVSRckQ
  5. -- Last updated: March 27 2020
  6.  
  7. local mod32 = 2^32
  8. local bor = bit32.bor
  9. local band = bit32.band
  10. local bnot = bit32.bnot
  11. local bxor = bit32.bxor
  12. local blshift = bit32.lshift
  13. local upack = unpack
  14.  
  15. local function lrotate(int, by)
  16.     local s = int/(2^(32-by))
  17.     local f = s%1
  18.     return (s-f)+f*mod32
  19. end
  20. local function brshift(int, by)
  21.     local s = int / (2^by)
  22.     return s-s%1
  23. end
  24.  
  25. local s = {
  26.      7, 12, 17, 22,
  27.      5,  9, 14, 20,
  28.      4, 11, 16, 23,
  29.      6, 10, 15, 21,
  30. }
  31.  
  32. local K = {
  33.     0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  34.     0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  35.     0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  36.     0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  37.     0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  38.     0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  39.     0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  40.     0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  41.     0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  42.     0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  43.     0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
  44.     0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  45.     0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  46.     0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  47.     0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  48.     0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  49. }
  50.  
  51. local H = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}
  52.  
  53. local function counter(incr)
  54.     local t1, t2 = 0, 0
  55.     if 0xFFFFFFFF - t1 < incr then
  56.         t2 = t2 + 1
  57.         t1 = incr - (0xFFFFFFFF - t1) - 1      
  58.     else t1 = t1 + incr
  59.     end
  60.     return t2, t1
  61. end
  62.  
  63. local function LE_toInt(bs, i)
  64.     return (bs[i] or 0) + blshift((bs[i+1] or 0), 8) + blshift((bs[i+2] or 0), 16) + blshift((bs[i+3] or 0), 24)
  65. end
  66.  
  67. local function preprocess(data)
  68.     local len = #data
  69.     local proc = {}
  70.     data[#data+1] = 0x80
  71.     while #data%64~=56 do data[#data+1] = 0 end
  72.     local blocks = math.ceil(#data/64)
  73.     for i = 1, blocks do
  74.         proc[i] = {}
  75.         for j = 1, 16 do
  76.             proc[i][j] = LE_toInt(data, 1+((i-1)*64)+((j-1)*4))
  77.         end
  78.     end
  79.     proc[blocks][16], proc[blocks][15] = counter(len*8)
  80.     return proc
  81. end
  82.  
  83. local function digestblock(m, C)
  84.     local a, b, c, d = upack(C)
  85.     for j = 0, 63 do
  86.         local f, g, r = 0, j, brshift(j, 4)
  87.         if r == 0 then
  88.             f = bor(band(b, c), band(bnot(b), d))
  89.         elseif r == 1 then
  90.             f = bor(band(d, b), band(bnot(d), c))
  91.             g = (5*j+1)%16
  92.         elseif r == 2 then
  93.             f = bxor(b, c, d)
  94.             g = (3*j+5)%16
  95.         elseif r == 3 then
  96.             f = bxor(c, bor(b, bnot(d)))
  97.             g = (7*j)%16
  98.         end
  99.         local dTemp = d
  100.         a, b, c, d = dTemp, (b+lrotate((a + f + K[j+1] + m[g+1])%mod32, s[bor(blshift(r, 2), band(j, 3))+1]))%mod32, b, c
  101.     end
  102.     C[1] = (C[1] + a)%mod32
  103.     C[2] = (C[2] + b)%mod32
  104.     C[3] = (C[3] + c)%mod32
  105.     C[4] = (C[4] + d)%mod32
  106.     return C
  107. end
  108.  
  109. local mt = {
  110.     __tostring = function(a) return string.char(unpack(a)) end,
  111.     __index = {
  112.         toHex = function(self, s) return ("%02x"):rep(#self):format(unpack(self)) end,
  113.         isEqual = function(self, t)
  114.             if type(t) ~= "table" then return false end
  115.             if #self ~= #t then return false end
  116.             local ret = 0
  117.             for i = 1, #self do
  118.                 ret = bor(ret, bxor(self[i], t[i]))
  119.             end
  120.             return ret == 0
  121.         end
  122.     }
  123. }
  124.  
  125. local function toBytes(t, n)
  126.     local b = {}
  127.     for i = 1, n do
  128.         b[(i-1)*4+1] = band(t[i], 0xFF)
  129.         b[(i-1)*4+2] = band(brshift(t[i], 8), 0xFF)
  130.         b[(i-1)*4+3] = band(brshift(t[i], 16), 0xFF)
  131.         b[(i-1)*4+4] = band(brshift(t[i], 24), 0xFF)
  132.     end
  133.     return setmetatable(b, mt)
  134. end
  135.  
  136. function digest(data)
  137.     data = data or ""
  138.     data = type(data) == "string" and {data:byte(1,-1)} or data
  139.  
  140.     data = preprocess(data)
  141.     local C = {upack(H)}
  142.     for i = 1, #data do C = digestblock(data[i], C) end
  143.     return toBytes(C, 4)
  144. end
  145.  
  146. return {
  147.     digest = digest,
  148. }
RAW Paste Data