谁实现过DES加密算法的,帮我看看我的密码钥匙的生成有什么问题!只是生成钥匙部分

chaoplusplus 2013-07-02 09:18:39
根据用户输入的64bit初期密钥生成K1到K16,一共16个密钥。这个16个钥匙即可用来加密,也可用来解密,不过加密和解密使用的顺序不一样。

我用一个long long 数据类型来输入用户输入的初期密钥。
因为涉及到bit位的操作,我用了C++的bitset类型。
我的想法是把64bit的long long类型转换成对应的bitset类型。这样比较方便操作bit。可是bitset中01排列的顺序好像是逆序的。
比如:unsigned long a = 0x1;
bitset<32> bitvec(a);
cout<<bitvec; //打印的结果是00000000000000000000000000000001
而bitvec[0] == 1; //也就是说你用下标0访问到的打印结果的最后一位。

我要把用户输入的64bit long long数据,变成两个32bit的unsigned long 类型,再来初始化两个bitset对象。再用这两个bitset对象来生成一个64bit的bitset对象。

问题就是bitset下标是逆序,导致我混乱了。大家帮我看看,我的逻辑有什么问题。
void generate_keys(long long a)是主要函数,其他都是被它调用的。

/*
*生成加密和解密需要的16把钥匙
*/
#include "key.h"
#include <assert.h>
bitset<48> KEY[16];//钥匙

unsigned char left_shift_num[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

//置换选择表1 PC-1
unsigned char 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
};
//置换选择表2 PC-2
unsigned char 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
};

//左移bit数,c为要移动的对象,n为移动的位数(只能为1或2)
void left_shift(bitset<28> &c,unsigned char n)
{
if (1 == n)
{
int c0 = c[0];
for (int i = 0; i < 27; i++)
{
c[i] = c[i+1];
}
c[27] = c0;
}
else if (2 == n)
{
int c0 = c[0];
int c1 = c[1];
for (int i = 0; i < 26; i += 2)
{
c[i] = c[i+2];
c[i+1] = c[i+3];
}
c[26] = c0;
c[27] = c1;
}
}

//利用用户提供的key产生加密和解密用的钥匙
void generate_keys(long long a)
{
//根据用户输入的long long,得到钥匙
bitset<64> key;
get_key(a,key);
//选择置换PC-1
bitset<56> key1;
for (int i = 0; i < 56; i++)
{
key1[i] = key[63 - PC_1[i]];//因为bitset对象的下标是逆序的63~0,所以为63 - PC_1[i]
}
//cout<<"key1:"<<key1<<endl;
//将56bit分为两组
bitset<28> c;//左
bitset<28> d;//右

for (int i = 0; i < 28; i++)
{
c[i] = key1[i+28];
d[i] = key1[i];
}

//cout<<"c:"<<c<<endl<<"d:"<<d<<endl;

//重复生成加密和解密中使用的Kn
for (int j = 0; j < 16; j++)
{
//左巡回转换
left_shift(c,left_shift_num[j]);
left_shift(d,left_shift_num[j]);
//合并
bitset<56> key3;
for (int i = 0; i < 28; i++)
{
key3[i] = d[i];
key[i+28] = c[i];
}
//压缩置换PC-2

for (int i = 0; i < 48; i++)
{
KEY[j][i] = key3[56 - PC_2[i]];
}
cout<<KEY[j]<<endl;
}
}

//判断本地机器存储数据是否为大端模式
bool is_big_edian(void)
{
union
{
short s;
char c[sizeof(short)];
}un;

un.s = 0x0102;

assert(sizeof(short) == 2);

if(un.c[0] == 0x01 && un.c[1] == 0x02)
{
return true;
}
else
{
return false;
}
}

//根据用户的输入设置密钥
void get_key(long long a,bitset <64> &key)
{
union
{
long long l;
unsigned long ul[2];
}un;
un.l = a;
//cout<<"un.ul[0]=="<<un.ul[0]<<endl;
//cout<<"un.ul[1]=="<<un.ul[1]<<endl;
bitset<32> bitvec1;
bitset<32> bitvec2;
bitset<32> b1(un.ul[0]);
bitset<32> b2(un.ul[1]);

if (is_big_edian())
{
bitvec1 = b1;
bitvec2 = b2;
}
else
{
bitvec2 = b1;
bitvec1 = b2;
}

cout<<"bitvec1:"<<bitvec1<<endl;
cout<<"bitvec2:"<<bitvec2<<endl;
for (int i = 0; i < 32; i++)
{
key[i] = bitvec2[i];
key[i+32] = bitvec1[i];
}
//cout<<"key= :"<<key<<endl;
}
...全文
86 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2013-07-02
  • 打赏
  • 举报
回复
bitvec[0] 对应最低位, 怎么算逆序了...
chaoplusplus 2013-07-02
  • 打赏
  • 举报
回复
怎么没人回答呢?要不给我一个标准的生成密钥的程序,让我把输出结果对比一下 0x0f1571c947d9e859
chaoplusplus 2013-07-02
  • 打赏
  • 举报
回复
引用 2 楼 adlay 的回复:
bitvec[0] 对应最低位, 怎么算逆序了...
用cout打印出来 bitvec[0]出现在最后。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧