// コピペ用sha1
// WTFPL or NYSL
#include <stdio.h>
void CalcSHA1(void *result, const void *message, size_t length)
{
typedef unsigned int u32;
typedef unsigned char u8;
u32 W[80] = { 0 };
u32 H [] = { 0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u, 0xC3D2E1F0u };
u32 blockCount = (length + 9) + 63 >> 6;
for (int block = 0; block < blockCount; block++)
{
// feed
{
const u8* src = static_cast <const u8*>(message);
for (int i = 0; i < 16; i++)
{
W[i] = 0;
for (int j = 0; j < 4; j++)
{
int p = block * 64 + i * 4 + j;
if (p < length) { W[i] |= src[p] << ((~j & 3) << 3); }
else if (p == length) { W[i] |= 0x80 << ((~j & 3) << 3); }
}
}
if (block == blockCount - 1)
{
W[14] = length >> 29;
W[15] = length << 3;
}
}
# define ROL(v,n) ((v)<<(n)|(v)>>(32-(n)))
# define REP(i,s,e) for (int i = (s); i < (e); i++)
# define CALCW(i) { W[i] = ROL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); }
# define ROUND(a) { T = ROL(A, 5) + E + W[i] + (a); E = D; D = C; C = ROL(B, 30); B = A; A = T; }
u32 A = H[0], B = H[1], C = H[2], D = H[3], E = H[4], T = 0;
REP(i, 16, 80) W[i] = ROL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
REP(i, 0, 20) ROUND((B & C | ~B & D) + 0x5A827999u);
REP(i, 20, 40) ROUND((B ^ C ^ D) + 0x6ED9EBA1u);
REP(i, 40, 60) ROUND((B & C | B & D | C & D) + 0x8F1BBCDCu);
REP(i, 60, 80) ROUND((B ^ C ^ D) + 0xCA62C1D6u);
H[0] += A; H[1] += B; H[2] += C; H[3] += D; H[4] += E;
}
reinterpret_cast<u32 *>(result)[0] = H[4];
reinterpret_cast<u32 *>(result)[1] = H[3];
reinterpret_cast<u32 *>(result)[2] = H[2];
reinterpret_cast<u32 *>(result)[3] = H[1];
reinterpret_cast<u32 *>(result)[4] = H[0];
}
void test(const char* text, size_t len, const char* expected)
{
unsigned char sha1[20];
CalcSHA1(sha1, text, len);
printf("result: ");
for (int i = 19; i >= 0; i--) printf("%02x", sha1[i]);
printf("\n"); \
printf("expected: %s\n", expected);
}
int main()
{
#define RUNTEST(text, expected) test(text, sizeof(text) - 1, expected)
RUNTEST("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
RUNTEST("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
RUNTEST("abcdbcdecdefdefgefghfghighijhi" "jkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
RUNTEST(
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
"01234567012345670123456701234567" "01234567012345670123456701234567"
, "dea356a2cddd90c7a7ecedc5ebb563934f460452");
}