SM3算法的C++实现(代码)
生活随笔
收集整理的這篇文章主要介紹了
SM3算法的C++实现(代码)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 一、SM3算法原理
- 二、SM3算法的C++代碼實現
- 三、SM3算法的實現結果(給了文檔里兩個示例的運行結果)
- 1.當輸入數據值“abc”時候的實驗結果:
- 2.當輸入數據值為“abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd”時候的實驗結果:
- 總結
一、SM3算法原理
二、SM3算法的C++代碼實現
#include <iostream> #include <string> #include <cmath> using namespace std;//二進制轉換為十六進制函數實現 string BinToHex(string str) {string hex = "";//用來存儲最后生成的十六進制數int temp = 0;//用來存儲每次四位二進制數的十進制值while (str.size() % 4 != 0) {//因為每四位二進制數就能夠成為一個十六進制數,所以將二進制數長度轉換為4的倍數str = "0" + str;//最高位添0直到長度為4的倍數即可}for (int i = 0; i < str.size(); i += 4) {temp = (str[i] - '0') * 8 + (str[i + 1] - '0') * 4 + (str[i + 2] - '0') * 2 + (str[i + 3] - '0') * 1;//判斷出4位二進制數的十進制大小為多少if (temp < 10) {//當得到的值小于10時,可以直接用0-9來代替hex += to_string(temp);}else {//當得到的值大于10時,需要進行A-F的轉換hex += 'A' + (temp - 10);}}return hex; }//十六進制轉換為二進制函數實現 string HexToBin(string str) {string bin = "";string table[16] = { "0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111" };for (int i = 0; i < str.size(); i++) {if (str[i] >= 'A'&&str[i] <= 'F') {bin += table[str[i] - 'A' + 10];}else {bin += table[str[i] - '0'];}}return bin; }//二進制轉換為十進制的函數實現 int BinToDec(string str) {int dec = 0;for (int i = 0; i < str.size(); i++) {dec += (str[i] - '0')*pow(2, str.size() - i - 1);}return dec; }//十進制轉換為二進制的函數實現 string DecToBin(int str) {string bin = "";while (str >= 1) {bin = to_string(str % 2) + bin;str = str / 2;}return bin; }//十六進制轉換為十進制的函數實現 int HexToDec(string str) {int dec = 0;for (int i = 0; i < str.size(); i++) {if (str[i] >= 'A'&&str[i] <= 'F') {dec += (str[i] - 'A' + 10)*pow(16, str.size() - i - 1);}else {dec += (str[i] - '0')*pow(16, str.size() - i - 1);}}return dec; }//十進制轉換為十六進制的函數實現 string DecToHex(int str) {string hex = "";int temp = 0;while (str >= 1) {temp = str % 16;if (temp < 10 && temp >= 0) {hex = to_string(temp) + hex;}else {hex += ('A' + (temp - 10));}str = str / 16;}return hex; }string padding(string str) {//對數據進行填充 string res = "";for (int i = 0; i < str.size(); i++) {//首先將輸入值轉換為16進制字符串res += DecToHex((int)str[i]);}cout << "輸入字符串的ASCII碼表示為:" << endl;for (int i = 0; i < res.size(); i++) {cout << res[i];if ((i + 1) % 8 == 0) {cout << " ";}if ((i + 1) % 64 == 0 || (i + 1) == res.size()) {cout << endl;}}cout << endl;int res_length = res.size() * 4;//記錄的長度為2進制下的長度res += "8";//在獲得的數據后面添1,在16進制下相當于是添加8while (res.size() % 128 != 112) {res += "0";//“0”數據填充}string res_len = DecToHex(res_length);//用于記錄數據長度的字符串while (res_len.size() != 16) {res_len = "0" + res_len;}res += res_len;return res; }string LeftShift(string str, int len) {//實現循環左移len位功能string res = HexToBin(str);res = res.substr(len) + res.substr(0, len);return BinToHex(res); }string XOR(string str1, string str2) {//實現異或操作string res1 = HexToBin(str1);string res2 = HexToBin(str2);string res = "";for (int i = 0; i < res1.size(); i++) {if (res1[i] == res2[i]) {res += "0";}else {res += "1";}}return BinToHex(res); }string AND(string str1, string str2) {//實現與操作string res1 = HexToBin(str1);string res2 = HexToBin(str2);string res = "";for (int i = 0; i < res1.size(); i++) {if (res1[i] == '1' && res2[i] == '1') {res += "1";}else {res += "0";}}return BinToHex(res); }string OR(string str1, string str2) {//實現或操作string res1 = HexToBin(str1);string res2 = HexToBin(str2);string res = "";for (int i = 0; i < res1.size(); i++) {if (res1[i] == '0' && res2[i] == '0') {res += "0";}else {res += "1";}}return BinToHex(res); }string NOT(string str) {//實現非操作string res1 = HexToBin(str);string res = "";for (int i = 0; i < res1.size(); i++) {if (res1[i] == '0') {res += "1";}else {res += "0";}}return BinToHex(res); }char binXor (char str1, char str2) {//實現單比特的異或操作return str1 == str2 ? '0' : '1'; }char binAnd(char str1, char str2) {//實現單比特的與操作return (str1 == '1'&&str2 == '1') ? '1' : '0'; }string ModAdd(string str1, string str2) {//mod 2^32運算的函數實現string res1 = HexToBin(str1);string res2 = HexToBin(str2);char temp = '0';string res = "";for (int i = res1.size() - 1; i >= 0; i--) {res = binXor(binXor(res1[i], res2[i]), temp) + res;if (binAnd(res1[i], res2[i]) == '1') {temp = '1';}else {if (binXor(res1[i], res2[i]) == '1') {temp = binAnd('1', temp);}else {temp = '0';}}}return BinToHex(res); }string P1(string str) {//實現置換功能P1(X)return XOR(XOR(str, LeftShift(str, 15)), LeftShift(str, 23)); }string P0(string str) {//實現置換功能P0(X)return XOR(XOR(str, LeftShift(str, 9)), LeftShift(str, 17)); }string T(int j) {//返回Tj常量值的函數實現if (0 <= j && j <= 15) {return "79CC4519";}else {return "7A879D8A";} }string FF(string str1, string str2, string str3, int j) {//實現布爾函數FF功能if (0 <= j && j <= 15) {return XOR(XOR(str1, str2), str3);}else {return OR(OR(AND(str1, str2), AND(str1, str3)), AND(str2, str3));} }string GG(string str1, string str2, string str3, int j) {//實現布爾函數GG功能if (0 <= j && j <= 15) {return XOR(XOR(str1, str2), str3);}else {return OR(AND(str1, str2), AND(NOT(str1), str3));} } string extension(string str) {//消息擴展函數string res = str;//字符串類型存儲前68位存儲擴展字W值for (int i = 16; i < 68; i++) {//根據公式生成第17位到第68位的W值res += XOR(XOR(P1(XOR(XOR(res.substr((i-16)*8,8), res.substr((i - 9) * 8, 8)), LeftShift(res.substr((i - 3) * 8, 8), 15))), LeftShift(res.substr((i - 13) * 8, 8), 7)), res.substr((i - 6) * 8, 8));}cout << "擴展后的消息:" << endl;cout << "W0,W1,……,W67的消息:" << endl;for (int i = 0; i < 8; i++) {for (int j = 0; j < 8; j++) {cout << res.substr(i * 64 + j * 8, 8) << " ";}cout << endl;}cout << res.substr(512, 8) << " " << res.substr(520, 8) << " " << res.substr(528, 8) << " " << res.substr(536, 8) << endl;cout << endl;for (int i = 0; i < 64; i++) {//根據公式生成64位W'值res += XOR(res.substr(i * 8, 8), res.substr((i + 4) * 8, 8));}cout << "W0',W1',……,W63'的消息:" << endl;for (int i = 0; i < 8; i++) {for (int j = 0; j < 8; j++) {cout << res.substr(544+i * 64 + j * 8, 8) << " ";}cout << endl;}cout << endl;return res; }string compress(string str1, string str2) {//消息壓縮函數string IV = str2;string A = IV.substr(0, 8), B = IV.substr(8, 8), C = IV.substr(16, 8), D = IV.substr(24, 8), E = IV.substr(32, 8), F = IV.substr(40, 8), G = IV.substr(48, 8), H = IV.substr(56, 8);string SS1 = "", SS2 = "", TT1 = "", TT2 = "";cout << "迭代壓縮中間值: " << endl;cout << " A B C D E F G H " << endl;cout << A << " " << B << " " << C << " " << D << " " << E << " " << F << " " << G << " " << H << endl;for (int j = 0; j < 64; j++) {SS1 = LeftShift(ModAdd(ModAdd(LeftShift(A, 12), E), LeftShift(T(j), (j%32))), 7);SS2 = XOR(SS1, LeftShift(A, 12));TT1 = ModAdd(ModAdd(ModAdd(FF(A, B, C, j), D), SS2), str1.substr((j + 68) * 8, 8));TT2 = ModAdd(ModAdd(ModAdd(GG(E, F, G, j), H), SS1), str1.substr(j * 8, 8));D = C;C = LeftShift(B, 9);B = A;A = TT1;H = G;G = LeftShift(F, 19);F = E;E = P0(TT2);cout << A << " " << B << " " << C << " " << D << " " << E << " " << F << " " << G << " " << H << endl;}string res = (A + B + C + D + E + F + G + H);cout << endl;return res; }string iteration(string str) {//迭代壓縮函數實現int num = str.size() / 128;cout << "消息經過填充之后共有 " + to_string(num) + " 個消息分組。" << endl;cout << endl;string V = "7380166F4914B2B9172442D7DA8A0600A96F30BC163138AAE38DEE4DB0FB0E4E";string B = "", extensionB = "", compressB = "";for (int i = 0; i < num; i++) {cout << "第 " << to_string(i+1) << " 個消息分組:" << endl;cout << endl;B = str.substr(i * 128, 128);extensionB = extension(B);compressB = compress(extensionB, V);V = XOR(V, compressB);}return V; }int main() {//主函數string str[2];str[0] = "abc";str[1] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";for (int num = 0; num < 2; num++) {cout << "示例 " + to_string(num + 1) + " :輸入消息為字符串: " + str[num] << endl;cout << endl;string paddingValue = padding(str[num]);cout << "填充后的消息為:" << endl;for (int i = 0; i < paddingValue.size() / 64; i++) {for (int j = 0; j < 8; j++) {cout << paddingValue.substr(i * 64 + j * 8, 8) << " ";}cout << endl;}cout << endl;string result = iteration(paddingValue);cout << "雜湊值:" << endl;for (int i = 0; i < 8; i++) {cout << result.substr(i * 8, 8) << " ";}cout << endl;cout << endl;} }三、SM3算法的實現結果(給了文檔里兩個示例的運行結果)
1.當輸入數據值“abc”時候的實驗結果:
2.當輸入數據值為“abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd”時候的實驗結果:
總結
- 實現的C++代碼還有很多值得改進的地方,但是因為本人是菜鳥一只,代碼寫的略長,哈哈哈。
總結
以上是生活随笔為你收集整理的SM3算法的C++实现(代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于Matpower的电力系统潮流计算设
- 下一篇: 做游戏开发要学什么