Last active
January 26, 2022 01:51
-
-
Save ynkdir/4474930 to your computer and use it in GitHub Desktop.
hash function simple version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" md5: http://www.ietf.org/rfc/rfc1321.txt | |
function! Md5(data) | |
let data = (type(a:data) == type("") ? s:strtobytes(a:data) : a:data) | |
return s:md5(data) | |
endfunction | |
function! Md5Test() | |
let s = "" | |
let h = Md5(s) | |
if h ==? 'd41d8cd98f00b204e9800998ecf8427e' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "a" | |
let h = Md5(s) | |
if h ==? '0cc175b9c0f1b6a831c399e269772661' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abc" | |
let h = Md5(s) | |
if h ==? '900150983cd24fb0d6963f7d28e17f72' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "message digest" | |
let h = Md5(s) | |
if h ==? 'f96b697d7cb7938d525a2f31aaf161d0' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abcdefghijklmnopqrstuvwxyz" | |
let h = Md5(s) | |
if h ==? 'c3fcd3d76192e4007dfb496cca67e13b' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | |
let h = Md5(s) | |
if h ==? 'd174ab98d277d9f5a5611c2c9f419d9f' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "12345678901234567890123456789012345678901234567890123456789012345678901234567890" | |
let h = Md5(s) | |
if h ==? '57edf4a22be3c955ac49da2e2107b67a' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
endfunction | |
function! s:md5(bytes) | |
let m = a:bytes | |
let bitslen = len(m) * 8 | |
let m += [0x80] | |
let m += repeat([0], 64 - (len(m) + 8) % 64) | |
let m += s:uint64_to_bytes_le([bitslen, 0]) | |
let a = 0x67452301 | |
let b = 0xefcdab89 | |
let c = 0x98badcfe | |
let d = 0x10325476 | |
let x = repeat([0], 16) | |
for i in range(0, len(m) - 1, 64) | |
for t in range(0, 15) | |
let x[t] = s:bytes_to_uint32_le(m[i + t * 4 : i + t * 4 + 3]) | |
endfor | |
let aa = a | |
let bb = b | |
let cc = c | |
let dd = d | |
let a = s:FF(a, b, c, d, x[ 0], 7, 0xd76aa478) | |
let d = s:FF(d, a, b, c, x[ 1], 12, 0xe8c7b756) | |
let c = s:FF(c, d, a, b, x[ 2], 17, 0x242070db) | |
let b = s:FF(b, c, d, a, x[ 3], 22, 0xc1bdceee) | |
let a = s:FF(a, b, c, d, x[ 4], 7, 0xf57c0faf) | |
let d = s:FF(d, a, b, c, x[ 5], 12, 0x4787c62a) | |
let c = s:FF(c, d, a, b, x[ 6], 17, 0xa8304613) | |
let b = s:FF(b, c, d, a, x[ 7], 22, 0xfd469501) | |
let a = s:FF(a, b, c, d, x[ 8], 7, 0x698098d8) | |
let d = s:FF(d, a, b, c, x[ 9], 12, 0x8b44f7af) | |
let c = s:FF(c, d, a, b, x[10], 17, 0xffff5bb1) | |
let b = s:FF(b, c, d, a, x[11], 22, 0x895cd7be) | |
let a = s:FF(a, b, c, d, x[12], 7, 0x6b901122) | |
let d = s:FF(d, a, b, c, x[13], 12, 0xfd987193) | |
let c = s:FF(c, d, a, b, x[14], 17, 0xa679438e) | |
let b = s:FF(b, c, d, a, x[15], 22, 0x49b40821) | |
let a = s:GG(a, b, c, d, x[ 1], 5, 0xf61e2562) | |
let d = s:GG(d, a, b, c, x[ 6], 9, 0xc040b340) | |
let c = s:GG(c, d, a, b, x[11], 14, 0x265e5a51) | |
let b = s:GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa) | |
let a = s:GG(a, b, c, d, x[ 5], 5, 0xd62f105d) | |
let d = s:GG(d, a, b, c, x[10], 9, 0x2441453) | |
let c = s:GG(c, d, a, b, x[15], 14, 0xd8a1e681) | |
let b = s:GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8) | |
let a = s:GG(a, b, c, d, x[ 9], 5, 0x21e1cde6) | |
let d = s:GG(d, a, b, c, x[14], 9, 0xc33707d6) | |
let c = s:GG(c, d, a, b, x[ 3], 14, 0xf4d50d87) | |
let b = s:GG(b, c, d, a, x[ 8], 20, 0x455a14ed) | |
let a = s:GG(a, b, c, d, x[13], 5, 0xa9e3e905) | |
let d = s:GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8) | |
let c = s:GG(c, d, a, b, x[ 7], 14, 0x676f02d9) | |
let b = s:GG(b, c, d, a, x[12], 20, 0x8d2a4c8a) | |
let a = s:HH(a, b, c, d, x[ 5], 4, 0xfffa3942) | |
let d = s:HH(d, a, b, c, x[ 8], 11, 0x8771f681) | |
let c = s:HH(c, d, a, b, x[11], 16, 0x6d9d6122) | |
let b = s:HH(b, c, d, a, x[14], 23, 0xfde5380c) | |
let a = s:HH(a, b, c, d, x[ 1], 4, 0xa4beea44) | |
let d = s:HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9) | |
let c = s:HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60) | |
let b = s:HH(b, c, d, a, x[10], 23, 0xbebfbc70) | |
let a = s:HH(a, b, c, d, x[13], 4, 0x289b7ec6) | |
let d = s:HH(d, a, b, c, x[ 0], 11, 0xeaa127fa) | |
let c = s:HH(c, d, a, b, x[ 3], 16, 0xd4ef3085) | |
let b = s:HH(b, c, d, a, x[ 6], 23, 0x4881d05) | |
let a = s:HH(a, b, c, d, x[ 9], 4, 0xd9d4d039) | |
let d = s:HH(d, a, b, c, x[12], 11, 0xe6db99e5) | |
let c = s:HH(c, d, a, b, x[15], 16, 0x1fa27cf8) | |
let b = s:HH(b, c, d, a, x[ 2], 23, 0xc4ac5665) | |
let a = s:II(a, b, c, d, x[ 0], 6, 0xf4292244) | |
let d = s:II(d, a, b, c, x[ 7], 10, 0x432aff97) | |
let c = s:II(c, d, a, b, x[14], 15, 0xab9423a7) | |
let b = s:II(b, c, d, a, x[ 5], 21, 0xfc93a039) | |
let a = s:II(a, b, c, d, x[12], 6, 0x655b59c3) | |
let d = s:II(d, a, b, c, x[ 3], 10, 0x8f0ccc92) | |
let c = s:II(c, d, a, b, x[10], 15, 0xffeff47d) | |
let b = s:II(b, c, d, a, x[ 1], 21, 0x85845dd1) | |
let a = s:II(a, b, c, d, x[ 8], 6, 0x6fa87e4f) | |
let d = s:II(d, a, b, c, x[15], 10, 0xfe2ce6e0) | |
let c = s:II(c, d, a, b, x[ 6], 15, 0xa3014314) | |
let b = s:II(b, c, d, a, x[13], 21, 0x4e0811a1) | |
let a = s:II(a, b, c, d, x[ 4], 6, 0xf7537e82) | |
let d = s:II(d, a, b, c, x[11], 10, 0xbd3af235) | |
let c = s:II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb) | |
let b = s:II(b, c, d, a, x[ 9], 21, 0xeb86d391) | |
let a = a + aa | |
let b = b + bb | |
let c = c + cc | |
let d = d + dd | |
endfor | |
let digest = s:uint32_to_bytes_le(a) | |
let digest += s:uint32_to_bytes_le(b) | |
let digest += s:uint32_to_bytes_le(c) | |
let digest += s:uint32_to_bytes_le(d) | |
return s:bytestohex(digest) | |
endfunction | |
function! s:F(x, y, z) | |
return or(and(a:x, a:y), and(invert(a:x), a:z)) | |
endfunction | |
function! s:G(x, y, z) | |
return or(and(a:x, a:z), and(a:y, invert(a:z))) | |
endfunction | |
function! s:H(x, y, z) | |
return xor(xor(a:x, a:y), a:z) | |
endfunction | |
function! s:I(x, y, z) | |
return xor(a:y, or(a:x, invert(a:z))) | |
endfunction | |
function! s:FF(a, b, c, d, xk, s, ti) | |
return a:b + s:rotateleft32(a:a + s:F(a:b, a:c, a:d) + a:xk + a:ti, a:s) | |
endfunction | |
function! s:GG(a, b, c, d, xk, s, ti) | |
return a:b + s:rotateleft32(a:a + s:G(a:b, a:c, a:d) + a:xk + a:ti, a:s) | |
endfunction | |
function! s:HH(a, b, c, d, xk, s, ti) | |
return a:b + s:rotateleft32(a:a + s:H(a:b, a:c, a:d) + a:xk + a:ti, a:s) | |
endfunction | |
function! s:II(a, b, c, d, xk, s, ti) | |
return a:b + s:rotateleft32(a:a + s:I(a:b, a:c, a:d) + a:xk + a:ti, a:s) | |
endfunction | |
function! s:rotateleft32(a, offset) | |
return or(s:leftshift32(a:a, a:offset), s:rightshift32(a:a, 32 - a:offset)) | |
endfunction | |
let s:pow2 = [ | |
\ 0x1, 0x2, 0x4, 0x8, | |
\ 0x10, 0x20, 0x40, 0x80, | |
\ 0x100, 0x200, 0x400, 0x800, | |
\ 0x1000, 0x2000, 0x4000, 0x8000, | |
\ 0x10000, 0x20000, 0x40000, 0x80000, | |
\ 0x100000, 0x200000, 0x400000, 0x800000, | |
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000, | |
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000, | |
\ ] | |
function! s:leftshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n] | |
endfunction | |
function! s:rightshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : | |
\ a:a < 0 | |
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1] | |
\ : a:a / s:pow2[a:n] | |
endfunction | |
function! s:bytes_to_uint32_le(x) | |
return a:x[3] * 0x1000000 + a:x[2] * 0x10000 + a:x[1] * 0x100 + a:x[0] | |
endfunction | |
function! s:uint32_to_bytes_le(x) | |
let x0 = and(a:x, 0xFF) | |
let x1 = and(s:rightshift32(a:x, 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x, 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x, 24), 0xFF) | |
return [x0, x1, x2, x3] | |
endfunction | |
function! s:uint64_to_bytes_le(x) | |
let x0 = and(a:x[0], 0xFF) | |
let x1 = and(s:rightshift32(a:x[0], 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x[0], 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x[0], 24), 0xFF) | |
let x4 = and(a:x[1], 0xFF) | |
let x5 = and(s:rightshift32(a:x[1], 8), 0xFF) | |
let x6 = and(s:rightshift32(a:x[1], 16), 0xFF) | |
let x7 = and(s:rightshift32(a:x[1], 24), 0xFF) | |
return [x0, x1, x2, x3, x4, x5, x6, x7] | |
endfunction | |
function! s:bytes(seq) | |
if type(a:seq) | |
return s:strtobytes(a:seq) | |
elseif type(a:seq) == type([]) | |
return a:seq | |
else | |
throw 'type error' | |
endif | |
endfunction | |
function! s:hextobytes(hex) | |
return map(split(a:hex, '..\zs'), 'str2nr(v:val, 16)') | |
endfunction | |
function! s:bytestohex(bytes) | |
return join(map(copy(a:bytes), 'printf("%02x", v:val)'), '') | |
endfunction | |
function! s:strtobytes(str) | |
return map(range(len(a:str)), 'char2nr(a:str[v:val])') | |
endfunction |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" sha1: http://www.ietf.org/rfc/rfc3174.txt | |
function! Sha1(data) | |
let data = (type(a:data) == type("") ? s:strtobytes(a:data) : a:data) | |
return s:sha1(data) | |
endfunction | |
function! Sha1Test() | |
let s = "abc" | |
let h = Sha1(s) | |
if h ==? 'a9993e364706816aba3e25717850c26c9cd0d89d' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | |
let h = Sha1(s) | |
if h ==? '84983e441c3bd26ebaae4aa1f95129e5e54670f1' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
"let s = repeat("a", 1000000) | |
"let h = Sha1(s) | |
"if h ==? '34aa973cd4c4daa4f61eeb2bdbad27316534016f' | |
" echo printf('"%.1s..." => %s', s, h) | |
"else | |
" echoerr printf('"%.1s..." => %s', s, h) | |
"endif | |
let s = repeat("0123456701234567012345670123456701234567012345670123456701234567", 10) | |
let h = Sha1(s) | |
if h ==? 'dea356a2cddd90c7a7ecedc5ebb563934f460452' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
endfunction | |
function! s:sha1(bytes) | |
let m = a:bytes | |
let bitslen = len(m) * 8 | |
let m += [0x80] | |
let m += repeat([0], 64 - (len(m) + 8) % 64) | |
let m += s:uint64_to_bytes_be([bitslen, 0]) | |
let h0 = 0x67452301 | |
let h1 = 0xEFCDAB89 | |
let h2 = 0x98BADCFE | |
let h3 = 0x10325476 | |
let h4 = 0xC3D2E1F0 | |
let w = repeat([0], 80) | |
for i in range(0, len(m) - 1, 64) | |
for t in range(0, 15) | |
let w[t] = s:bytes_to_uint32_be(m[i + t * 4 : i + t * 4 + 3]) | |
endfor | |
for t in range(16, 79) | |
let w[t] = s:rotateleft32(xor(xor(xor(w[t - 3], w[t - 8]), w[t - 14]), w[t - 16]), 1) | |
endfor | |
let a = h0 | |
let b = h1 | |
let c = h2 | |
let d = h3 | |
let e = h4 | |
for t in range(0, 79) | |
if 0 <= t && t <= 19 | |
let f = or(and(b, c), and(invert(b), d)) | |
let k = 0x5A827999 | |
elseif 20 <= t && t <= 39 | |
let f = xor(xor(b, c), d) | |
let k = 0x6ED9EBA1 | |
elseif 40 <= t && t <= 59 | |
let f = or(or(and(b, c), and(b, d)), and(c, d)) | |
let k = 0x8F1BBCDC | |
elseif 60 <= t && t <= 79 | |
let f = xor(xor(b, c), d) | |
let k = 0xCA62C1D6 | |
endif | |
let temp = s:rotateleft32(a, 5) + f + e + k + w[t] | |
let e = d | |
let d = c | |
let c = s:rotateleft32(b, 30) | |
let b = a | |
let a = temp | |
endfor | |
let h0 = h0 + a | |
let h1 = h1 + b | |
let h2 = h2 + c | |
let h3 = h3 + d | |
let h4 = h4 + e | |
endfor | |
let digest = s:uint32_to_bytes_be(h0) | |
let digest += s:uint32_to_bytes_be(h1) | |
let digest += s:uint32_to_bytes_be(h2) | |
let digest += s:uint32_to_bytes_be(h3) | |
let digest += s:uint32_to_bytes_be(h4) | |
return s:bytestohex(digest) | |
endfunction | |
function! s:rotateleft32(a, offset) | |
return or(s:leftshift32(a:a, a:offset), s:rightshift32(a:a, 32 - a:offset)) | |
endfunction | |
let s:pow2 = [ | |
\ 0x1, 0x2, 0x4, 0x8, | |
\ 0x10, 0x20, 0x40, 0x80, | |
\ 0x100, 0x200, 0x400, 0x800, | |
\ 0x1000, 0x2000, 0x4000, 0x8000, | |
\ 0x10000, 0x20000, 0x40000, 0x80000, | |
\ 0x100000, 0x200000, 0x400000, 0x800000, | |
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000, | |
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000, | |
\ ] | |
function! s:leftshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n] | |
endfunction | |
function! s:rightshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : | |
\ a:a < 0 | |
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1] | |
\ : a:a / s:pow2[a:n] | |
endfunction | |
function! s:bytes_to_uint32_be(x) | |
return a:x[0] * 0x1000000 + a:x[1] * 0x10000 + a:x[2] * 0x100 + a:x[3] | |
endfunction | |
function! s:uint32_to_bytes_be(x) | |
let x0 = and(a:x, 0xFF) | |
let x1 = and(s:rightshift32(a:x, 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x, 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x, 24), 0xFF) | |
return [x3, x2, x1, x0] | |
endfunction | |
function! s:uint64_to_bytes_be(x) | |
let x0 = and(a:x[0], 0xFF) | |
let x1 = and(s:rightshift32(a:x[0], 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x[0], 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x[0], 24), 0xFF) | |
let x4 = and(a:x[1], 0xFF) | |
let x5 = and(s:rightshift32(a:x[1], 8), 0xFF) | |
let x6 = and(s:rightshift32(a:x[1], 16), 0xFF) | |
let x7 = and(s:rightshift32(a:x[1], 24), 0xFF) | |
return [x7, x6, x5, x4, x3, x2, x1, x0] | |
endfunction | |
function! s:bytes(seq) | |
if type(a:seq) | |
return s:strtobytes(a:seq) | |
elseif type(a:seq) == type([]) | |
return a:seq | |
else | |
throw 'type error' | |
endif | |
endfunction | |
function! s:hextobytes(hex) | |
return map(split(a:hex, '..\zs'), 'str2nr(v:val, 16)') | |
endfunction | |
function! s:bytestohex(bytes) | |
return join(map(copy(a:bytes), 'printf("%02x", v:val)'), '') | |
endfunction | |
function! s:strtobytes(str) | |
return map(range(len(a:str)), 'char2nr(a:str[v:val])') | |
endfunction |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" sha224: http://www.ietf.org/rfc/rfc4634.txt | |
function! Sha224(data) | |
let data = (type(a:data) == type("") ? s:strtobytes(a:data) : a:data) | |
return s:sha224(data) | |
endfunction | |
function! Sha224Test() | |
let s = "abc" | |
let h = Sha224(s) | |
if h ==? '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | |
let h = Sha224(s) | |
if h ==? '75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
"let s = repeat("a", 1000000) | |
"let h = Sha224(s) | |
"if h ==? '20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67' | |
" echo printf('"%.1s..." => %s', s, h) | |
"else | |
" echoerr printf('"%.1s..." => %s', s, h) | |
"endif | |
let s = repeat("0123456701234567012345670123456701234567012345670123456701234567", 10) | |
let h = Sha224(s) | |
if h ==? '567f69f168cd7844e65259ce658fe7aadfa25216e68eca0eb7ab8262' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
endfunction | |
let s:K = [ | |
\ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | |
\ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | |
\ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | |
\ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | |
\ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | |
\ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | |
\ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | |
\ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | |
\ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | |
\ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |
\ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | |
\ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | |
\ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | |
\ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | |
\ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | |
\ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, | |
\ ] | |
function! s:sha224(bytes) | |
let m = a:bytes | |
let bitslen = len(m) * 8 | |
let m += [0x80] | |
let m += repeat([0], 64 - (len(m) + 8) % 64) | |
let m += s:uint64_to_bytes_be([bitslen, 0]) | |
let h0 = 0xc1059ed8 | |
let h1 = 0x367cd507 | |
let h2 = 0x3070dd17 | |
let h3 = 0xf70e5939 | |
let h4 = 0xffc00b31 | |
let h5 = 0x68581511 | |
let h6 = 0x64f98fa7 | |
let h7 = 0xbefa4fa4 | |
let w = repeat([0], 64) | |
for i in range(0, len(m) - 1, 64) | |
for t in range(0, 15) | |
let w[t] = s:bytes_to_uint32_be(m[i + t * 4 : i + t * 4 + 3]) | |
endfor | |
for t in range(16, 63) | |
let w[t] = s:SSIG1(w[t - 2]) + w[t - 7] + s:SSIG0(w[t - 15]) + w[t - 16] | |
endfor | |
let a = h0 | |
let b = h1 | |
let c = h2 | |
let d = h3 | |
let e = h4 | |
let f = h5 | |
let g = h6 | |
let h = h7 | |
for t in range(0, 63) | |
let t1 = h + s:BSIG1(e) + s:CH(e, f, g) + s:K[t] + w[t] | |
let t2 = s:BSIG0(a) + s:MAJ(a, b, c) | |
let h = g | |
let g = f | |
let f = e | |
let e = d + t1 | |
let d = c | |
let c = b | |
let b = a | |
let a = t1 + t2 | |
endfor | |
let h0 = a + h0 | |
let h1 = b + h1 | |
let h2 = c + h2 | |
let h3 = d + h3 | |
let h4 = e + h4 | |
let h5 = f + h5 | |
let h6 = g + h6 | |
let h7 = h + h7 | |
endfor | |
let digest = s:uint32_to_bytes_be(h0) | |
let digest += s:uint32_to_bytes_be(h1) | |
let digest += s:uint32_to_bytes_be(h2) | |
let digest += s:uint32_to_bytes_be(h3) | |
let digest += s:uint32_to_bytes_be(h4) | |
let digest += s:uint32_to_bytes_be(h5) | |
let digest += s:uint32_to_bytes_be(h6) | |
return s:bytestohex(digest) | |
endfunction | |
function! s:CH(x, y, z) | |
return xor(and(a:x, a:y), and(invert(a:x), a:z)) | |
endfunction | |
function! s:MAJ(x, y, z) | |
return xor(xor(and(a:x, a:y), and(a:x, a:z)), and(a:y, a:z)) | |
endfunction | |
function! s:BSIG0(x) | |
return xor(xor(s:rotateright32(a:x, 2), s:rotateright32(a:x, 13)), s:rotateright32(a:x, 22)) | |
endfunction | |
function! s:BSIG1(x) | |
return xor(xor(s:rotateright32(a:x, 6), s:rotateright32(a:x, 11)), s:rotateright32(a:x, 25)) | |
endfunction | |
function! s:SSIG0(x) | |
return xor(xor(s:rotateright32(a:x, 7), s:rotateright32(a:x, 18)), s:rightshift32(a:x, 3)) | |
endfunction | |
function! s:SSIG1(x) | |
return xor(xor(s:rotateright32(a:x, 17), s:rotateright32(a:x, 19)), s:rightshift32(a:x, 10)) | |
endfunction | |
function! s:rotateleft32(a, offset) | |
return or(s:leftshift32(a:a, a:offset), s:rightshift32(a:a, 32 - a:offset)) | |
endfunction | |
function! s:rotateright32(a, offset) | |
return or(s:rightshift32(a:a, a:offset), s:leftshift32(a:a, 32 - a:offset)) | |
endfunction | |
let s:pow2 = [ | |
\ 0x1, 0x2, 0x4, 0x8, | |
\ 0x10, 0x20, 0x40, 0x80, | |
\ 0x100, 0x200, 0x400, 0x800, | |
\ 0x1000, 0x2000, 0x4000, 0x8000, | |
\ 0x10000, 0x20000, 0x40000, 0x80000, | |
\ 0x100000, 0x200000, 0x400000, 0x800000, | |
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000, | |
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000, | |
\ ] | |
function! s:leftshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n] | |
endfunction | |
function! s:rightshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : | |
\ a:a < 0 | |
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1] | |
\ : a:a / s:pow2[a:n] | |
endfunction | |
function! s:bytes_to_uint32_be(x) | |
return a:x[0] * 0x1000000 + a:x[1] * 0x10000 + a:x[2] * 0x100 + a:x[3] | |
endfunction | |
function! s:uint32_to_bytes_be(x) | |
let x0 = and(a:x, 0xFF) | |
let x1 = and(s:rightshift32(a:x, 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x, 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x, 24), 0xFF) | |
return [x3, x2, x1, x0] | |
endfunction | |
function! s:uint64_to_bytes_be(x) | |
let x0 = and(a:x[0], 0xFF) | |
let x1 = and(s:rightshift32(a:x[0], 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x[0], 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x[0], 24), 0xFF) | |
let x4 = and(a:x[1], 0xFF) | |
let x5 = and(s:rightshift32(a:x[1], 8), 0xFF) | |
let x6 = and(s:rightshift32(a:x[1], 16), 0xFF) | |
let x7 = and(s:rightshift32(a:x[1], 24), 0xFF) | |
return [x7, x6, x5, x4, x3, x2, x1, x0] | |
endfunction | |
function! s:bytes(seq) | |
if type(a:seq) | |
return s:strtobytes(a:seq) | |
elseif type(a:seq) == type([]) | |
return a:seq | |
else | |
throw 'type error' | |
endif | |
endfunction | |
function! s:hextobytes(hex) | |
return map(split(a:hex, '..\zs'), 'str2nr(v:val, 16)') | |
endfunction | |
function! s:bytestohex(bytes) | |
return join(map(copy(a:bytes), 'printf("%02x", v:val)'), '') | |
endfunction | |
function! s:strtobytes(str) | |
return map(range(len(a:str)), 'char2nr(a:str[v:val])') | |
endfunction |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" sha256: http://www.ietf.org/rfc/rfc4634.txt | |
function! Sha256(data) | |
let data = (type(a:data) == type("") ? s:strtobytes(a:data) : a:data) | |
return s:sha256(data) | |
endfunction | |
function! Sha256Test() | |
let s = "abc" | |
let h = Sha256(s) | |
if h ==? 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | |
let h = Sha256(s) | |
if h ==? '248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
"let s = repeat("a", 1000000) | |
"let h = Sha256(s) | |
"if h ==? '594847328451bdfa85056225462cc1d867d877fb388df0ce35f25ab5562bfbb5' | |
" echo printf('"%.1s..." => %s', s, h) | |
"else | |
" echoerr printf('"%.1s..." => %s', s, h) | |
"endif | |
let s = repeat("0123456701234567012345670123456701234567012345670123456701234567", 10) | |
let h = Sha256(s) | |
if h ==? '594847328451bdfa85056225462cc1d867d877fb388df0ce35f25ab5562bfbb5' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
endfunction | |
let s:K = [ | |
\ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | |
\ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | |
\ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | |
\ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | |
\ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | |
\ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | |
\ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | |
\ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | |
\ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | |
\ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |
\ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | |
\ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | |
\ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | |
\ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | |
\ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | |
\ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, | |
\ ] | |
function! s:sha256(bytes) | |
let m = a:bytes | |
let bitslen = len(m) * 8 | |
let m += [0x80] | |
let m += repeat([0], 64 - (len(m) + 8) % 64) | |
let m += s:uint64_to_bytes_be([bitslen, 0]) | |
let h0 = 0x6a09e667 | |
let h1 = 0xbb67ae85 | |
let h2 = 0x3c6ef372 | |
let h3 = 0xa54ff53a | |
let h4 = 0x510e527f | |
let h5 = 0x9b05688c | |
let h6 = 0x1f83d9ab | |
let h7 = 0x5be0cd19 | |
let w = repeat([0], 64) | |
for i in range(0, len(m) - 1, 64) | |
for t in range(0, 15) | |
let w[t] = s:bytes_to_uint32_be(m[i + t * 4 : i + t * 4 + 3]) | |
endfor | |
for t in range(16, 63) | |
let w[t] = s:SSIG1(w[t - 2]) + w[t - 7] + s:SSIG0(w[t - 15]) + w[t - 16] | |
endfor | |
let a = h0 | |
let b = h1 | |
let c = h2 | |
let d = h3 | |
let e = h4 | |
let f = h5 | |
let g = h6 | |
let h = h7 | |
for t in range(0, 63) | |
let t1 = h + s:BSIG1(e) + s:CH(e, f, g) + s:K[t] + w[t] | |
let t2 = s:BSIG0(a) + s:MAJ(a, b, c) | |
let h = g | |
let g = f | |
let f = e | |
let e = d + t1 | |
let d = c | |
let c = b | |
let b = a | |
let a = t1 + t2 | |
endfor | |
let h0 = a + h0 | |
let h1 = b + h1 | |
let h2 = c + h2 | |
let h3 = d + h3 | |
let h4 = e + h4 | |
let h5 = f + h5 | |
let h6 = g + h6 | |
let h7 = h + h7 | |
endfor | |
let digest = s:uint32_to_bytes_be(h0) | |
let digest += s:uint32_to_bytes_be(h1) | |
let digest += s:uint32_to_bytes_be(h2) | |
let digest += s:uint32_to_bytes_be(h3) | |
let digest += s:uint32_to_bytes_be(h4) | |
let digest += s:uint32_to_bytes_be(h5) | |
let digest += s:uint32_to_bytes_be(h6) | |
let digest += s:uint32_to_bytes_be(h7) | |
return s:bytestohex(digest) | |
endfunction | |
function! s:CH(x, y, z) | |
return xor(and(a:x, a:y), and(invert(a:x), a:z)) | |
endfunction | |
function! s:MAJ(x, y, z) | |
return xor(xor(and(a:x, a:y), and(a:x, a:z)), and(a:y, a:z)) | |
endfunction | |
function! s:BSIG0(x) | |
return xor(xor(s:rotateright32(a:x, 2), s:rotateright32(a:x, 13)), s:rotateright32(a:x, 22)) | |
endfunction | |
function! s:BSIG1(x) | |
return xor(xor(s:rotateright32(a:x, 6), s:rotateright32(a:x, 11)), s:rotateright32(a:x, 25)) | |
endfunction | |
function! s:SSIG0(x) | |
return xor(xor(s:rotateright32(a:x, 7), s:rotateright32(a:x, 18)), s:rightshift32(a:x, 3)) | |
endfunction | |
function! s:SSIG1(x) | |
return xor(xor(s:rotateright32(a:x, 17), s:rotateright32(a:x, 19)), s:rightshift32(a:x, 10)) | |
endfunction | |
function! s:rotateleft32(a, offset) | |
return or(s:leftshift32(a:a, a:offset), s:rightshift32(a:a, 32 - a:offset)) | |
endfunction | |
function! s:rotateright32(a, offset) | |
return or(s:rightshift32(a:a, a:offset), s:leftshift32(a:a, 32 - a:offset)) | |
endfunction | |
let s:pow2 = [ | |
\ 0x1, 0x2, 0x4, 0x8, | |
\ 0x10, 0x20, 0x40, 0x80, | |
\ 0x100, 0x200, 0x400, 0x800, | |
\ 0x1000, 0x2000, 0x4000, 0x8000, | |
\ 0x10000, 0x20000, 0x40000, 0x80000, | |
\ 0x100000, 0x200000, 0x400000, 0x800000, | |
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000, | |
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000, | |
\ ] | |
function! s:leftshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n] | |
endfunction | |
function! s:rightshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : | |
\ a:a < 0 | |
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1] | |
\ : a:a / s:pow2[a:n] | |
endfunction | |
function! s:bytes_to_uint32_be(x) | |
return a:x[0] * 0x1000000 + a:x[1] * 0x10000 + a:x[2] * 0x100 + a:x[3] | |
endfunction | |
function! s:uint32_to_bytes_be(x) | |
let x0 = and(a:x, 0xFF) | |
let x1 = and(s:rightshift32(a:x, 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x, 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x, 24), 0xFF) | |
return [x3, x2, x1, x0] | |
endfunction | |
function! s:uint64_to_bytes_be(x) | |
let x0 = and(a:x[0], 0xFF) | |
let x1 = and(s:rightshift32(a:x[0], 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x[0], 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x[0], 24), 0xFF) | |
let x4 = and(a:x[1], 0xFF) | |
let x5 = and(s:rightshift32(a:x[1], 8), 0xFF) | |
let x6 = and(s:rightshift32(a:x[1], 16), 0xFF) | |
let x7 = and(s:rightshift32(a:x[1], 24), 0xFF) | |
return [x7, x6, x5, x4, x3, x2, x1, x0] | |
endfunction | |
function! s:bytes(seq) | |
if type(a:seq) | |
return s:strtobytes(a:seq) | |
elseif type(a:seq) == type([]) | |
return a:seq | |
else | |
throw 'type error' | |
endif | |
endfunction | |
function! s:hextobytes(hex) | |
return map(split(a:hex, '..\zs'), 'str2nr(v:val, 16)') | |
endfunction | |
function! s:bytestohex(bytes) | |
return join(map(copy(a:bytes), 'printf("%02x", v:val)'), '') | |
endfunction | |
function! s:strtobytes(str) | |
return map(range(len(a:str)), 'char2nr(a:str[v:val])') | |
endfunction |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" sha384: http://www.ietf.org/rfc/rfc4634.txt | |
function! Sha384(data) | |
let data = (type(a:data) == type("") ? s:strtobytes(a:data) : a:data) | |
return s:sha384(data) | |
endfunction | |
function! Sha384Test() | |
let s = "abc" | |
let h = Sha384(s) | |
if h ==? 'cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" | |
let h = Sha384(s) | |
if h ==? '09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
"let s = repeat("a", 1000000) | |
"let h = Sha384(s) | |
"if h ==? '9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985' | |
" echo printf('"%.1s..." => %s', s, h) | |
"else | |
" echoerr printf('"%.1s..." => %s', s, h) | |
"endif | |
let s = repeat("0123456701234567012345670123456701234567012345670123456701234567", 10) | |
let h = Sha384(s) | |
if h ==? '2fc64a4f500ddb6828f6a3430b8dd72a368eb7f3a8322a70bc84275b9c0b3ab00d27a5cc3c2d224aa6b61a0d79fb4596' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
endfunction | |
let s:K = [ | |
\ [0xd728ae22, 0x428a2f98], [0x23ef65cd, 0x71374491], [0xec4d3b2f, 0xb5c0fbcf], [0x8189dbbc, 0xe9b5dba5], | |
\ [0xf348b538, 0x3956c25b], [0xb605d019, 0x59f111f1], [0xaf194f9b, 0x923f82a4], [0xda6d8118, 0xab1c5ed5], | |
\ [0xa3030242, 0xd807aa98], [0x45706fbe, 0x12835b01], [0x4ee4b28c, 0x243185be], [0xd5ffb4e2, 0x550c7dc3], | |
\ [0xf27b896f, 0x72be5d74], [0x3b1696b1, 0x80deb1fe], [0x25c71235, 0x9bdc06a7], [0xcf692694, 0xc19bf174], | |
\ [0x9ef14ad2, 0xe49b69c1], [0x384f25e3, 0xefbe4786], [0x8b8cd5b5, 0x0fc19dc6], [0x77ac9c65, 0x240ca1cc], | |
\ [0x592b0275, 0x2de92c6f], [0x6ea6e483, 0x4a7484aa], [0xbd41fbd4, 0x5cb0a9dc], [0x831153b5, 0x76f988da], | |
\ [0xee66dfab, 0x983e5152], [0x2db43210, 0xa831c66d], [0x98fb213f, 0xb00327c8], [0xbeef0ee4, 0xbf597fc7], | |
\ [0x3da88fc2, 0xc6e00bf3], [0x930aa725, 0xd5a79147], [0xe003826f, 0x06ca6351], [0x0a0e6e70, 0x14292967], | |
\ [0x46d22ffc, 0x27b70a85], [0x5c26c926, 0x2e1b2138], [0x5ac42aed, 0x4d2c6dfc], [0x9d95b3df, 0x53380d13], | |
\ [0x8baf63de, 0x650a7354], [0x3c77b2a8, 0x766a0abb], [0x47edaee6, 0x81c2c92e], [0x1482353b, 0x92722c85], | |
\ [0x4cf10364, 0xa2bfe8a1], [0xbc423001, 0xa81a664b], [0xd0f89791, 0xc24b8b70], [0x0654be30, 0xc76c51a3], | |
\ [0xd6ef5218, 0xd192e819], [0x5565a910, 0xd6990624], [0x5771202a, 0xf40e3585], [0x32bbd1b8, 0x106aa070], | |
\ [0xb8d2d0c8, 0x19a4c116], [0x5141ab53, 0x1e376c08], [0xdf8eeb99, 0x2748774c], [0xe19b48a8, 0x34b0bcb5], | |
\ [0xc5c95a63, 0x391c0cb3], [0xe3418acb, 0x4ed8aa4a], [0x7763e373, 0x5b9cca4f], [0xd6b2b8a3, 0x682e6ff3], | |
\ [0x5defb2fc, 0x748f82ee], [0x43172f60, 0x78a5636f], [0xa1f0ab72, 0x84c87814], [0x1a6439ec, 0x8cc70208], | |
\ [0x23631e28, 0x90befffa], [0xde82bde9, 0xa4506ceb], [0xb2c67915, 0xbef9a3f7], [0xe372532b, 0xc67178f2], | |
\ [0xea26619c, 0xca273ece], [0x21c0c207, 0xd186b8c7], [0xcde0eb1e, 0xeada7dd6], [0xee6ed178, 0xf57d4f7f], | |
\ [0x72176fba, 0x06f067aa], [0xa2c898a6, 0x0a637dc5], [0xbef90dae, 0x113f9804], [0x131c471b, 0x1b710b35], | |
\ [0x23047d84, 0x28db77f5], [0x40c72493, 0x32caab7b], [0x15c9bebc, 0x3c9ebe0a], [0x9c100d4c, 0x431d67c4], | |
\ [0xcb3e42b6, 0x4cc5d4be], [0xfc657e2a, 0x597f299c], [0x3ad6faec, 0x5fcb6fab], [0x4a475817, 0x6c44198c], | |
\ ] | |
function! s:sha384(bytes) | |
let m = a:bytes | |
let bitslen = len(m) * 8 | |
let m += [0x80] | |
let m += repeat([0], 128 - (len(m) + 16) % 128) | |
let m += s:uint64_to_bytes_be([0, 0]) | |
let m += s:uint64_to_bytes_be([bitslen, 0]) | |
let h0 = [0xc1059ed8, 0xcbbb9d5d] | |
let h1 = [0x367cd507, 0x629a292a] | |
let h2 = [0x3070dd17, 0x9159015a] | |
let h3 = [0xf70e5939, 0x152fecd8] | |
let h4 = [0xffc00b31, 0x67332667] | |
let h5 = [0x68581511, 0x8eb44a87] | |
let h6 = [0x64f98fa7, 0xdb0c2e0d] | |
let h7 = [0xbefa4fa4, 0x47b5481d] | |
let w = repeat([0], 80) | |
for i in range(0, len(m) - 1, 128) | |
for t in range(0, 15) | |
let w[t] = s:bytes_to_uint64_be(m[i + t * 8 : i + t * 8 + 7]) | |
endfor | |
for t in range(16, 79) | |
let w[t] = s:add64(s:add64(s:add64(s:SSIG1(w[t - 2]), w[t - 7]), s:SSIG0(w[t - 15])), w[t - 16]) | |
endfor | |
let a = h0 | |
let b = h1 | |
let c = h2 | |
let d = h3 | |
let e = h4 | |
let f = h5 | |
let g = h6 | |
let h = h7 | |
for t in range(0, 79) | |
let t1 = s:add64(s:add64(s:add64(s:add64(h, s:BSIG1(e)), s:CH(e, f, g)), s:K[t]), w[t]) | |
let t2 = s:add64(s:BSIG0(a), s:MAJ(a, b, c)) | |
let h = g | |
let g = f | |
let f = e | |
let e = s:add64(d, t1) | |
let d = c | |
let c = b | |
let b = a | |
let a = s:add64(t1, t2) | |
endfor | |
let h0 = s:add64(a, h0) | |
let h1 = s:add64(b, h1) | |
let h2 = s:add64(c, h2) | |
let h3 = s:add64(d, h3) | |
let h4 = s:add64(e, h4) | |
let h5 = s:add64(f, h5) | |
let h6 = s:add64(g, h6) | |
let h7 = s:add64(h, h7) | |
endfor | |
let digest = s:uint64_to_bytes_be(h0) | |
let digest += s:uint64_to_bytes_be(h1) | |
let digest += s:uint64_to_bytes_be(h2) | |
let digest += s:uint64_to_bytes_be(h3) | |
let digest += s:uint64_to_bytes_be(h4) | |
let digest += s:uint64_to_bytes_be(h5) | |
return s:bytestohex(digest) | |
endfunction | |
function! s:CH(x, y, z) | |
return s:xor64(s:and64(a:x, a:y), s:and64(s:invert64(a:x), a:z)) | |
endfunction | |
function! s:MAJ(x, y, z) | |
return s:xor64(s:xor64(s:and64(a:x, a:y), s:and64(a:x, a:z)), s:and64(a:y, a:z)) | |
endfunction | |
function! s:BSIG0(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 28), s:rotateright64(a:x, 34)), s:rotateright64(a:x, 39)) | |
endfunction | |
function! s:BSIG1(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 14), s:rotateright64(a:x, 18)), s:rotateright64(a:x, 41)) | |
endfunction | |
function! s:SSIG0(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 1), s:rotateright64(a:x, 8)), s:rightshift64(a:x, 7)) | |
endfunction | |
function! s:SSIG1(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 19), s:rotateright64(a:x, 61)), s:rightshift64(a:x, 6)) | |
endfunction | |
function! s:cmp64(a, b) | |
let c = s:cmp32(a:a[1], a:b[1]) | |
if c == 0 | |
let c = s:cmp32(a:a[0], a:b[0]) | |
endif | |
return c | |
endfunction | |
function! s:cmp32(a, b) | |
if (a:a >= 0 && a:b >= 0) || (a:a < 0 && a:b < 0) | |
return a:a < a:b ? -1 : a:a > a:b ? 1 : 0 | |
else | |
return a:a < 0 ? 1 : -1 | |
endif | |
endfunction | |
function! s:add64(a, b) | |
let lo = a:a[0] + a:b[0] | |
let c = (s:cmp32(lo, a:b[0]) < 0) | |
let hi = a:a[1] + a:b[1] + c | |
return [lo, hi] | |
endfunction | |
function! s:rotateleft64(a, offset) | |
return s:or64(s:leftshift64(a:a, a:offset), s:rightshift64(a:a, 64 - a:offset)) | |
endfunction | |
function! s:rotateright64(a, offset) | |
return s:or64(s:rightshift64(a:a, a:offset), s:leftshift64(a:a, 64 - a:offset)) | |
endfunction | |
function! s:invert64(x) | |
return [invert(a:x[0]), invert(a:x[1])] | |
endfunction | |
function! s:and64(x, y) | |
return [and(a:x[0], a:y[0]), and(a:x[1], a:y[1])] | |
endfunction | |
function! s:or64(x, y) | |
return [or(a:x[0], a:y[0]), or(a:x[1], a:y[1])] | |
endfunction | |
function! s:xor64(x, y) | |
return [xor(a:x[0], a:y[0]), xor(a:x[1], a:y[1])] | |
endfunction | |
let s:pow2 = [ | |
\ 0x1, 0x2, 0x4, 0x8, | |
\ 0x10, 0x20, 0x40, 0x80, | |
\ 0x100, 0x200, 0x400, 0x800, | |
\ 0x1000, 0x2000, 0x4000, 0x8000, | |
\ 0x10000, 0x20000, 0x40000, 0x80000, | |
\ 0x100000, 0x200000, 0x400000, 0x800000, | |
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000, | |
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000, | |
\ ] | |
function! s:leftshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n] | |
endfunction | |
function! s:rightshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : | |
\ a:a < 0 | |
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1] | |
\ : a:a / s:pow2[a:n] | |
endfunction | |
function! s:leftshift64(x, n) | |
let lo = s:leftshift32(a:x[0], a:n) | |
if a:n < 32 | |
let hi = or(s:leftshift32(a:x[1], a:n), s:rightshift32(a:x[0], 32 - a:n)) | |
else | |
let hi = s:leftshift32(a:x[0], a:n - 32) | |
endif | |
return [lo, hi] | |
endfunction | |
function! s:rightshift64(x, n) | |
let hi = s:rightshift32(a:x[1], a:n) | |
if a:n < 32 | |
let lo = or(s:rightshift32(a:x[0], a:n), s:leftshift32(a:x[1], 32 - a:n)) | |
else | |
let lo = s:rightshift32(a:x[1], a:n - 32) | |
endif | |
return [lo, hi] | |
endfunction | |
function! s:bytes_to_uint64_be(x) | |
let lo = a:x[4] * 0x1000000 + a:x[5] * 0x10000 + a:x[6] * 0x100 + a:x[7] | |
let hi = a:x[0] * 0x1000000 + a:x[1] * 0x10000 + a:x[2] * 0x100 + a:x[3] | |
return [lo, hi] | |
endfunction | |
function! s:uint64_to_bytes_be(x) | |
let x0 = and(a:x[0], 0xFF) | |
let x1 = and(s:rightshift32(a:x[0], 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x[0], 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x[0], 24), 0xFF) | |
let x4 = and(a:x[1], 0xFF) | |
let x5 = and(s:rightshift32(a:x[1], 8), 0xFF) | |
let x6 = and(s:rightshift32(a:x[1], 16), 0xFF) | |
let x7 = and(s:rightshift32(a:x[1], 24), 0xFF) | |
return [x7, x6, x5, x4, x3, x2, x1, x0] | |
endfunction | |
function! s:bytes(seq) | |
if type(a:seq) | |
return s:strtobytes(a:seq) | |
elseif type(a:seq) == type([]) | |
return a:seq | |
else | |
throw 'type error' | |
endif | |
endfunction | |
function! s:hextobytes(hex) | |
return map(split(a:hex, '..\zs'), 'str2nr(v:val, 16)') | |
endfunction | |
function! s:bytestohex(bytes) | |
return join(map(copy(a:bytes), 'printf("%02x", v:val)'), '') | |
endfunction | |
function! s:strtobytes(str) | |
return map(range(len(a:str)), 'char2nr(a:str[v:val])') | |
endfunction |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" sha512: http://www.ietf.org/rfc/rfc4634.txt | |
function! Sha512(data) | |
let data = (type(a:data) == type("") ? s:strtobytes(a:data) : a:data) | |
return s:sha512(data) | |
endfunction | |
function! Sha512Test() | |
let s = "abc" | |
let h = Sha512(s) | |
if h ==? 'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
let s = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" | |
let h = Sha512(s) | |
if h ==? '8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
"let s = repeat("a", 1000000) | |
"let h = Sha512(s) | |
"if h ==? 'e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b' | |
" echo printf('"%.1s..." => %s', s, h) | |
"else | |
" echoerr printf('"%.1s..." => %s', s, h) | |
"endif | |
let s = repeat("0123456701234567012345670123456701234567012345670123456701234567", 10) | |
let h = Sha512(s) | |
if h ==? '89d05ba632c699c31231ded4ffc127d5a894dad412c0e024db872d1abd2ba8141a0f85072a9be1e2aa04cf33c765cb510813a39cd5a84c4acaa64d3f3fb7bae9' | |
echo printf('"%s" => %s', s, h) | |
else | |
echoerr printf('"%s" => %s', s, h) | |
endif | |
endfunction | |
let s:K = [ | |
\ [0xd728ae22, 0x428a2f98], [0x23ef65cd, 0x71374491], [0xec4d3b2f, 0xb5c0fbcf], [0x8189dbbc, 0xe9b5dba5], | |
\ [0xf348b538, 0x3956c25b], [0xb605d019, 0x59f111f1], [0xaf194f9b, 0x923f82a4], [0xda6d8118, 0xab1c5ed5], | |
\ [0xa3030242, 0xd807aa98], [0x45706fbe, 0x12835b01], [0x4ee4b28c, 0x243185be], [0xd5ffb4e2, 0x550c7dc3], | |
\ [0xf27b896f, 0x72be5d74], [0x3b1696b1, 0x80deb1fe], [0x25c71235, 0x9bdc06a7], [0xcf692694, 0xc19bf174], | |
\ [0x9ef14ad2, 0xe49b69c1], [0x384f25e3, 0xefbe4786], [0x8b8cd5b5, 0x0fc19dc6], [0x77ac9c65, 0x240ca1cc], | |
\ [0x592b0275, 0x2de92c6f], [0x6ea6e483, 0x4a7484aa], [0xbd41fbd4, 0x5cb0a9dc], [0x831153b5, 0x76f988da], | |
\ [0xee66dfab, 0x983e5152], [0x2db43210, 0xa831c66d], [0x98fb213f, 0xb00327c8], [0xbeef0ee4, 0xbf597fc7], | |
\ [0x3da88fc2, 0xc6e00bf3], [0x930aa725, 0xd5a79147], [0xe003826f, 0x06ca6351], [0x0a0e6e70, 0x14292967], | |
\ [0x46d22ffc, 0x27b70a85], [0x5c26c926, 0x2e1b2138], [0x5ac42aed, 0x4d2c6dfc], [0x9d95b3df, 0x53380d13], | |
\ [0x8baf63de, 0x650a7354], [0x3c77b2a8, 0x766a0abb], [0x47edaee6, 0x81c2c92e], [0x1482353b, 0x92722c85], | |
\ [0x4cf10364, 0xa2bfe8a1], [0xbc423001, 0xa81a664b], [0xd0f89791, 0xc24b8b70], [0x0654be30, 0xc76c51a3], | |
\ [0xd6ef5218, 0xd192e819], [0x5565a910, 0xd6990624], [0x5771202a, 0xf40e3585], [0x32bbd1b8, 0x106aa070], | |
\ [0xb8d2d0c8, 0x19a4c116], [0x5141ab53, 0x1e376c08], [0xdf8eeb99, 0x2748774c], [0xe19b48a8, 0x34b0bcb5], | |
\ [0xc5c95a63, 0x391c0cb3], [0xe3418acb, 0x4ed8aa4a], [0x7763e373, 0x5b9cca4f], [0xd6b2b8a3, 0x682e6ff3], | |
\ [0x5defb2fc, 0x748f82ee], [0x43172f60, 0x78a5636f], [0xa1f0ab72, 0x84c87814], [0x1a6439ec, 0x8cc70208], | |
\ [0x23631e28, 0x90befffa], [0xde82bde9, 0xa4506ceb], [0xb2c67915, 0xbef9a3f7], [0xe372532b, 0xc67178f2], | |
\ [0xea26619c, 0xca273ece], [0x21c0c207, 0xd186b8c7], [0xcde0eb1e, 0xeada7dd6], [0xee6ed178, 0xf57d4f7f], | |
\ [0x72176fba, 0x06f067aa], [0xa2c898a6, 0x0a637dc5], [0xbef90dae, 0x113f9804], [0x131c471b, 0x1b710b35], | |
\ [0x23047d84, 0x28db77f5], [0x40c72493, 0x32caab7b], [0x15c9bebc, 0x3c9ebe0a], [0x9c100d4c, 0x431d67c4], | |
\ [0xcb3e42b6, 0x4cc5d4be], [0xfc657e2a, 0x597f299c], [0x3ad6faec, 0x5fcb6fab], [0x4a475817, 0x6c44198c], | |
\ ] | |
function! s:sha512(bytes) | |
let m = a:bytes | |
let bitslen = len(m) * 8 | |
let m += [0x80] | |
let m += repeat([0], 128 - (len(m) + 16) % 128) | |
let m += s:uint64_to_bytes_be([0, 0]) | |
let m += s:uint64_to_bytes_be([bitslen, 0]) | |
let h0 = [0xf3bcc908, 0x6a09e667] | |
let h1 = [0x84caa73b, 0xbb67ae85] | |
let h2 = [0xfe94f82b, 0x3c6ef372] | |
let h3 = [0x5f1d36f1, 0xa54ff53a] | |
let h4 = [0xade682d1, 0x510e527f] | |
let h5 = [0x2b3e6c1f, 0x9b05688c] | |
let h6 = [0xfb41bd6b, 0x1f83d9ab] | |
let h7 = [0x137e2179, 0x5be0cd19] | |
let w = repeat([0], 80) | |
for i in range(0, len(m) - 1, 128) | |
for t in range(0, 15) | |
let w[t] = s:bytes_to_uint64_be(m[i + t * 8 : i + t * 8 + 7]) | |
endfor | |
for t in range(16, 79) | |
let w[t] = s:add64(s:add64(s:add64(s:SSIG1(w[t - 2]), w[t - 7]), s:SSIG0(w[t - 15])), w[t - 16]) | |
endfor | |
let a = h0 | |
let b = h1 | |
let c = h2 | |
let d = h3 | |
let e = h4 | |
let f = h5 | |
let g = h6 | |
let h = h7 | |
for t in range(0, 79) | |
let t1 = s:add64(s:add64(s:add64(s:add64(h, s:BSIG1(e)), s:CH(e, f, g)), s:K[t]), w[t]) | |
let t2 = s:add64(s:BSIG0(a), s:MAJ(a, b, c)) | |
let h = g | |
let g = f | |
let f = e | |
let e = s:add64(d, t1) | |
let d = c | |
let c = b | |
let b = a | |
let a = s:add64(t1, t2) | |
endfor | |
let h0 = s:add64(a, h0) | |
let h1 = s:add64(b, h1) | |
let h2 = s:add64(c, h2) | |
let h3 = s:add64(d, h3) | |
let h4 = s:add64(e, h4) | |
let h5 = s:add64(f, h5) | |
let h6 = s:add64(g, h6) | |
let h7 = s:add64(h, h7) | |
endfor | |
let digest = s:uint64_to_bytes_be(h0) | |
let digest += s:uint64_to_bytes_be(h1) | |
let digest += s:uint64_to_bytes_be(h2) | |
let digest += s:uint64_to_bytes_be(h3) | |
let digest += s:uint64_to_bytes_be(h4) | |
let digest += s:uint64_to_bytes_be(h5) | |
let digest += s:uint64_to_bytes_be(h6) | |
let digest += s:uint64_to_bytes_be(h7) | |
return s:bytestohex(digest) | |
endfunction | |
function! s:CH(x, y, z) | |
return s:xor64(s:and64(a:x, a:y), s:and64(s:invert64(a:x), a:z)) | |
endfunction | |
function! s:MAJ(x, y, z) | |
return s:xor64(s:xor64(s:and64(a:x, a:y), s:and64(a:x, a:z)), s:and64(a:y, a:z)) | |
endfunction | |
function! s:BSIG0(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 28), s:rotateright64(a:x, 34)), s:rotateright64(a:x, 39)) | |
endfunction | |
function! s:BSIG1(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 14), s:rotateright64(a:x, 18)), s:rotateright64(a:x, 41)) | |
endfunction | |
function! s:SSIG0(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 1), s:rotateright64(a:x, 8)), s:rightshift64(a:x, 7)) | |
endfunction | |
function! s:SSIG1(x) | |
return s:xor64(s:xor64(s:rotateright64(a:x, 19), s:rotateright64(a:x, 61)), s:rightshift64(a:x, 6)) | |
endfunction | |
function! s:cmp64(a, b) | |
let c = s:cmp32(a:a[1], a:b[1]) | |
if c == 0 | |
let c = s:cmp32(a:a[0], a:b[0]) | |
endif | |
return c | |
endfunction | |
function! s:cmp32(a, b) | |
if (a:a >= 0 && a:b >= 0) || (a:a < 0 && a:b < 0) | |
return a:a < a:b ? -1 : a:a > a:b ? 1 : 0 | |
else | |
return a:a < 0 ? 1 : -1 | |
endif | |
endfunction | |
function! s:add64(a, b) | |
let lo = a:a[0] + a:b[0] | |
let c = (s:cmp32(lo, a:b[0]) < 0) | |
let hi = a:a[1] + a:b[1] + c | |
return [lo, hi] | |
endfunction | |
function! s:rotateleft64(a, offset) | |
return s:or64(s:leftshift64(a:a, a:offset), s:rightshift64(a:a, 64 - a:offset)) | |
endfunction | |
function! s:rotateright64(a, offset) | |
return s:or64(s:rightshift64(a:a, a:offset), s:leftshift64(a:a, 64 - a:offset)) | |
endfunction | |
function! s:invert64(x) | |
return [invert(a:x[0]), invert(a:x[1])] | |
endfunction | |
function! s:and64(x, y) | |
return [and(a:x[0], a:y[0]), and(a:x[1], a:y[1])] | |
endfunction | |
function! s:or64(x, y) | |
return [or(a:x[0], a:y[0]), or(a:x[1], a:y[1])] | |
endfunction | |
function! s:xor64(x, y) | |
return [xor(a:x[0], a:y[0]), xor(a:x[1], a:y[1])] | |
endfunction | |
let s:pow2 = [ | |
\ 0x1, 0x2, 0x4, 0x8, | |
\ 0x10, 0x20, 0x40, 0x80, | |
\ 0x100, 0x200, 0x400, 0x800, | |
\ 0x1000, 0x2000, 0x4000, 0x8000, | |
\ 0x10000, 0x20000, 0x40000, 0x80000, | |
\ 0x100000, 0x200000, 0x400000, 0x800000, | |
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000, | |
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000, | |
\ ] | |
function! s:leftshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n] | |
endfunction | |
function! s:rightshift32(a, n) | |
return a:n == 0 ? a:a : a:n > 31 ? 0 : | |
\ a:a < 0 | |
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1] | |
\ : a:a / s:pow2[a:n] | |
endfunction | |
function! s:leftshift64(x, n) | |
let lo = s:leftshift32(a:x[0], a:n) | |
if a:n < 32 | |
let hi = or(s:leftshift32(a:x[1], a:n), s:rightshift32(a:x[0], 32 - a:n)) | |
else | |
let hi = s:leftshift32(a:x[0], a:n - 32) | |
endif | |
return [lo, hi] | |
endfunction | |
function! s:rightshift64(x, n) | |
let hi = s:rightshift32(a:x[1], a:n) | |
if a:n < 32 | |
let lo = or(s:rightshift32(a:x[0], a:n), s:leftshift32(a:x[1], 32 - a:n)) | |
else | |
let lo = s:rightshift32(a:x[1], a:n - 32) | |
endif | |
return [lo, hi] | |
endfunction | |
function! s:bytes_to_uint64_be(x) | |
let lo = a:x[4] * 0x1000000 + a:x[5] * 0x10000 + a:x[6] * 0x100 + a:x[7] | |
let hi = a:x[0] * 0x1000000 + a:x[1] * 0x10000 + a:x[2] * 0x100 + a:x[3] | |
return [lo, hi] | |
endfunction | |
function! s:uint64_to_bytes_be(x) | |
let x0 = and(a:x[0], 0xFF) | |
let x1 = and(s:rightshift32(a:x[0], 8), 0xFF) | |
let x2 = and(s:rightshift32(a:x[0], 16), 0xFF) | |
let x3 = and(s:rightshift32(a:x[0], 24), 0xFF) | |
let x4 = and(a:x[1], 0xFF) | |
let x5 = and(s:rightshift32(a:x[1], 8), 0xFF) | |
let x6 = and(s:rightshift32(a:x[1], 16), 0xFF) | |
let x7 = and(s:rightshift32(a:x[1], 24), 0xFF) | |
return [x7, x6, x5, x4, x3, x2, x1, x0] | |
endfunction | |
function! s:bytes(seq) | |
if type(a:seq) | |
return s:strtobytes(a:seq) | |
elseif type(a:seq) == type([]) | |
return a:seq | |
else | |
throw 'type error' | |
endif | |
endfunction | |
function! s:hextobytes(hex) | |
return map(split(a:hex, '..\zs'), 'str2nr(v:val, 16)') | |
endfunction | |
function! s:bytestohex(bytes) | |
return join(map(copy(a:bytes), 'printf("%02x", v:val)'), '') | |
endfunction | |
function! s:strtobytes(str) | |
return map(range(len(a:str)), 'char2nr(a:str[v:val])') | |
endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A comprehensive list of general purpose hash functions and their implementations can found here:
https://www.partow.net/programming/hashfunctions/index.html