本文主要是介绍【SHA256】sha256加解密算法源码,亲测可用,纯C跨平台,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、源码
#include "sha256.h"#define rightrotate(w, n) ((w >> n) | (w) << (32 - (n)))
#define copy_uint32(p, val) *((uint32_t *)p) = (val)static const uint32_t 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 int s_htonl(unsigned val)
{unsigned char tmp0 = val >> 0 & 0xff;unsigned char tmp1 = val >> 8 & 0xff;unsigned char tmp2 = val >> 16 & 0xff;unsigned char tmp3 = val >> 24 & 0xff;unsigned int ans = 0;ans |= tmp0 << 24;ans |= tmp1 << 16;ans |= tmp2 << 8;ans |= tmp3 << 0;return ans;
}
void sha256(const char *data, size_t len, unsigned char *out)
{uint32_t h0 = 0x6a09e667;uint32_t h1 = 0xbb67ae85;uint32_t h2 = 0x3c6ef372;uint32_t h3 = 0xa54ff53a;uint32_t h4 = 0x510e527f;uint32_t h5 = 0x9b05688c;uint32_t h6 = 0x1f83d9ab;uint32_t h7 = 0x5be0cd19;int r = (int)(len * 8 % 512);int append = ((r < 448) ? (448 - r) : (448 + 512 - r)) / 8;unsigned int new_len = len + append + 8; // ԭʼ + +64bitλ unsigned char *buf = (unsigned char *)malloc(new_len);memset(buf + len, 0, append);if (len > 0){memcpy(buf, data, len);}buf[len] = (unsigned char)0x80;uint64_t bits_len = len * 8;for (int i = 0; i < 8; i++){buf[len + append + i] = (bits_len >> ((7 - i) * 8)) & 0xff;}uint32_t w[64];memset(w, 0, 64);size_t chunk_len = new_len / 64; // 512bit for (unsigned int idx = 0; idx < chunk_len; idx++){// printf("**start idx=%d\n", idx);uint32_t val = 0;for (int i = 0; i < 64; i++){ // ֽ Ϊ16 32-bit big-endian ֣ Ϊw[0], , w[15]// printf("val figure1:i=%d val=%x \n", i, val);unsigned char buffer_data = *(buf + idx * 64 + i);unsigned int shift_number = 8 * (3 - i % 4);unsigned int fix_number = buffer_data << shift_number;// printf("val figure2:i=%d buffer_data=%c shift_number=%d fix_number=%x \n", i, buffer_data, shift_number, fix_number);val = val | fix_number;// printf("val figure3:i=%d val=%x \n", i, val);if (i % 4 == 3){w[i / 4] = val;// printf("w[i] figure:i=%d w[%d]=%x \n", i, i / 4, val);val = 0;}}for (int i = 16; i < 64; i++){ //ǰ16 ֱ Ϣ ĵ i ֽ õ µ ʽ õ uint32_t s0 = rightrotate(w[i - 15], 7) ^ rightrotate(w[i - 15], 18) ^ (w[i - 15] >> 3);uint32_t s1 = rightrotate(w[i - 2], 17) ^ rightrotate(w[i - 2], 19) ^ (w[i - 2] >> 10);w[i] = w[i - 16] + s0 + w[i - 7] + s1;}uint32_t a = h0;uint32_t b = h1;uint32_t c = h2;uint32_t d = h3;uint32_t e = h4;uint32_t f = h5;uint32_t g = h6;uint32_t h = h7;// printf("h0=%x h1=%x h2=%x h3=%x h4=%x h5=%x h6=%x h7=%x \n", h0, h1, h2, h3, h4, h5, h6, h7);for (int i = 0; i < 64; i++){ //uint32_t s_1 = rightrotate(e, 6) ^ rightrotate(e, 11) ^ rightrotate(e, 25);uint32_t ch = (e & f) ^ (~e & g);uint32_t temp1 = h + s_1 + ch + k[i] + w[i];uint32_t s_0 = rightrotate(a, 2) ^ rightrotate(a, 13) ^ rightrotate(a, 22);uint32_t maj = (a & b) ^ (a & c) ^ (b & c);uint32_t temp2 = s_0 + maj;// printf("temp1 figure:h=%x s_1=%x ch=%x w[%d]=%x\n", h, s_1, ch, i, w[i]);// printf("temp2 figure:s_0=%x maj=%x\n", s_0, maj);h = g;g = f;f = e;e = d + temp1;d = c;c = b;b = a;a = temp1 + temp2;// printf("i=%d\n", i);// printf("a=%x b=%x c=%x d=%x e=%x f=%x g=%x h=%x \n", a, b, c, d, e, f, g, h);}h0 += a;h1 += b;h2 += c;h3 += d;h4 += e;h5 += f;h6 += g;h7 += h;// printf("h0=%x h1=%x h2=%x h3=%x h4=%x h5=%x h6=%x h7=%x \n", h0, h1, h2, h3, h4, h5, h6, h7);}// printf("The ho is %x\n",h0);h0 = s_htonl(h0);h1 = s_htonl(h1);h2 = s_htonl(h2);h3 = s_htonl(h3);h4 = s_htonl(h4);h5 = s_htonl(h5);h6 = s_htonl(h6);h7 = s_htonl(h7);copy_uint32(out, h0);copy_uint32(out + 1, h1);copy_uint32(out + 2, h2);copy_uint32(out + 3, h3);copy_uint32(out + 4, h4);copy_uint32(out + 5, h5);copy_uint32(out + 6, h6);copy_uint32(out + 7, h7);/*for(int i=0;i<32;i++){printf("%x",out[i]);}*/
}
啥也不用介绍了,把这代码存成c文件直接编译就能用,跟那些在线加解密工具的结果是一致的,最近在网上找了些资料,以及gpt,发现直接copy的算出来结果多少都有差异,干脆直接自己撸一套来调,这套代码中对类型和字节严格定义,即便是跨平台也可以用。
这篇关于【SHA256】sha256加解密算法源码,亲测可用,纯C跨平台的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!