• Source
    1. // コピペ用sha1
    2. // WTFPL or NYSL
    3.  
    4. #include <stdio.h>
    5.  
    6. void CalcSHA1(void *result, const void *message, size_t length)
    7. {
    8. typedef unsigned int u32;
    9. typedef unsigned char u8;
    10. u32 W[80] = { 0 };
    11. u32 H [] = { 0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u, 0xC3D2E1F0u };
    12. u32 blockCount = (length + 9) + 63 >> 6;
    13.  
    14. for (int block = 0; block < blockCount; block++)
    15. {
    16. // feed
    17. {
    18. const u8* src = static_cast <const u8*>(message);
    19. for (int i = 0; i < 16; i++)
    20. {
    21. W[i] = 0;
    22. for (int j = 0; j < 4; j++)
    23. {
    24. int p = block * 64 + i * 4 + j;
    25. if (p < length) { W[i] |= src[p] << ((~j & 3) << 3); }
    26. else if (p == length) { W[i] |= 0x80 << ((~j & 3) << 3); }
    27. }
    28. }
    29.  
    30. if (block == blockCount - 1)
    31. {
    32. W[14] = length >> 29;
    33. W[15] = length << 3;
    34. }
    35. }
    36.  
    37. # define ROL(v,n) ((v)<<(n)|(v)>>(32-(n)))
    38. # define REP(i,s,e) for (int i = (s); i < (e); i++)
    39. # define CALCW(i) { W[i] = ROL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); }
    40. # define ROUND(a) { T = ROL(A, 5) + E + W[i] + (a); E = D; D = C; C = ROL(B, 30); B = A; A = T; }
    41.  
    42. u32 A = H[0], B = H[1], C = H[2], D = H[3], E = H[4], T = 0;
    43. REP(i, 16, 80) W[i] = ROL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
    44. REP(i, 0, 20) ROUND((B & C | ~B & D) + 0x5A827999u);
    45. REP(i, 20, 40) ROUND((B ^ C ^ D) + 0x6ED9EBA1u);
    46. REP(i, 40, 60) ROUND((B & C | B & D | C & D) + 0x8F1BBCDCu);
    47. REP(i, 60, 80) ROUND((B ^ C ^ D) + 0xCA62C1D6u);
    48. H[0] += A; H[1] += B; H[2] += C; H[3] += D; H[4] += E;
    49. }
    50.  
    51. reinterpret_cast<u32 *>(result)[0] = H[4];
    52. reinterpret_cast<u32 *>(result)[1] = H[3];
    53. reinterpret_cast<u32 *>(result)[2] = H[2];
    54. reinterpret_cast<u32 *>(result)[3] = H[1];
    55. reinterpret_cast<u32 *>(result)[4] = H[0];
    56. }
    57.  
    58. void test(const char* text, size_t len, const char* expected)
    59. {
    60. unsigned char sha1[20];
    61. CalcSHA1(sha1, text, len);
    62. printf("result: ");
    63. for (int i = 19; i >= 0; i--) printf("%02x", sha1[i]);
    64. printf("\n"); \
    65. printf("expected: %s\n", expected);
    66. }
    67.  
    68. int main()
    69. {
    70. #define RUNTEST(text, expected) test(text, sizeof(text) - 1, expected)
    71.  
    72. RUNTEST("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
    73. RUNTEST("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
    74. RUNTEST("abcdbcdecdefdefgefghfghighijhi" "jkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
    75. RUNTEST(
    76. "01234567012345670123456701234567" "01234567012345670123456701234567"
    77. "01234567012345670123456701234567" "01234567012345670123456701234567"
    78. "01234567012345670123456701234567" "01234567012345670123456701234567"
    79. "01234567012345670123456701234567" "01234567012345670123456701234567"
    80. "01234567012345670123456701234567" "01234567012345670123456701234567"
    81. "01234567012345670123456701234567" "01234567012345670123456701234567"
    82. "01234567012345670123456701234567" "01234567012345670123456701234567"
    83. "01234567012345670123456701234567" "01234567012345670123456701234567"
    84. "01234567012345670123456701234567" "01234567012345670123456701234567"
    85. "01234567012345670123456701234567" "01234567012345670123456701234567"
    86. , "dea356a2cddd90c7a7ecedc5ebb563934f460452");
    87. }
    88.