Code:
// sha256.cpp v2 - Compute SHA-256 checksums of filename arguments.
// Written by Matt Mahoney. Public domain.
#define _CRT_DISABLE_PERFCRIT_LOCKS
#include <stdio.h>
#include <stdint.h>
// For computing SHA-256 checksums
// http://en.wikipedia.org/wiki/SHA-2
class SHA256 {
public:
void put(int c) { // hash 1 byte
unsigned& r=w[len0>>5&15];
r=(r<<8)|(c&255);
if (!(len0+=8)) ++len1;
if ((len0&511)==0) process();
}
double size() const {return len0/8+len1*536870912.0;} // size in bytes
uint64_t usize() const {return len0/8+(uint64_t(len1)<<29);} //size in bytes
const char* result(); // get hash and reset
SHA256() {init();}
private:
void init(); // reset, but don't clear hbuf
unsigned len0, len1; // length in bits (low, high)
unsigned s[8]; // hash state
unsigned w[16]; // input buffer
char hbuf[32]; // result
void process(); // hash 1 block
};
void SHA256::init() {
len0=len1=0;
s[0]=0x6a09e667;
s[1]=0xbb67ae85;
s[2]=0x3c6ef372;
s[3]=0xa54ff53a;
s[4]=0x510e527f;
s[5]=0x9b05688c;
s[6]=0x1f83d9ab;
s[7]=0x5be0cd19;
}
void SHA256::process() {
#define ror(a,b) ((a)>>(b)|(a<<(32-(b))))
#define m(i) \
w[(i)&15]+=w[(i-7)&15] \
+(ror(w[(i-15)&15],7)^ror(w[(i-15)&15],18)^(w[(i-15)&15]>>3)) \
+(ror(w[(i-2)&15],17)^ror(w[(i-2)&15],19)^(w[(i-2)&15]>>10))
#define r(a,b,c,d,e,f,g,h,i) \
t1=ror(e,14)^e; \
t1=ror(t1,5)^e; \
h+=ror(t1,6)+((e&f)^(~e&g))+k[i]+w[(i)&15]; \
d+=h; \
t1=ror(a,9)^a; \
t1=ror(t1,11)^a; \
h+=ror(t1,2)+((a&b)^(c&(a^b)));
#define mr(a,b,c,d,e,f,g,h,i) m(i); r(a,b,c,d,e,f,g,h,i);
#define r8(i) \
r(a,b,c,d,e,f,g,h,i); \
r(h,a,b,c,d,e,f,g,i+1); \
r(g,h,a,b,c,d,e,f,i+2); \
r(f,g,h,a,b,c,d,e,i+3); \
r(e,f,g,h,a,b,c,d,i+4); \
r(d,e,f,g,h,a,b,c,i+5); \
r(c,d,e,f,g,h,a,b,i+6); \
r(b,c,d,e,f,g,h,a,i+7);
#define mr8(i) \
mr(a,b,c,d,e,f,g,h,i); \
mr(h,a,b,c,d,e,f,g,i+1); \
mr(g,h,a,b,c,d,e,f,i+2); \
mr(f,g,h,a,b,c,d,e,i+3); \
mr(e,f,g,h,a,b,c,d,i+4); \
mr(d,e,f,g,h,a,b,c,i+5); \
mr(c,d,e,f,g,h,a,b,i+6); \
mr(b,c,d,e,f,g,h,a,i+7);
static const unsigned k[64]={
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};
unsigned a=s[0];
unsigned b=s[1];
unsigned c=s[2];
unsigned d=s[3];
unsigned e=s[4];
unsigned f=s[5];
unsigned g=s[6];
unsigned h=s[7];
unsigned t1;
r8(0);
r8(8);
mr8(16);
mr8(24);
mr8(32);
mr8(40);
mr8(48);
mr8(56);
s[0]+=a;
s[1]+=b;
s[2]+=c;
s[3]+=d;
s[4]+=e;
s[5]+=f;
s[6]+=g;
s[7]+=h;
#undef mr8
#undef r8
#undef mr
#undef r
#undef m
#undef ror
};
// Return old result and start a new hash
const char* SHA256::result() {
// pad and append length
const unsigned s1=len1, s0=len0;
put(0x80);
while ((len0&511)!=448) put(0);
put(s1>>24);
put(s1>>16);
put(s1>>8);
put(s1);
put(s0>>24);
put(s0>>16);
put(s0>>8);
put(s0);
// copy s to hbuf
for (int i=0; i<8; ++i) {
hbuf[4*i]=s[i]>>24;
hbuf[4*i+1]=s[i]>>16;
hbuf[4*i+2]=s[i]>>8;
hbuf[4*i+3]=s[i];
}
// return hash prior to clearing state
init();
return hbuf;
}
int main(int argc, char** argv) {
SHA256 sha256;
for (int i=1; i<argc; ++i) {
FILE* in=fopen(argv[i], "rb");
if (!in)
perror(argv[i]);
else {
const int BUFSIZE=4096;
int n;
unsigned char buf[BUFSIZE];
while ((n=fread(buf, 1, BUFSIZE, in))>0) {
for (int i=0; i<n; ++i)
sha256.put(buf[i]);
}
fclose(in);
double sz=sha256.size();
const char* p=sha256.result();
for (int j=0; j<32; ++j) printf("%02x", p[j]&255);
printf(" %1.0f %s\n", sz, argv[i]);
}
}
return 0;
}