DES秘钥字符互换的C++算法_获取子秘钥

该博客紧跟DES章节,介绍了应用密码学中DES子密钥替换算法。因手动进行置换工程量大,博主编写了一个C++算法,可将number字符串不断替换16次得出所有子密钥,还可将子密钥以字符串数组形式记录进行算法变换,满足了DES子密钥替换需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1

这个事紧跟着DES那个章节的贴,如果你不懂DES,还是去看看我的那一个帖子,不然不知道我算法干嘛的。。。。。
应用密码学chapter12——DES

L0=1100110 0000000 1100111 1111111 R0=1111000 1010101 1111000 1010101
L1=1001100 0000001 1001111 1111111 R1=1110001 0101011 1110001 0101011
L2=0011000 0000011 0011111 1111111 R2=1100010 1010111 1100010 1010111
L3=1100000 0001100 1111111 1111100 R3=0001010 1011111 0001010 1011111
L4=0000000 0110011 1111111 1110011 R4=0101010 1111100 0101010 1111100
L5=0000001 1001111 1111111 1001100 R5=0101011 1110001 0101011 1110001 
L6=0000110 0111111 1111110 0110000 R6=0101111 1000101 0101111 1000101 
L7=0011001 1111111 1111001 1000000 R7=0111110 0010101 0111110 0010101 
L8=1100111 1111111 1100110 0000000 R8=1111000 1010101 1111000 1010101 
L9=1001111 1111111 1001100 0000001 R9=1110001 0101011 1110001 0101011
L10=0111111 1111110 0110000 0000110 R10=1000101 0101111 1000101 0101111
L11=1111111 1111001 1000000 0011001 R11=0010101 0111110 0010101 0111110
L12=1111111 1100110 0000000 1100111 R12=1010101 1111000 1010101 1111000
L13=1111111 0011000 0000011 0011111 R13=1010111 1100010 1010111 1100010
L14=1111100 1100000 0001100 1111111 R14=1011111 0001010 1011111 0001010
L15=1110011 0000000 0110011 1111111 R15=1111100 0101010 1111100 0101010
L16=1001100 0000001 1001111 1111111 R16=1110001 0101011 1110001 0101011

这么多字符串,要按照下面的表进行置换

                              PC-2
 
                 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

工程量也太大了,我写DES那个帖子,L0R0到L16R16的循环置换,眼睛都看花了,在这么来一次,铁定要瞎掉。所以写一个c++算法,帮助我能快速得出16组子秘钥

2

#include<iostream>
#include<vector>
#include<string> 
using namespace std;

vector<int> getResult(vector<int> array,vector<int> array1){
	int i,j;
	vector<int> result(48);
	for(i=0;i<=array1.size();i++){
		result[i]=array[array1[i]];
	}
	return result;
}

int main(){
	//这里是LxRx连接而成的待转换的秘钥,由于中间没有逗号,
	//我又不想一个一个点上去,只能直接用字符串来表示。
	string number="11001100000000110011111111111111000101010111110001010101";
	
	vector<int> array(57);
	//PC-2置换表
	vector<int> array1={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};
    
    int i=0;
    for(i=0;i<number.length();i++){
    	array[i+1]=number[i]-'0';
	}
    
    vector<int> result=getResult(array,array1);
    for(i=0;i<result.size();i++){
    	cout<<result[i];
	}	
}

这个算法每次可以将number字符串不断替换,一共进行16次,就能将所有的子秘钥都弄出来了

3

想要更加方便点,可以直接将所有的子秘钥,以字符串数组的形式记录,进行算法变换。代码如下所示

#include<iostream>
#include<vector>
#include<string> 
using namespace std;

vector<int> getResult(vector<int> array,vector<int> array1){
	int i,j;
	vector<int> result(48);
	for(i=0;i<=array1.size();i++){
		result[i]=array[array1[i]];
	}
	return result;
}

vector<int> getConclusion(string a,vector<int> array1){
	int i=0;
	vector<int> array(57);
    for(i=0;i<a.length();i++){
    	array[i+1]=a[i]-'0';
	}
	vector<int> result=getResult(array,array1);
	return result;
}

int main(){
	string number[17]={"11001100000000110011111111111111000101010111110001010101",
	"10011000000001100111111111111110001010101111100010101011",
	"00110000000011001111111111111100010101011111000101010111",
	"11000000001100111111111111000001010101111100010101011111",
	"00000000110011111111111100110101010111110001010101111100",
	"00000011001111111111110011000101011111000101010111110001",
	"00001100111111111111001100000101111100010101011111000101",
	"00110011111111111100110000000111110001010101111100010101",
	"11001111111111110011000000001111000101010111110001010101",
	"10011111111111100110000000011110001010101111100010101011",
	"01111111111110011000000001101000101010111110001010101111",
	"11111111111001100000000110010010101011111000101010111110",
	"11111111100110000000011001111010101111100010101011111000",
	"11111110011000000001100111111010111110001010101111100010",
	"11111001100000000110011111111011111000101010111110001010",
	"11100110000000011001111111111111100010101011111000101010",
	"10011000000001100111111111111110001010101111100010101011"
	}; 
	vector<vector<int>> array(17);
	vector<int> array1={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};
    
    int i=0,j;
    vector<int> temp;
    temp=getConclusion(number[0],array1);
    
    for(i=0;i<17;i++){
    	temp=getConclusion(number[i],array1);
    	array[i]=temp;
	} 
    
    for(i=0;i<17;i++){
    	for(j=0;j<48;j++){
    		cout<<array[i][j];
		}
		cout<<endl;
	}	
}

程序执行图
程序这样,算是直接满足了DES的子秘钥替换算法。

密钥生成算法DES加密算法中的一个重要流程,用于生成16个48位的密钥,用于后续的轮加密操作。下面是一个简单的Python实现: ``` def generate_subkeys(key): # 生成16个48位密钥 pc1_table = [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] pc2_table = [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] shifts = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] key_bits = ''.join([f'{ord(c):08b}' for c in key]) permuted_key = ''.join([key_bits[i - 1] for i in pc1_table]) left_half = permuted_key[:28] right_half = permuted_key[28:] subkeys = [] for round_num in range(1, 17): left_half = shift_left(left_half, round_num) right_half = shift_left(right_half, round_num) shifted_key = left_half + right_half subkey = ''.join([shifted_key[i - 1] for i in pc2_table]) subkeys.append(subkey) return subkeys ``` 这段代码首先将原始密钥按照表pc1_table进行置换,得到56位的密钥。然后将56位密钥分成左右两部分,每部分28位。接下来,对左右两部分分别进行16轮循环左移,并将左右两部分合并成一个56位的密钥。最后,对56位密钥再次进行置换,得到一个48位的密钥。这样,就可以得到16个48位的密钥,用于后续的轮加密操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值