|
4 | 4 | ---@param file file The file |
5 | 5 | ---@return string SHA-256 checksum |
6 | 6 | function sha256_file(file) |
7 | | - local M,K=0xFFFFFFFF,{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} |
8 | | - local function RR(x,n)return (x>>n)|((x&M)<<(32-n))end |
9 | | - local function TF(k,H)local W={}for i=0,15 do local o=i*4+1 W[i]=string.byte(k,o)<<24|string.byte(k,o+1)<<16|string.byte(k,o+2)<<8|string.byte(k,o+3)end |
10 | | - for i=16,63 do |
11 | | - local s0,s1=RR(W[i-15],7)~RR(W[i-15],18)~(W[i-15]>>3),RR(W[i-2],17)~RR(W[i-2],19)~(W[i-2]>>10) --#squish keep-eol |
12 | | - W[i]=(W[i-16]+s0+W[i-7]+s1)&M end |
13 | | - local a,b,c,d,e,f,g,h=table.unpack(H)for i=0,63 do |
14 | | - local S0,S1,ch,maj=RR(a,2)~RR(a,13)~RR(a,22),RR(e,6)~RR(e,11)~RR(e,25),(e&f)~((~e)&g),(a&b)~(a&c)~(b&c) --#squish keep-eol |
15 | | - local t1,t2=(h+S1+ch+K[i+1]+W[i])&M,(S0+maj)&M |
16 | | - h=g g=f f=e e=(d+t1)&M d=c c=b b=a a=(t1+t2)&M end |
17 | | - H[1]=(H[1]+a)&M H[2]=(H[2]+b)&M H[3]=(H[3]+c)&M H[4]=(H[4]+d)&M H[5]=(H[5]+e)&M H[6]=(H[6]+f)&M H[7]=(H[7]+g)&M H[8]=(H[8]+h)&M end |
| 7 | + -- M = Maximum value of number (32-bits) |
| 8 | + -- K = SHA256 round constants |
| 9 | + local M, K = 0xFFFFFFFF, { |
| 10 | + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, |
| 11 | + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
| 12 | + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, |
| 13 | + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
| 14 | + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, |
| 15 | + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
| 16 | + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, |
| 17 | + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
| 18 | + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, |
| 19 | + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
| 20 | + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
| 21 | + } |
18 | 22 |
|
19 | | - local function P(l)local ml,p,pl=l*8,"\128",56-(l%64) --#squish keep-eol |
20 | | - if pl<=0 then pl=pl+64 end p=p..string.rep("\0",pl-1) --#squish keep-eol |
21 | | - for i=7,0,-1 do p=p..string.char((ml>>(i*8))&0xFF)end return p end |
| 23 | + ---Right rotate a 32-bit value |
| 24 | + ---@param x number The 32-bit value to be rotated |
| 25 | + ---@param n number The number of rotations to the right that should be done |
| 26 | + ---@return number The right shifted value |
| 27 | + local function RR(x, n) |
| 28 | + return (x >> n) | ((x & M) << (32 - n)) |
| 29 | + end |
22 | 30 |
|
23 | | - local H,l={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19},0 |
24 | | - while 1 do local c=file:read(64)if not c then break end l=l+#c if #c<64 then c=c..P(l)TF(c,H)break end TF(c,H)end |
25 | | - local function h(x)return string.format("%08x",x)end |
26 | | - return table.concat({h(H[1]),h(H[2]),h(H[3]),h(H[4]),h(H[5]),h(H[6]),h(H[7]),h(H[8])}) --#squish keep-eol |
| 31 | + ---SHA-256 transformation function |
| 32 | + ---@param k string A 64-byte chunk of the message |
| 33 | + ---@param H table The current hash state (8 32-bit values) |
| 34 | + local function TF(k, H) |
| 35 | + local W = {} |
| 36 | + for i = 0, 15 do -- Convert chunk into 32-bit list |
| 37 | + local o = i * 4 + 1 |
| 38 | + W[i] = string.byte(k, o) << 24 | string.byte(k, o + 1) << 16 | string.byte(k, o + 2) << 8 | string.byte(k, o + 3) |
| 39 | + end |
| 40 | + for i = 16, 63 do -- Message expansion |
| 41 | + local s0, s1 = RR(W[i - 15], 7) ~ RR(W[i - 15], 18) ~ (W[i - 15] >> 3), RR(W[i - 2], 17) ~ RR(W[i - 2], 19) ~ (W[i - 2] >> 10) --#squish keep-eol |
| 42 | + W[i] = (W[i - 16] + s0 + W[i - 7] + s1) & M |
| 43 | + end |
| 44 | + local a, b, c, d, e, f, g, h = table.unpack(H) |
| 45 | + for i = 0, 63 do |
| 46 | + local S0, S1, ch, maj = RR(a, 2) ~ RR(a, 13) ~ RR(a, 22), RR(e, 6) ~ RR(e, 11) ~ RR(e, 25), (e & f) ~ ((~e) & g), (a & b) ~ (a & c) ~ (b & c) --#squish keep-eol |
| 47 | + local t1, t2 = (h + S1 + ch + K[i + 1] + W[i]) & M, (S0 + maj) & M |
| 48 | + h = g |
| 49 | + g = f |
| 50 | + f = e |
| 51 | + e = (d + t1) & M |
| 52 | + d = c |
| 53 | + c = b |
| 54 | + b = a |
| 55 | + a = (t1 + t2) & M |
| 56 | + end |
| 57 | + H[1] = (H[1] + a) & M |
| 58 | + H[2] = (H[2] + b) & M |
| 59 | + H[3] = (H[3] + c) & M |
| 60 | + H[4] = (H[4] + d) & M |
| 61 | + H[5] = (H[5] + e) & M |
| 62 | + H[6] = (H[6] + f) & M |
| 63 | + H[7] = (H[7] + g) & M |
| 64 | + H[8] = (H[8] + h) & M |
| 65 | + end |
| 66 | + |
| 67 | + ---Create SHA-256 padding for message |
| 68 | + ---@param l number The length of the message in bytes |
| 69 | + ---@return string The padding string to append to the message |
| 70 | + local function P(l) |
| 71 | + local ml, p, pl = l * 8, "\128", 56 - (l % 64) --#squish keep-eol |
| 72 | + if pl <= 0 then |
| 73 | + pl = pl + 64 |
| 74 | + end |
| 75 | + p = p .. string.rep("\0", pl - 1) --#squish keep-eol |
| 76 | + for i = 7, 0, -1 do |
| 77 | + p = p .. string.char((ml >> (i * 8)) & 0xFF) |
| 78 | + end |
| 79 | + return p |
| 80 | + end |
| 81 | + |
| 82 | + local H, l = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }, 0 |
| 83 | + while 1 do |
| 84 | + local c = file:read(64) |
| 85 | + if not c then |
| 86 | + break |
| 87 | + end |
| 88 | + l = l + #c |
| 89 | + if #c < 64 then |
| 90 | + c = c .. P(l) |
| 91 | + TF(c, H) |
| 92 | + break |
| 93 | + end |
| 94 | + TF(c, H) |
| 95 | + end |
| 96 | + local function h(x) |
| 97 | + return string.format("%08x", x) |
| 98 | + end |
| 99 | + return table.concat({ h(H[1]), h(H[2]), h(H[3]), h(H[4]), h(H[5]), h(H[6]), h(H[7]), h(H[8]) }) --#squish keep-eol |
| 100 | +end |
| 101 | + |
| 102 | +if LIB then |
| 103 | + return -- Don't run below code if brought in as a library |
27 | 104 | end |
28 | 105 |
|
29 | | -if LIB then return end |
30 | | -if #arg<1 then print((arg[-1] or "?").." "..(arg[0] or "?").." [FILE]...")os.exit(1) --#squish keep-eol |
31 | | -else for i=1,#arg do local f,e=io.open(arg[i],"rb") --#squish keep-eol |
32 | | - if not f then print(e)os.exit(1)end |
33 | | - local sum=sha256_file(f)f:close() --#squish keep-eol |
34 | | - if sum then print(sum.." "..arg[i])else print(arg[i]..": ".."Unknown error")os.exit(-1)end |
35 | | - end |
| 106 | +if #arg < 1 then |
| 107 | + print((arg[-1] or "?") .. " " .. (arg[0] or "?") .. " [FILE]...") |
| 108 | + os.exit(1) --#squish keep-eol |
| 109 | +else |
| 110 | + for i = 1, #arg do |
| 111 | + local f, e = io.open(arg[i], "rb") --#squish keep-eol |
| 112 | + if not f then |
| 113 | + print(e) |
| 114 | + os.exit(1) |
| 115 | + end |
| 116 | + local sum = sha256_file(f) |
| 117 | + f:close() --#squish keep-eol |
| 118 | + if sum then |
| 119 | + print(sum .. " " .. arg[i]) |
| 120 | + else |
| 121 | + print(arg[i] .. ": " .. "Unknown error") |
| 122 | + os.exit(-1) |
| 123 | + end |
| 124 | + end |
36 | 125 | end |
0 commit comments