sha1.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /************************************************************************/
  2. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  3. /* 模 块 名:;
  4. /* 描 述:;
  5. /*
  6. /* 版 本:[V];
  7. /* 作 者:[IT];
  8. /* 日 期:[7/11/2016];
  9. /*
  10. /*
  11. /* 注 意:;
  12. /*
  13. /* 修改记录:[IT];
  14. /* 修改日期:;
  15. /* 修改版本:;
  16. /* 修改内容:;
  17. /************************************************************************/
  18. #ifndef __SHA1_HEADER__
  19. #define __SHA1_HEADER__
  20. #include <assert.h>
  21. typedef unsigned int uint32_t;
  22. typedef unsigned long long uint64_t;
  23. // 字节序的小头和大头的问题;
  24. #define LITTLE_ENDIAN 0x0123
  25. #define BIG_ENDIAN 0x3210
  26. #ifndef BYTES_ORDER
  27. #define BYTES_ORDER LITTLE_ENDIAN
  28. #endif
  29. #ifndef SWAP_UINT16
  30. #define SWAP_UINT16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
  31. #endif
  32. #ifndef SWAP_UINT32
  33. #define SWAP_UINT32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
  34. (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
  35. #endif
  36. #ifndef SWAP_UINT64
  37. #define SWAP_UINT64(x) ((((x) & 0xff00000000000000) >> 56) | (((x) & 0x00ff000000000000) >> 40) | \
  38. (((x) & 0x0000ff0000000000) >> 24) | (((x) & 0x000000ff00000000) >> 8) | \
  39. (((x) & 0x00000000ff000000) << 8 ) | (((x) & 0x0000000000ff0000) << 24) | \
  40. (((x) & 0x000000000000ff00) << 40 ) | (((x) & 0x00000000000000ff) << 56))
  41. #endif
  42. #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))
  43. #define ROTR32(dword, n) ((dword) >> (n) ^ ((dword) << (32 - (n))))
  44. #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
  45. #define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n))))
  46. // SHA1的结果数据长度;
  47. static const size_t SHA1_HASH_SIZE = 20;
  48. // SHA1每次处理的BLOCK的大小;
  49. static const size_t SHA1_BLOCK_SIZE = 64;
  50. /************************************************************************/
  51. /* 函数:ByteTrun2Hex[7/11/2016 IT];
  52. /* 描述:将每个字节转化成由2个十六进制字符表示的字符串;
  53. /* 参数:;
  54. /* [IN] szMsg:要被转换的字节数组;
  55. /* [IN] nCount:要被转换的字节数组长度;
  56. /* [IN/OUT] szConvMsg:转换成2个十六进制字符表示的字符串;
  57. /* 返回:void;
  58. /* 注意:;
  59. /* 示例:;
  60. /*
  61. /* 修改:;
  62. /* 日期:;
  63. /* 内容:;
  64. /************************************************************************/
  65. void ByteTrun2Hex( unsigned char *szMsg, int nCount, unsigned char *szConvMsg )
  66. {
  67. unsigned char lh[2];
  68. for (int i = 0; i < nCount; i++)
  69. {
  70. lh[0] = szMsg[i] >> 4;
  71. lh[1] = szMsg[i] & 0x0f;
  72. for ( int j = 0; j < 2; j++ )
  73. {
  74. if ( lh[j] <= 9 )
  75. szConvMsg[i*2 + j] = lh[j] + '0';
  76. else
  77. {
  78. switch ( lh[j] )
  79. {
  80. case 10:
  81. szConvMsg[i*2 + j] = 'a';
  82. break;
  83. case 11:
  84. szConvMsg[i*2 + j] = 'b';
  85. break;
  86. case 12:
  87. szConvMsg[i*2 + j] = 'c';
  88. break;
  89. case 13:
  90. szConvMsg[i*2 + j] = 'd';
  91. break;
  92. case 14:
  93. szConvMsg[i*2 + j] = 'e';
  94. break;
  95. case 15:
  96. szConvMsg[i*2 + j] = 'f';
  97. break;
  98. default:
  99. break;
  100. }
  101. }
  102. }
  103. }
  104. }
  105. /************************************************************************/
  106. /* 函数:swap_uint32_memcpy[7/11/2016 IT];
  107. /* 描述:将一个(字符串)数组,拷贝到另外一个uint32_t数组,同时每个uint32_t反字节序;
  108. /* 参数:;
  109. /* [IN] :;
  110. /* [OUT] :;
  111. /* [IN/OUT] :;
  112. /* 返回:void;
  113. /* 注意:;
  114. /* 示例:;
  115. /*
  116. /* 修改:;
  117. /* 日期:;
  118. /* 内容:;
  119. /************************************************************************/
  120. void *swap_uint32_memcpy(void *to, const void *from, size_t length)
  121. {
  122. memcpy(to, from, length);
  123. size_t remain_len = (4 - (length & 3)) & 3;
  124. // 数据不是4字节的倍数,补充0;
  125. if (remain_len)
  126. {
  127. for (size_t i = 0; i < remain_len; ++i)
  128. {
  129. *((char *)(to) + length + i) = 0;
  130. }
  131. //调整成4的倍数;
  132. length += remain_len;
  133. }
  134. // 所有的数据反转;
  135. for (size_t i = 0; i < length / 4; ++i)
  136. {
  137. ((uint32_t *)to)[i] = SWAP_UINT32(((uint32_t *)to)[i]);
  138. }
  139. return to;
  140. }
  141. //SHA1算法的上下文,保存一些状态,中间数据,结果;
  142. typedef struct sha1_ctx
  143. {
  144. // 处理的数据的长度;
  145. uint64_t length_;
  146. // 还没有处理的数据长度;
  147. uint64_t unprocessed_;
  148. /* 160-bit algorithm internal hashing state */
  149. uint32_t hash_[5];
  150. } sha1_ctx;
  151. //内部函数,SHA1算法的上下文的初始化;
  152. static void sha1_init(sha1_ctx *ctx)
  153. {
  154. ctx->length_ = 0;
  155. ctx->unprocessed_ = 0;
  156. // 初始化算法的几个常量,魔术数;
  157. ctx->hash_[0] = 0x67452301;
  158. ctx->hash_[1] = 0xefcdab89;
  159. ctx->hash_[2] = 0x98badcfe;
  160. ctx->hash_[3] = 0x10325476;
  161. ctx->hash_[4] = 0xc3d2e1f0;
  162. }
  163. /************************************************************************/
  164. /* 函数:sha1_process_block[7/12/2016 IT];
  165. /* 描述:内部函数,对一个64bit内存块进行摘要(杂凑)处理;
  166. /* 参数:;
  167. /* [IN] hash:存放计算hash结果的的数组;
  168. /* [IN] block:要计算的处理得内存块;
  169. /* 返回:void;
  170. /* 注意:;
  171. /* 示例:;
  172. /*
  173. /* 修改:;
  174. /* 日期:;
  175. /* 内容:;
  176. /************************************************************************/
  177. static void sha1_process_block(uint32_t hash[5],const uint32_t block[SHA1_BLOCK_SIZE / 4])
  178. {
  179. size_t t;
  180. uint32_t wblock[80];
  181. register uint32_t a, b, c, d, e, temp;
  182. //SHA1算法处理的内部数据要求是大头党的,在小头的环境转换;
  183. #if BYTES_ORDER == LITTLE_ENDIAN
  184. swap_uint32_memcpy(wblock, block, SHA1_BLOCK_SIZE);
  185. #else
  186. ::memcpy(wblock, block, SHA1_BLOCK_SIZE);
  187. #endif
  188. //处理
  189. for (t = 16; t < 80; t++)
  190. {
  191. wblock[t] = ROTL32(wblock[t - 3] ^ wblock[t - 8] ^ wblock[t - 14] ^ wblock[t - 16], 1);
  192. }
  193. a = hash[0];
  194. b = hash[1];
  195. c = hash[2];
  196. d = hash[3];
  197. e = hash[4];
  198. for (t = 0; t < 20; t++)
  199. {
  200. /* the following is faster than ((B & C) | ((~B) & D)) */
  201. temp = ROTL32(a, 5) + (((c ^ d) & b) ^ d) + e + wblock[t] + 0x5A827999;
  202. e = d;
  203. d = c;
  204. c = ROTL32(b, 30);
  205. b = a;
  206. a = temp;
  207. }
  208. for (t = 20; t < 40; t++)
  209. {
  210. temp = ROTL32(a, 5) + (b ^ c ^ d) + e + wblock[t] + 0x6ED9EBA1;
  211. e = d;
  212. d = c;
  213. c = ROTL32(b, 30);
  214. b = a;
  215. a = temp;
  216. }
  217. for (t = 40; t < 60; t++)
  218. {
  219. temp = ROTL32(a, 5) + ((b & c) | (b & d) | (c & d)) + e + wblock[t] + 0x8F1BBCDC;
  220. e = d;
  221. d = c;
  222. c = ROTL32(b, 30);
  223. b = a;
  224. a = temp;
  225. }
  226. for (t = 60; t < 80; t++)
  227. {
  228. temp = ROTL32(a, 5) + (b ^ c ^ d) + e + wblock[t] + 0xCA62C1D6;
  229. e = d;
  230. d = c;
  231. c = ROTL32(b, 30);
  232. b = a;
  233. a = temp;
  234. }
  235. hash[0] += a;
  236. hash[1] += b;
  237. hash[2] += c;
  238. hash[3] += d;
  239. hash[4] += e;
  240. }
  241. /************************************************************************/
  242. /* 函数:sha1_update[7/12/2016 IT];
  243. /* 描述:内部函数,处理数据的前面部分(>64字节的部分),每次组成一个64字节的block就进行杂凑处理;
  244. /* 参数:;
  245. /* [IN] ctx:算法的上下文,记录中间数据,结果等;
  246. /* [IN] msg:要进行计算的数据buffer;
  247. /* [IN] size:长度;
  248. /* 返回:void;
  249. /* 注意:;
  250. /* 示例:;
  251. /*
  252. /* 修改:;
  253. /* 日期:;
  254. /* 内容:;
  255. /************************************************************************/
  256. static void sha1_update(sha1_ctx *ctx,const unsigned char *buf, size_t size)
  257. {
  258. //为了让zen_sha1_update可以多次进入,长度可以累计;
  259. ctx->length_ += size;
  260. //每个处理的块都是64字节;
  261. while (size >= SHA1_BLOCK_SIZE)
  262. {
  263. sha1_process_block(ctx->hash_, reinterpret_cast<const uint32_t *>(buf));
  264. buf += SHA1_BLOCK_SIZE;
  265. size -= SHA1_BLOCK_SIZE;
  266. }
  267. ctx->unprocessed_ = size;
  268. }
  269. /************************************************************************/
  270. /* 函数:sha1_final[7/12/2016 IT];
  271. /* 描述:内部函数,处理数据的最后部分,添加0x80,补0,增加长度信息;
  272. /* 参数:;
  273. /* [IN] ctx:算法的上下文,记录中间数据,结果等;
  274. /* [IN] msg:要进行计算的数据buffer;
  275. /* [IN] result:返回的结果;
  276. /* 返回:void;
  277. /* 注意:;
  278. /* 示例:;
  279. /*
  280. /* 修改:;
  281. /* 日期:;
  282. /* 内容:;
  283. /************************************************************************/
  284. static void sha1_final(sha1_ctx *ctx, const unsigned char *msg,size_t size, unsigned char *result)
  285. {
  286. uint32_t message[SHA1_BLOCK_SIZE / 4];
  287. //保存剩余的数据,我们要拼出最后1个(或者两个)要处理的块,前面的算法保证了,最后一个块肯定小于64个字节;
  288. if (ctx->unprocessed_)
  289. {
  290. memcpy(message, msg + size - ctx->unprocessed_, static_cast<size_t>( ctx->unprocessed_));
  291. }
  292. //得到0x80要添加在的位置(在uint32_t 数组中);
  293. uint32_t index = ((uint32_t)ctx->length_ & 63) >> 2;
  294. uint32_t shift = ((uint32_t)ctx->length_ & 3) * 8;
  295. //添加0x80进去,并且把余下的空间补充0;
  296. message[index] &= ~(0xFFFFFFFF << shift);
  297. message[index++] ^= 0x80 << shift;
  298. //如果这个block还无法处理,其后面的长度无法容纳长度64bit,那么先处理这个block;
  299. if (index > 14)
  300. {
  301. while (index < 16)
  302. {
  303. message[index++] = 0;
  304. }
  305. sha1_process_block(ctx->hash_, message);
  306. index = 0;
  307. }
  308. //补0;
  309. while (index < 14)
  310. {
  311. message[index++] = 0;
  312. }
  313. // 保存长度,注意是bit位的长度,这个问题让我看着郁闷了半天;
  314. uint64_t data_len = (ctx->length_) << 3;
  315. //注意SHA1算法要求的64bit的长度是大头BIG-ENDIAN,在小头的世界要进行转换;
  316. #if BYTES_ORDER == LITTLE_ENDIAN
  317. data_len = SWAP_UINT64(data_len);
  318. #endif
  319. message[14] = (uint32_t) (data_len & 0x00000000FFFFFFFF);
  320. message[15] = (uint32_t) ((data_len & 0xFFFFFFFF00000000ULL) >> 32);
  321. sha1_process_block(ctx->hash_, message);
  322. // 注意结果是大头党的,在小头的世界要进行转换;
  323. #if BYTES_ORDER == LITTLE_ENDIAN
  324. swap_uint32_memcpy(result, &ctx->hash_, SHA1_HASH_SIZE);
  325. #else
  326. memcpy(result, &ctx->hash_, SHA1_HASH_SIZE);
  327. #endif
  328. }
  329. /************************************************************************/
  330. /* 函数:sha1[7/12/2016 IT];
  331. /* 描述:求内存块BUFFER的SHA1值;
  332. /* 参数:;
  333. /* [IN] msg:求SHA1的内存BUFFER指针;
  334. /* [OUT] size:BUFFER长度;
  335. /* [IN/OUT] result:结果;
  336. /* 返回:void;
  337. /* 注意:;
  338. /* 示例:;
  339. /*
  340. /* 修改:;
  341. /* 日期:;
  342. /* 内容:;
  343. /************************************************************************/
  344. unsigned char *sha1(const unsigned char *msg,size_t size,unsigned char result[SHA1_HASH_SIZE])
  345. {
  346. assert(result != NULL);
  347. sha1_ctx ctx;
  348. sha1_init(&ctx);
  349. sha1_update(&ctx, msg, size);
  350. sha1_final(&ctx, msg, size, result);
  351. return result;
  352. }
  353. /************************************************************************/
  354. /* 函数:sha1Hex[7/12/2016 IT];
  355. /* 描述:求内存块BUFFER的SHA1值的十六进制字符表示的字符串值;
  356. /* 参数:;
  357. /* [IN] msg:求SHA1的内存BUFFER指针;
  358. /* [OUT] size:BUFFER长度;
  359. /* [IN/OUT] szHexResult:十六进制字符结果;
  360. /* 返回:void;
  361. /* 注意:;
  362. /* 示例:;
  363. /*
  364. /* 修改:;
  365. /* 日期:;
  366. /* 内容:;
  367. /************************************************************************/
  368. unsigned char *sha1Hex(const unsigned char *msg, size_t size, unsigned char szHexResult[41])
  369. {
  370. assert(szHexResult != NULL);
  371. sha1_ctx ctx;
  372. unsigned char result[21] = {0};
  373. sha1_init(&ctx);
  374. sha1_update(&ctx, msg, size);
  375. sha1_final(&ctx, msg, size, result);
  376. ByteTrun2Hex(result, 20, szHexResult);
  377. return szHexResult;
  378. }
  379. #endif