# Array sum helper function. sum = (array) -> array.reduce (x, y) -> x + y md5 = do -> # Per-round shift amounts. s = [738695, 669989, 770404, 703814] s = (s[i >> 4] >> i % 4 * 5 & 31 for i in [0..63]) # Constants cache generated by sine. K = (Math.floor 2**32 * Math.abs Math.sin i for i in [1..64]) # Bitwise left rotate helper function. lrot = (x, y) -> x << y | x >>> 32 - y; (input) -> # Initialize values. d0 = 0x10325476; a0 = 0x67452301; b0 = ~d0 c0 = ~a0; # Convert the message to 32-bit words, little-endian. M = for i in [0...input.length] by 4 sum (input.charCodeAt(i + j) << j*8 for j in [0..3]) # Pre-processing: append a 1 bit, then message length % 2^64. len = input.length * 8 M[len >> 5] |= 128 << len % 32 M[(len + 64 >>> 9 << 4) + 14] = len # Process the message in chunks of 16 32-bit words. for x in [0...M.length] by 16 [A, B, C, D] = [a0, b0, c0, d0] # Main loop. for i in [0..63] if i < 16 F = B & C | ~B & D g = i else if i < 32 F = B & D | C & ~D g = i * 5 + 1 else if i < 48 F = B ^ C ^ D g = i * 3 + 5 else F = C ^ (B | ~D) g = i * 7 [A, B, C, D] = [D, B + lrot(A + F + K[i] + (M[x + g % 16] ? 0), s[i]), B, C] a0 += A b0 += B c0 += C d0 += D # Convert the four words back to a string. return ( for x in [a0, b0, c0, d0] (String.fromCharCode x >>> 8 * y & 255 for y in [0..3]).join '' ).join ''