为什么我在 return 语句期间收到 Abort trap: 6 error C++
why am I getting Abort trap: 6 error C++ during return statement
我是编码新手,我需要一些帮助来了解我的 DES 加密实施可能存在的问题。我不断收到 Abort trap: 6 错误,但不确定原因。
我的尝试包括:
- 通过打印语句来确定错误。
我认为我的加密函数是罪魁祸首,因为当我 运行 其他函数单独运行时它们工作得很好。每一条语句都在加密的return函数之前执行;但是,在 return 语句之后,我得到了 abort trap: 6 错误。
'''
BEFORE ENDING TO ENCRYPT
/bin/sh: line 1: 39098 Abort trap: 6 ./DES
[Finished in 1.9s with exit code 134]
[cmd: pwd && g++ -c src/*.cpp -I /usr/local/include -I /Users/username/Desktop/coding_stuff/dev/DES/include -std=c++14 -g -Wall -m64 && g++ *.o -o bin/debug/DES -L /usr/local/lib && cd bin/debug && ./DES]
[dir: /Users/username/Desktop/coding_stuff/dev/DES]
[path: /Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands]
'''
我在 Mac OS Monterey 并且正在为我的项目使用 Sublime Text 编辑器。
如果我的代码看起来有点乱,我深表歉意,谢谢!!
我的DES.h文件
'''
#include <iostream>
#include <string>
#ifndef _DES_
#define _DES_
class DES
{
public:
DES(){}; // default constructor
std::string shiftbits(std::string bits, int n /* number of shifts*/, char dir);
std::string xOr(std::string s1, std::string s2); // does XOR of two std::strings
std::string expansion_ri(std::string s1, std::string input32bit); // expansion of 32_bit
std::string encrypt(std::string plain_txt, std::string key);
std::vector<std::string> key_sched_des(std::string key);
std::string F(std::string subkey, std::string right_block);
private:
// This is the PC_1 vector
const int pc_1[56] = { 57 ,49 ,41 ,33 ,25 ,17 ,9 ,
1 ,58 ,50 ,42 ,34 ,26 ,18 ,
10 ,2 ,59 ,51 ,43 ,35 ,27 ,
19 ,11 ,3 ,60 ,52 ,44 ,36 ,
63 ,55 ,47 ,39 ,31 ,23 ,15 ,
7 ,62 ,54 ,46 ,38 ,30 ,22 ,
14 ,6 ,61 ,53 ,45 ,37 ,29 ,
21 ,13 ,5 ,28 ,20 ,12 ,4 };
int num_leftShift[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; // number of bits to shift for each iteration
// This is the PC_2 vector that shrinks 64_bit input to 56 bits
const int pc_2[48] = { 14 ,17 ,11 ,24 ,1 ,5 ,
3 ,28 ,15 ,6 ,21 ,10 ,
23 ,19 ,12 ,4 ,26 ,8 ,
16 ,7 ,27 ,20 ,13 ,2 ,
41 ,52 ,31 ,37 ,47 ,55 ,
30 ,40 ,51 ,45 ,33 ,48 ,
44 ,49 ,39 ,56 ,34 ,53 ,
46 ,42 ,50 ,36 ,29 ,32 };
// This vector is the inital permutatinon table
const int IP_t[64] = { 58 ,50 ,42 ,34 ,26 ,18 ,10 ,2 ,
60 ,52 ,44 ,36 ,28 ,20 ,12 ,4 ,
62 ,54 ,46 ,38 ,30 ,22 ,14 ,6 ,
64 ,56 ,48 ,40 ,32 ,24 ,16 ,8 ,
57 ,49 ,41 ,33 ,25 ,17 ,9 ,1 ,
59 ,51 ,43 ,35 ,27 ,19 ,11 ,3 ,
61 ,53 ,45 ,37 ,29 ,21 ,13 ,5 ,
63 ,55 ,47 ,39 ,31 ,23 ,15 ,7 };
// expansion table for F function
const int E_t[48] = { 32 ,1 ,2 ,3 ,4 ,5 ,
4 ,5 ,6 ,7 ,8 ,9 ,
8 ,9 ,10 ,11 ,12 ,13 ,
12 ,13 ,14 ,15 ,16 ,17 ,
16 ,17 ,18 ,19 ,20 ,21 ,
20 ,21 ,22 ,23 ,24 ,25 ,
24 ,25 ,26 ,27 ,28 ,29 ,
28 ,29 ,30 ,31 ,32 ,1 };
// these are the S-boxes in a 3d array where the first value is the number of S-boxes, second is the rows and third is the columns for the S-boxes
int S[8][4][16] = { // S-box
{
{ 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7 },
{ 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8 },
{ 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0 },
{ 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 }
},
{
{ 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10 },
{ 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5 },
{ 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15 },
{ 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9 }
},
{
{ 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8 },
{ 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1 },
{ 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7 },
{ 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 }
},
{
{ 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15 },
{ 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9 },
{ 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4 },
{ 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 }
},
{
{ 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9 },
{ 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6 },
{ 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14 },
{ 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3 }
},
{
{ 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11 },
{ 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8 },
{ 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6 },
{ 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 }
},
{
{ 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1 },
{ 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6 },
{ 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2 },
{ 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 }
},
{
{ 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7 },
{ 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2 },
{ 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8 },
{ 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 }
}
};
// The permutation table for the F funciton
const int P[32] = { 16 ,7 ,20 ,21 ,
29 ,12 ,28 ,17 ,
1 ,15 ,23 ,26 ,
5 ,18 ,31 ,10 ,
2 ,8 ,24 ,14 ,
32 ,27 ,3 ,9 ,
19 ,13 ,30 ,6 ,
22 ,11 ,4 ,25 };
// This is the final permutation table for the end of the encryption/decryption
const int P_1[64] = { 40 ,8 ,48 ,16 ,56 ,24 ,64 ,32 ,
39 ,7 ,47 ,15 ,55 ,23 ,63 ,31 ,
38 ,6 ,46 ,14 ,54 ,22 ,62 ,30 ,
37 ,5 ,45 ,13 ,53 ,21 ,61 ,29 ,
36 ,4 ,44 ,12 ,52 ,20 ,60 ,28 ,
35 ,3 ,43 ,11 ,51 ,19 ,59 ,27 ,
34 ,2 ,42 ,10 ,50 ,18 ,58 ,26 ,
33 ,1 ,41 ,9 ,49 ,17 ,57 ,25 };
};
#endif
'''
这是我的DES.cpp文件
'''
#include "DES.h"
#include <vector>
#include <math.h>
#include <sstream>
int bit_to_dec(std::string num);
std::string Dec_to_Bin(int n);
std::string DES::shiftbits(std::string bits, int n, char dir)
{
std::string temp = "";
if(dir =='l') // shift to left
{
for(std::size_t i = n; i < bits.size();i++) // prints bits from n to length of std::string
temp += bits[i];
for(std::size_t i = 0; i < n;i++) // then prints from 0 to n
temp += bits[i];
} else //shift to the right
{
int diff = bits.length() - n;
//cout << diff;
for(std::size_t i = diff; i < bits.length(); i++)
temp += bits[i];
//cout << temp;
for(std::size_t i = 0; i < diff; i++)
temp += bits[i];
}
return temp;
}
std::string DES::xOr(std::string x1, std::string x2)
{
std::string Xor = "";
int bigest;
if(x1.size() > x2.size())
bigest = x1.size();
else
bigest = x2.size();
for(int i = 0; i < bigest; i++)
{
if((x2[i] == '0' && x1[i] == '1')||(x2[i] == '1' && x1[i] == '0'))
Xor += '1';
else if(x2[i] == '0' && x1[i] == '0')
Xor += '0';
else if(x2[i] == '1' && x1[i] == '1')
Xor += '0';
}
return Xor;
}
std::string DES::expansion_ri(std::string s1, std::string input32bit)
{
std::string str_temp = "";
for(int i = 0; i < 48 /*The expansion of bits*/; i++)
str_temp += input32bit[E_t[i] - 1]; // go through every bit position in table
return str_temp;
}
std::vector<std::string> DES::key_sched_des(std::string key) // key schedule for des. returns a vector of subkeys
{
std::string key64 = key;
std::string key56;
for(int i = 0; i < 56; i++)
key56 += key64[pc_1[i] - 1];
// splits key into left and right
std::string left;
for(int i = 0; i < 28; i++)
left += key56[i];
std::string right;
for(int i = 28; i < 56; i++)
right += key56[i];
// first left shift in key schedule
std::vector<std::string> lef_key(16), rig_key(16);
rig_key[0] = shiftbits(right, num_leftShift[0], 'l');
lef_key[0] = shiftbits(left, num_leftShift[0], 'l');
for(int i = 1; i < 16; i++) // fills up the keys and the bits are shifted by corresponding shift table
{
rig_key[i] = shiftbits(rig_key[i - 1], num_leftShift[i], 'l');
lef_key[i] = shiftbits(lef_key[i - 1], num_leftShift[i], 'l');
}
// merge left and right previous keys to enject into pc_2
std::vector<std::string> merge(16), subkey(16);
for(int i = 0; i < 16; i++)
{
merge[i] = "";
merge[i] += lef_key[i] + rig_key[i];
}
// permutates merged left and right boxes
for(int i = 0; i < 16; i++)
{
for(int z = 0; z < 48; z++)
{
subkey[i] += merge[i][pc_2[z] - 1];
}
}
return subkey;
}
std::string DES::F(std::string subkey, std::string right_block) //F function
{
std::string expand = "";
for(int i = 0; i < 48; i++)
expand += right_block[E_t[i] - 1];
// std::cout << "expanded right block:" << expand << std::endl;
// std::cout << "*****************************\n";
std::string exceptOR;
exceptOR = xOr(expand, subkey);
// std::cout << "xor value:" << exceptOR << std::endl;
// std::cout << "*****************************\n";
// take S box calculation by 6 bits at a time
int z = 0;
std::string comb_sbox = "";
for(int i = 0; i < 48; i += 6)
{
std::string row_bits = "";
std::string column_bits = "";
row_bits = exceptOR[i];
row_bits += exceptOR[i + 5];
for(int j = i + 1; j < i + 5; j++)
column_bits += exceptOR[j];
// std::cout << "row:" << row_bits << std::endl;
// std::cout << "*****************************\n";
// std::cout << "column:" << column_bits << std::endl;
// std::cout << "*****************************\n";
// take bits and map to each S box
int row = bit_to_dec(row_bits);
int column = bit_to_dec(column_bits);
int sbox = S[z][row][column];
// std::cout << "number:" << sbox << std::endl;
std::string sbox_bin = Dec_to_Bin(sbox);
// std::cout << sbox_bin << std::endl;
// std::cout << "*****************************\n";
// need to combine sbox values and then use permutaiton
// switch up values
comb_sbox += sbox_bin;
z++;
}
//std::cout << comb_sbox << std::endl;
std::string permutate;// permutate the Sbox combination
for(int i = 0; i < 32; i++)
permutate += comb_sbox[P[i] - 1];
return permutate;
}
std::string DES::encrypt(std::string plain_txt, std::string key)
{
// set up keys
std::vector<std::string> sub_strs;
sub_strs = key_sched_des(key);
// do inital permutations
std::string IP = "";
for (int i = 0; i < 64; i++)
IP += plain_txt[IP_t[i] - 1];
std::string left[16], right[16];
// stores bits into left and right
for(int i = 0; i < 32; i++)
{
left[0] += IP[i];
}
for(int i = 32; i < 64; i++)
{
right[0] += IP[i];
}
for(int i = 0; i < 16; i++) //16 rounds
{
std::string sub_key = F(sub_strs[i], right[i]);
right[i + 1] = xOr(left[i], sub_key); // l - 1 because previous left was used
left[i + 1] = right[i];
}
//combine the std::strings of bits into one 64 bit block
std::string combined = "";
for(int i = 0; i < 32;i++)
combined += right[15][i];
for(int i = 0; i < 32;i++)
combined += left[15][i];
//do final permutation of block
std::string final_perm = "";
for(int i = 0; i < 64; i++)
final_perm += combined[P_1[i] - 1];
std::cout << "BEFORE ENDING TO ENCRYPT" << std::endl;
return final_perm;
}
std::string Dec_to_Bin(int n)
{
std::string binary = "";
while (n > 0)
{
std::string temp;
std::stringstream tmp;
tmp << (n % 2);
tmp >> temp;
binary = temp + binary;
n /= 2;
}
while(binary.size() < 4)
binary = '0' + binary;
return binary;
}
int bit_to_dec(std::string num)
{
int sum = 0;
for(int i = 0; i < num.size(); i++)
{
int value = num.size() - 1;
value -= i;
if(num[i] == '1')
{
sum += 1 * pow(2, value);
}else // then is 0
{
sum += 0 * pow(2, value);
}
}
return sum;
}
'''
这是我的main.cpp
'''
#include <iostream>
#include <string>
#include <bitset>
#include "DES.h"
#include <vector>
#include <math.h>
using namespace std;
string txttoBits(string str); // turns string into a string of bits
int bit_to_dec(std::string num);
// This program implments the DES symmetric encryption protocol
int main()
{
DES obj;
// key needs to be 64 bits
string temp = obj.encrypt("1010101011010100000011111101000101000100100101001001000010100000", "0100111111111111000010111111011110001110101100110100000000000000");
std::cout << "AFTER ENDING OF ENCRYPT" << std::endl;
//obj.F("110101000000111111010001010001001101111101010111","00010001010111111111001010010010");
// cout << "would you like to encrypt or decrypt your text?(E for encrypt, D for Decrypt):";
// char encOrdec;
// cin >> encOrdec;
// if(encOrdec == 'E')
// {
// cout << "please enter the text you would like to Encrypt:" << endl;
// cin.ignore();
// string plain_txt;
// getline(cin, plain_txt)
// vector<string> enc_text = obj.encrypt(/*value of the string*/)
// cout << "The encrypted text is:" << enc_text[0] << endl;
// cout << "The key is:" << enc_text[1] << endl;
// }
// else if(encOrdec == 'D')
// {
// cout << "please enter the text you would like to Decrypt:" << endl;
// cin.ignore();
// string cipher_txt;
// getline(cin, cipher_txt)
// vector<string> enc_text = obj.decrypt(/*value of the string*/)
// cout << "The decrypted text is:" << enc_text[0] << endl;
// cout << "The key is:" << enc_text[1] << endl;
// }
return 0;
}
string txttoBits(string str)
{
string bitstring = "";
for(std::size_t i = 0; i < str.size(); i++)
{
bitstring += bitset<8>(str[i]).to_string();
}
return bitstring;
}
'''
对于我的主要 obj.Encrypt(),0 和 1 只是随机二进制。这只是对 64 位二进制文件和 64 位密钥的测试,以确定函数是否有效。
这里至少有一个问题。您正在此处覆盖字符串数组的边界:
std::string left[16], right[16];
//...
for (int i = 0; i < 16; i++) //16 rounds
{
std::string sub_key = F(sub_strs[i], right[i]);
right[i + 1] = xOr(left[i], sub_key); // <-- What happens when i == 15?
....
}
注释行基本上指出了问题。您正在访问 right[16]
,即 out-of-bounds。
至于 bit_to_dec
功能,可以在一行代码中完成:
#include <bitset>
//...
int bit_to_dec(std::string num)
{
return static_cast<int>(std::bitset<32>(num).to_ulong());
}
这删除了 pow()
的用法,它是一个浮点函数。如果你在一个明明都是integer-based的程序中引入浮点数,你就有引入四舍五入等浮点数问题的风险
问题是encrypt
成员内部for
循环(如下所示)的最后一次迭代(当i = 15
时)函数,您将 越界 名为 right
和 left
的 std::string
,这将导致 未定义的行为.
for(int i = 0; i < 16; i++) //16 rounds
{
std::string sub_key = F(sub_strs[i], right[i]);
right[i + 1] = xOr(left[i], sub_key); // out of bounds here on the left hand side
left[i + 1] = right[i]; //out of bound here on the left hand side
}
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.
所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。
例如,here the program executes without giving any output while here 相同的程序以您预期的输出执行。
因此,使程序正确的第一步是删除 UB(在您的情况下,这意味着注意不要超出数组的范围)。 然后并且只有那时你可以开始对程序的输出进行推理。
1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.
我是编码新手,我需要一些帮助来了解我的 DES 加密实施可能存在的问题。我不断收到 Abort trap: 6 错误,但不确定原因。
我的尝试包括: - 通过打印语句来确定错误。
我认为我的加密函数是罪魁祸首,因为当我 运行 其他函数单独运行时它们工作得很好。每一条语句都在加密的return函数之前执行;但是,在 return 语句之后,我得到了 abort trap: 6 错误。
'''
BEFORE ENDING TO ENCRYPT
/bin/sh: line 1: 39098 Abort trap: 6 ./DES
[Finished in 1.9s with exit code 134]
[cmd: pwd && g++ -c src/*.cpp -I /usr/local/include -I /Users/username/Desktop/coding_stuff/dev/DES/include -std=c++14 -g -Wall -m64 && g++ *.o -o bin/debug/DES -L /usr/local/lib && cd bin/debug && ./DES]
[dir: /Users/username/Desktop/coding_stuff/dev/DES]
[path: /Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands]
'''
我在 Mac OS Monterey 并且正在为我的项目使用 Sublime Text 编辑器。
如果我的代码看起来有点乱,我深表歉意,谢谢!!
我的DES.h文件
'''
#include <iostream>
#include <string>
#ifndef _DES_
#define _DES_
class DES
{
public:
DES(){}; // default constructor
std::string shiftbits(std::string bits, int n /* number of shifts*/, char dir);
std::string xOr(std::string s1, std::string s2); // does XOR of two std::strings
std::string expansion_ri(std::string s1, std::string input32bit); // expansion of 32_bit
std::string encrypt(std::string plain_txt, std::string key);
std::vector<std::string> key_sched_des(std::string key);
std::string F(std::string subkey, std::string right_block);
private:
// This is the PC_1 vector
const int pc_1[56] = { 57 ,49 ,41 ,33 ,25 ,17 ,9 ,
1 ,58 ,50 ,42 ,34 ,26 ,18 ,
10 ,2 ,59 ,51 ,43 ,35 ,27 ,
19 ,11 ,3 ,60 ,52 ,44 ,36 ,
63 ,55 ,47 ,39 ,31 ,23 ,15 ,
7 ,62 ,54 ,46 ,38 ,30 ,22 ,
14 ,6 ,61 ,53 ,45 ,37 ,29 ,
21 ,13 ,5 ,28 ,20 ,12 ,4 };
int num_leftShift[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; // number of bits to shift for each iteration
// This is the PC_2 vector that shrinks 64_bit input to 56 bits
const int pc_2[48] = { 14 ,17 ,11 ,24 ,1 ,5 ,
3 ,28 ,15 ,6 ,21 ,10 ,
23 ,19 ,12 ,4 ,26 ,8 ,
16 ,7 ,27 ,20 ,13 ,2 ,
41 ,52 ,31 ,37 ,47 ,55 ,
30 ,40 ,51 ,45 ,33 ,48 ,
44 ,49 ,39 ,56 ,34 ,53 ,
46 ,42 ,50 ,36 ,29 ,32 };
// This vector is the inital permutatinon table
const int IP_t[64] = { 58 ,50 ,42 ,34 ,26 ,18 ,10 ,2 ,
60 ,52 ,44 ,36 ,28 ,20 ,12 ,4 ,
62 ,54 ,46 ,38 ,30 ,22 ,14 ,6 ,
64 ,56 ,48 ,40 ,32 ,24 ,16 ,8 ,
57 ,49 ,41 ,33 ,25 ,17 ,9 ,1 ,
59 ,51 ,43 ,35 ,27 ,19 ,11 ,3 ,
61 ,53 ,45 ,37 ,29 ,21 ,13 ,5 ,
63 ,55 ,47 ,39 ,31 ,23 ,15 ,7 };
// expansion table for F function
const int E_t[48] = { 32 ,1 ,2 ,3 ,4 ,5 ,
4 ,5 ,6 ,7 ,8 ,9 ,
8 ,9 ,10 ,11 ,12 ,13 ,
12 ,13 ,14 ,15 ,16 ,17 ,
16 ,17 ,18 ,19 ,20 ,21 ,
20 ,21 ,22 ,23 ,24 ,25 ,
24 ,25 ,26 ,27 ,28 ,29 ,
28 ,29 ,30 ,31 ,32 ,1 };
// these are the S-boxes in a 3d array where the first value is the number of S-boxes, second is the rows and third is the columns for the S-boxes
int S[8][4][16] = { // S-box
{
{ 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7 },
{ 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8 },
{ 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0 },
{ 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 }
},
{
{ 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10 },
{ 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5 },
{ 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15 },
{ 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9 }
},
{
{ 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8 },
{ 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1 },
{ 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7 },
{ 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 }
},
{
{ 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15 },
{ 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9 },
{ 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4 },
{ 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 }
},
{
{ 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9 },
{ 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6 },
{ 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14 },
{ 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3 }
},
{
{ 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11 },
{ 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8 },
{ 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6 },
{ 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 }
},
{
{ 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1 },
{ 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6 },
{ 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2 },
{ 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 }
},
{
{ 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7 },
{ 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2 },
{ 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8 },
{ 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 }
}
};
// The permutation table for the F funciton
const int P[32] = { 16 ,7 ,20 ,21 ,
29 ,12 ,28 ,17 ,
1 ,15 ,23 ,26 ,
5 ,18 ,31 ,10 ,
2 ,8 ,24 ,14 ,
32 ,27 ,3 ,9 ,
19 ,13 ,30 ,6 ,
22 ,11 ,4 ,25 };
// This is the final permutation table for the end of the encryption/decryption
const int P_1[64] = { 40 ,8 ,48 ,16 ,56 ,24 ,64 ,32 ,
39 ,7 ,47 ,15 ,55 ,23 ,63 ,31 ,
38 ,6 ,46 ,14 ,54 ,22 ,62 ,30 ,
37 ,5 ,45 ,13 ,53 ,21 ,61 ,29 ,
36 ,4 ,44 ,12 ,52 ,20 ,60 ,28 ,
35 ,3 ,43 ,11 ,51 ,19 ,59 ,27 ,
34 ,2 ,42 ,10 ,50 ,18 ,58 ,26 ,
33 ,1 ,41 ,9 ,49 ,17 ,57 ,25 };
};
#endif
'''
这是我的DES.cpp文件
'''
#include "DES.h"
#include <vector>
#include <math.h>
#include <sstream>
int bit_to_dec(std::string num);
std::string Dec_to_Bin(int n);
std::string DES::shiftbits(std::string bits, int n, char dir)
{
std::string temp = "";
if(dir =='l') // shift to left
{
for(std::size_t i = n; i < bits.size();i++) // prints bits from n to length of std::string
temp += bits[i];
for(std::size_t i = 0; i < n;i++) // then prints from 0 to n
temp += bits[i];
} else //shift to the right
{
int diff = bits.length() - n;
//cout << diff;
for(std::size_t i = diff; i < bits.length(); i++)
temp += bits[i];
//cout << temp;
for(std::size_t i = 0; i < diff; i++)
temp += bits[i];
}
return temp;
}
std::string DES::xOr(std::string x1, std::string x2)
{
std::string Xor = "";
int bigest;
if(x1.size() > x2.size())
bigest = x1.size();
else
bigest = x2.size();
for(int i = 0; i < bigest; i++)
{
if((x2[i] == '0' && x1[i] == '1')||(x2[i] == '1' && x1[i] == '0'))
Xor += '1';
else if(x2[i] == '0' && x1[i] == '0')
Xor += '0';
else if(x2[i] == '1' && x1[i] == '1')
Xor += '0';
}
return Xor;
}
std::string DES::expansion_ri(std::string s1, std::string input32bit)
{
std::string str_temp = "";
for(int i = 0; i < 48 /*The expansion of bits*/; i++)
str_temp += input32bit[E_t[i] - 1]; // go through every bit position in table
return str_temp;
}
std::vector<std::string> DES::key_sched_des(std::string key) // key schedule for des. returns a vector of subkeys
{
std::string key64 = key;
std::string key56;
for(int i = 0; i < 56; i++)
key56 += key64[pc_1[i] - 1];
// splits key into left and right
std::string left;
for(int i = 0; i < 28; i++)
left += key56[i];
std::string right;
for(int i = 28; i < 56; i++)
right += key56[i];
// first left shift in key schedule
std::vector<std::string> lef_key(16), rig_key(16);
rig_key[0] = shiftbits(right, num_leftShift[0], 'l');
lef_key[0] = shiftbits(left, num_leftShift[0], 'l');
for(int i = 1; i < 16; i++) // fills up the keys and the bits are shifted by corresponding shift table
{
rig_key[i] = shiftbits(rig_key[i - 1], num_leftShift[i], 'l');
lef_key[i] = shiftbits(lef_key[i - 1], num_leftShift[i], 'l');
}
// merge left and right previous keys to enject into pc_2
std::vector<std::string> merge(16), subkey(16);
for(int i = 0; i < 16; i++)
{
merge[i] = "";
merge[i] += lef_key[i] + rig_key[i];
}
// permutates merged left and right boxes
for(int i = 0; i < 16; i++)
{
for(int z = 0; z < 48; z++)
{
subkey[i] += merge[i][pc_2[z] - 1];
}
}
return subkey;
}
std::string DES::F(std::string subkey, std::string right_block) //F function
{
std::string expand = "";
for(int i = 0; i < 48; i++)
expand += right_block[E_t[i] - 1];
// std::cout << "expanded right block:" << expand << std::endl;
// std::cout << "*****************************\n";
std::string exceptOR;
exceptOR = xOr(expand, subkey);
// std::cout << "xor value:" << exceptOR << std::endl;
// std::cout << "*****************************\n";
// take S box calculation by 6 bits at a time
int z = 0;
std::string comb_sbox = "";
for(int i = 0; i < 48; i += 6)
{
std::string row_bits = "";
std::string column_bits = "";
row_bits = exceptOR[i];
row_bits += exceptOR[i + 5];
for(int j = i + 1; j < i + 5; j++)
column_bits += exceptOR[j];
// std::cout << "row:" << row_bits << std::endl;
// std::cout << "*****************************\n";
// std::cout << "column:" << column_bits << std::endl;
// std::cout << "*****************************\n";
// take bits and map to each S box
int row = bit_to_dec(row_bits);
int column = bit_to_dec(column_bits);
int sbox = S[z][row][column];
// std::cout << "number:" << sbox << std::endl;
std::string sbox_bin = Dec_to_Bin(sbox);
// std::cout << sbox_bin << std::endl;
// std::cout << "*****************************\n";
// need to combine sbox values and then use permutaiton
// switch up values
comb_sbox += sbox_bin;
z++;
}
//std::cout << comb_sbox << std::endl;
std::string permutate;// permutate the Sbox combination
for(int i = 0; i < 32; i++)
permutate += comb_sbox[P[i] - 1];
return permutate;
}
std::string DES::encrypt(std::string plain_txt, std::string key)
{
// set up keys
std::vector<std::string> sub_strs;
sub_strs = key_sched_des(key);
// do inital permutations
std::string IP = "";
for (int i = 0; i < 64; i++)
IP += plain_txt[IP_t[i] - 1];
std::string left[16], right[16];
// stores bits into left and right
for(int i = 0; i < 32; i++)
{
left[0] += IP[i];
}
for(int i = 32; i < 64; i++)
{
right[0] += IP[i];
}
for(int i = 0; i < 16; i++) //16 rounds
{
std::string sub_key = F(sub_strs[i], right[i]);
right[i + 1] = xOr(left[i], sub_key); // l - 1 because previous left was used
left[i + 1] = right[i];
}
//combine the std::strings of bits into one 64 bit block
std::string combined = "";
for(int i = 0; i < 32;i++)
combined += right[15][i];
for(int i = 0; i < 32;i++)
combined += left[15][i];
//do final permutation of block
std::string final_perm = "";
for(int i = 0; i < 64; i++)
final_perm += combined[P_1[i] - 1];
std::cout << "BEFORE ENDING TO ENCRYPT" << std::endl;
return final_perm;
}
std::string Dec_to_Bin(int n)
{
std::string binary = "";
while (n > 0)
{
std::string temp;
std::stringstream tmp;
tmp << (n % 2);
tmp >> temp;
binary = temp + binary;
n /= 2;
}
while(binary.size() < 4)
binary = '0' + binary;
return binary;
}
int bit_to_dec(std::string num)
{
int sum = 0;
for(int i = 0; i < num.size(); i++)
{
int value = num.size() - 1;
value -= i;
if(num[i] == '1')
{
sum += 1 * pow(2, value);
}else // then is 0
{
sum += 0 * pow(2, value);
}
}
return sum;
}
'''
这是我的main.cpp
'''
#include <iostream>
#include <string>
#include <bitset>
#include "DES.h"
#include <vector>
#include <math.h>
using namespace std;
string txttoBits(string str); // turns string into a string of bits
int bit_to_dec(std::string num);
// This program implments the DES symmetric encryption protocol
int main()
{
DES obj;
// key needs to be 64 bits
string temp = obj.encrypt("1010101011010100000011111101000101000100100101001001000010100000", "0100111111111111000010111111011110001110101100110100000000000000");
std::cout << "AFTER ENDING OF ENCRYPT" << std::endl;
//obj.F("110101000000111111010001010001001101111101010111","00010001010111111111001010010010");
// cout << "would you like to encrypt or decrypt your text?(E for encrypt, D for Decrypt):";
// char encOrdec;
// cin >> encOrdec;
// if(encOrdec == 'E')
// {
// cout << "please enter the text you would like to Encrypt:" << endl;
// cin.ignore();
// string plain_txt;
// getline(cin, plain_txt)
// vector<string> enc_text = obj.encrypt(/*value of the string*/)
// cout << "The encrypted text is:" << enc_text[0] << endl;
// cout << "The key is:" << enc_text[1] << endl;
// }
// else if(encOrdec == 'D')
// {
// cout << "please enter the text you would like to Decrypt:" << endl;
// cin.ignore();
// string cipher_txt;
// getline(cin, cipher_txt)
// vector<string> enc_text = obj.decrypt(/*value of the string*/)
// cout << "The decrypted text is:" << enc_text[0] << endl;
// cout << "The key is:" << enc_text[1] << endl;
// }
return 0;
}
string txttoBits(string str)
{
string bitstring = "";
for(std::size_t i = 0; i < str.size(); i++)
{
bitstring += bitset<8>(str[i]).to_string();
}
return bitstring;
}
'''
对于我的主要 obj.Encrypt(),0 和 1 只是随机二进制。这只是对 64 位二进制文件和 64 位密钥的测试,以确定函数是否有效。
这里至少有一个问题。您正在此处覆盖字符串数组的边界:
std::string left[16], right[16];
//...
for (int i = 0; i < 16; i++) //16 rounds
{
std::string sub_key = F(sub_strs[i], right[i]);
right[i + 1] = xOr(left[i], sub_key); // <-- What happens when i == 15?
....
}
注释行基本上指出了问题。您正在访问 right[16]
,即 out-of-bounds。
至于 bit_to_dec
功能,可以在一行代码中完成:
#include <bitset>
//...
int bit_to_dec(std::string num)
{
return static_cast<int>(std::bitset<32>(num).to_ulong());
}
这删除了 pow()
的用法,它是一个浮点函数。如果你在一个明明都是integer-based的程序中引入浮点数,你就有引入四舍五入等浮点数问题的风险
问题是encrypt
成员内部for
循环(如下所示)的最后一次迭代(当i = 15
时)函数,您将 越界 名为 right
和 left
的 std::string
,这将导致 未定义的行为.
for(int i = 0; i < 16; i++) //16 rounds
{
std::string sub_key = F(sub_strs[i], right[i]);
right[i + 1] = xOr(left[i], sub_key); // out of bounds here on the left hand side
left[i + 1] = right[i]; //out of bound here on the left hand side
}
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.
所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。
例如,here the program executes without giving any output while here 相同的程序以您预期的输出执行。
因此,使程序正确的第一步是删除 UB(在您的情况下,这意味着注意不要超出数组的范围)。 然后并且只有那时你可以开始对程序的输出进行推理。
1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.