#include <iostream> #include <string.h> #include <math.h> using namespace std; #define REG_A "6A09E667F3BCC908" #define REG_B "BB67AE8584CAA73B" #define REG_C "3C6EF372FE94F82B" #define REG_D "A54FF53A5F1D36F1" #define REG_E "510E527FADE682D1" #define REG_F "9B05688C2B3E6C1F" #define REG_G "1F83D9ABFB41Bd6B" #define REG_H "5BE0CD19137E2179" char WHEXADECIMAL[80][17] = {"428a2f98d728ae22", "7137449123ef65cd", "b5c0fbcfec4d3b2f", "e9b5dba58189dbbc", "3956c25bf348b538", "59f111f1b605d019", "923f82a4af194f9b", "ab1c5ed5da6d8118", "d807aa98a3030242", "12835b0145706fbe", "243185be4ee4b28c", "550c7dc3d5ffb4e2", "72be5d74f27b896f", "80deb1fe3b1696b1", "9bdc06a725c71235", "c19bf174cf692694", "e49b69c19ef14ad2", "efbe4786384f25e3", "0fc19dc68b8cd5b5", "240ca1cc77ac9c65", "2de92c6f592b0275", "4a7484aa6ea6e483", "5cb0a9dcbd41fbd4", "76f988da831153b5", "983e5152ee66dfab", "a831c66d2db43210", "b00327c898fb213f", "bf597fc7beef0ee4", "c6e00bf33da88fc2", "d5a79147930aa725", "06ca6351e003826f", "142929670a0e6e70", "27b70a8546d22ffc", "2e1b21385c26c926", "4d2c6dfc5ac42aed", "53380d139d95b3df", "650a73548baf63de", "766a0abb3c77b2a8", "81c2c92e47edaee6", "92722c851482353b", "a2bfe8a14cf10364", "a81a664bbc423001", "c24b8b70d0f89791", "c76c51a30654be30", "d192e819d6ef5218", "d69906245565a910", "f40e35855771202a", "106aa07032bbd1b8", "19a4c116b8d2d0c8", "1e376c085141ab53", "2748774cdf8eeb99", "34b0bcb5e19b48a8", "391c0cb3c5c95a63", "4ed8aa4ae3418acb", "5b9cca4f7763e373", "682e6ff3d6b2b8a3", "748f82ee5defb2fc", "78a5636f43172f60", "84c87814a1f0ab72", "8cc702081a6439ec", "90befffa23631e28", "a4506cebde82bde9", "bef9a3f7b2c67915", "c67178f2e372532b", "ca273eceea26619c", "d186b8c721c0c207", "eada7dd6cde0eb1e", "f57d4f7fee6ed178", "06f067aa72176fba", "0a637dc5a2c898a6", "113f9804bef90dae", "1b710b35131c471b", "28db77f523047d84", "32caab7b40c72493", "3c9ebe0a15c9bebc", "431d67c49c100d4c", "4cc5d4becb3e42b6", "597f299cfc657e2a", "5fcb6fab3ad6faec", "6c44198c4a475817" }; /* 十六进制转二进制 */ string Hex2Bin(const string hex){ string binary; for(int i = 0; i < 16; i++){ if(hex[i] == '0') binary += "0000"; else if(hex[i] == '1') binary += "0001"; else if(hex[i] == '2') binary += "0010"; else if(hex[i] == '3') binary += "0011"; else if(hex[i] == '4') binary += "0100"; else if(hex[i] == '5') binary += "0101"; else if(hex[i] == '6') binary += "0110"; else if(hex[i] == '7') binary += "0111"; else if(hex[i] == '8') binary += "1000"; else if(hex[i] == '9') binary += "1001"; else if(hex[i] == 'a' || hex[i] == 'A') binary += "1010"; else if(hex[i] == 'b' || hex[i] == 'B') binary += "1011"; else if(hex[i] == 'c' || hex[i] == 'C') binary += "1100"; else if(hex[i] == 'd' || hex[i] == 'D') binary += "1101"; else if(hex[i] == 'e' || hex[i] == 'E') binary += "1110"; else if(hex[i] == 'f' || hex[i] == 'F') binary += "1111"; else return NULL; } return binary; } /* 二进制转十六进制 */ string Bin2Hex(string bin,int n){ string hex; int count = n/4; for(int i = 0; i < count; i++){ char mid[4]; for(int r = 0; r < 4; r++){ mid[r] = bin[i*4+r]; } if(strcmp(mid,"0000") == 0) hex += "0"; else if(strcmp(mid,"0001") == 0) hex += "1"; else if(strcmp(mid,"0010") == 0) hex += "2"; else if(strcmp(mid,"0011") == 0) hex += "3"; else if(strcmp(mid,"0100") == 0) hex += "4"; else if(strcmp(mid,"0101") == 0) hex += "5"; else if(strcmp(mid,"0110") == 0) hex += "6"; else if(strcmp(mid,"0111") == 0) hex += "7"; else if(strcmp(mid,"1000") == 0) hex += "8"; else if(strcmp(mid,"1001") == 0) hex += "9"; else if(strcmp(mid,"1010") == 0) hex += "a"; else if(strcmp(mid,"1011") == 0) hex += "b"; else if(strcmp(mid,"1100") == 0) hex += "c"; else if(strcmp(mid,"1101") == 0) hex += "d"; else if(strcmp(mid,"1110") == 0) hex += "e"; else if(strcmp(mid,"1111") == 0) hex += "f"; else return NULL; } return hex; } /* 十进制转二进制 */ void Dec2Bin(int Dec, string &binary){ int n = Dec,j = 0; while(n > 0){ char s[8]; sprintf(s, "%d", n%2); binary += s; n /= 2; j++; } int len = binary.length(); for(int i = 0; i < len/2; i++){ char temp = binary[i]; binary[i] = binary[len-i-1]; binary[len-i-1] = temp; } } /* 字符串转换成二进制 */ string Str2Bin(string data) { string h0; for(int i = 0; data[i]; i++){ char c = data[i]; unsigned char k = 0x80; for (int i=0; i<8; i++, k >>= 1){ if (c & k){ h0 += "1"; }else{ h0 += "0"; } } } return h0; }
sha512.cpp
#include "constant.hpp" void AddP(string &h0, int n){ h0 += "1"; for(int i = 0; i < n-1; i++){ h0 += "0"; } } /* 按位进行模2加(异或) */ string mod2(string a, string b){ string res; int len = a.length(); for(int i = 0; i < len; i++){ if(a[i] == b[i]) res += "0"; else res += "1"; } return res; } /* 补全明文内容 */ void Completion(string &h0){ int len = h0.length(); string add; /* 附加填充位 */ int remainder = h0.length()%1024; if(remainder != 896) AddP(h0, 896-remainder); else AddP(h0, 1024); /* 附加长度 */ string L; Dec2Bin(len, L); if(L.length() == 128) h0 += L; else{ for(int i = 0; i < (128-L.length()); i++) h0 += "0"; h0 += L; } } /* 初始化a,b,c,d,e,f,g,h */ void InitRegis(string &a, string &b, string &c, string &d, string &e, string &f, string &g, string &h){ a = Hex2Bin(REG_A); b = Hex2Bin(REG_B); c = Hex2Bin(REG_C); d = Hex2Bin(REG_D); e = Hex2Bin(REG_E); f = Hex2Bin(REG_F); g = Hex2Bin(REG_G); h = Hex2Bin(REG_H); } /* x循环右移n位 */ string ROTR(string x, int n){ string str1 = x.substr(0, 64-n); string str2 = x.substr(64-n, n); return str2+str1; } /* 右移n位,左边填充0 */ string SHR(string x, int n){ string str1 = x.substr(0, 64-n); string str2; for(int i = 0; i < n; i++){ str2 += "0"; } return str2+str1; } /* 模2^64位加 */ string mod2_64(string a, string b){ string res; long long int n = 0; for(long long int i=60; i>=0;i-=8){ string add; long long int fir = 0,sec = 0,left = 0; for(long long int j=0;j<4;j++,i++){ if(a[i]=='1') fir+=pow(2.0,3-j); if(b[i]=='1') sec += pow(2.0,3-j); } left = (fir+sec+n)%16; n = (fir+sec+n-left)/16; Dec2Bin(left,add); if(add.length() == 4) res = add+res; else{ long long int len = add.length(); for(long long int r = 0; r < (4-len); r++) add = "0"+add; res = add+res; } } return res; } /* 获取输入序列Wt */ void GetW(string M, int i, string* Wi){ string res,sigma1,sigma0; if(i < 16){ Wi[i] = M.substr(i*64, 64); }else{ string a = mod2(ROTR(Wi[i-2], 19), ROTR(Wi[i-2], 61)); sigma1 = mod2(a, SHR(Wi[i-2], 6)); string b = mod2(ROTR(Wi[i-15], 1), ROTR(Wi[i-15], 8)); sigma0 = mod2(b, SHR(Wi[i-15], 7)); res = mod2_64(sigma1, Wi[i-7]); string mid = mod2_64(res, sigma0); res = mod2_64(mid, Wi[i-16]); Wi[i] = res; } } /* Ch(e,f,g) */ string Ch(string e, string f, string g){ string res; int len = e.length(); for(int i = 0; i < len; i++){ if(e[i] == '1') res += f[i]; else res += g[i]; } return res; } /* Maj(a,b,c) */ string Maj(string a, string b, string c){ string res; int selection; int len = a.length(); for(int i = 0; i < len; i++){ selection = (a[i]-48) + (b[i]-48) + (c[i]-48); if(selection >= 2) res += "1"; else res += "0"; } return res; } /* 轮函数 */ void Round(string M, string &a, string &b, string &c, string &d, string &e, string &f, string &g, string &h){ string K,Sum512_1,Sum512_0,Ch_efg,Maj_abc,T1,T2,mid; string Wi[80]; /* 80轮运算模块 */ for(int j = 0; j < 80; j++){ /* T1 */ GetW(M, j, Wi); string k = WHEXADECIMAL[j]; K = Hex2Bin(k); mid = mod2(ROTR(e, 14), ROTR(e, 18)); Sum512_1 = mod2(mid, ROTR(e, 41)); mid = mod2(ROTR(a, 28), ROTR(a, 34)); Sum512_0 = mod2(mid, ROTR(a, 39)); Ch_efg = Ch(e, f, g); Maj_abc = Maj(a, b, c); T1 = mod2_64(h, Ch_efg); mid = mod2_64(T1, Sum512_1); T1 = mod2_64(mid, Wi[j]); mid = mod2_64(T1, K); T1 = mid; /* T2 */ T2 = mod2_64(Sum512_0, Maj_abc); h = g; g = f; f = e; e = mod2_64(d, T1); d = c; c = b; b = a; a = mod2_64(T1, T2); } } int main() { /* 明文 */ cout << "输入文本:" << endl; string data; cin >> data; /* 字符串模拟二进制形式 */ string h0 = Str2Bin(data); /* 补全h0 */ Completion(h0); /* 初始化abcdefgh */ string a,b,c,d,e,f,g,h; InitRegis(a,b,c,d,e,f,g,h); string H1,H2,Hi; /* 主循环次数 */ int N = h0.length()/1024; for(int i = 0; i < N; i++){ string M = h0.substr(i*1024, 1024); /* 记录H(i-1)的值 */ string A=a,B=b,C=c,D=d,E=e,F=f,G=g,H=h; Round(M,a,b,c,d,e,f,g,h); a = mod2_64(a,A); b = mod2_64(b,B); c = mod2_64(c,C); d = mod2_64(d,D); e = mod2_64(e,E); f = mod2_64(f,F); g = mod2_64(g,G); h = mod2_64(h,H); A = a; B = b; C = c; D = d; E = e; F = f; G = g; H = h; } string result = Bin2Hex(a+b+c+d+e+f+g+h,64*8); cout << "摘要结果:" << result << endl; return 0; }