书上说如果向下面的des main函数的const unsigned char *key参数传NULL,就能使用之前计算得到的subkeys数组,具体调用就像下面这个样子:
des_encipher(&plaintext[0], &ciphertext[0], key);//通过key计算subkeys
des_encipher(temp, &ciphertext[i], NULL);//重用上次调用创建的subkeys
我认为重用功能实现的原理是每次调用des encipher函数就会在原来声明subkeys数组的地方再次声明一次subkeys,只有这样才能重用,因为根据下面具体的函数,声明subkeys数组时是没有初始化的.我的想法对吗?总觉得这样实现重用功能很不正规.
void des_encipher(const unsigned char *plaintext, unsigned char *ciphertext,const unsigned char *key)
{
des_main(plaintext, ciphertext, key, encipher);
return;
}
上面是封装函数,下面是des main函数
全选复制放进笔记static int des_main(const unsigned char *source, unsigned char *target, const unsigned char *key, DesEorD direction)
{
static unsigned char subkeys[16][7];
unsigned char temp[8],
lkey[4],
rkey[4],
lblk[6],
rblk[6],
fblk[6],
xblk[6],
sblk;
int row,
col,
i,
j,
k,
p;
if (key != NULL)
{
memcpy(temp, key, 8);
permute(temp, DesTransform, 56);
memset(lkey, 0, 4);
memset(rkey, 0, 4);
for (j = 0; j < 28; j++)
bit_set(lkey, j, bit_get(temp, j));
for (j = 0; j < 28; j++)
bit_set(rkey, j, bit_get(temp, j + 28));
for (i = 0; i < 16; i++)
{
bit_rot_left(lkey, 28, DesRotations[i]);
bit_rot_left(rkey, 28, DesRotations[i]);
for (j = 0; j < 28; j++)
bit_set(subkeys[i], j, bit_get(lkey, j));
for (j = 0; j < 28; j++)
bit_set(subkeys[i], j + 28, bit_get(rkey, j));
permute(subkeys[i], DesPermuted, 48);
}
}
memcpy(temp, source, 8);
permute(temp, DesInitial, 64);
memcpy(lblk, &temp[0], 4);
memcpy(rblk, &temp[4], 4);
for (i = 0; i < 16; i++)
{
memcpy(fblk, rblk, 4);
permute(fblk, DesExpansion, 48);
if (direction == encipher)
{
bit_xor(fblk, subkeys[i], xblk, 48);
memcpy(fblk, xblk, 6);
}
else
{
bit_xor(fblk, subkeys[15 - i], xblk, 48);
memcpy(fblk, xblk, 6);
}
p = 0;
for (j = 0; j < 8; j++)
{
row = (bit_get(fblk, (j * 6)+0) * 2) + (bit_get(fblk, (j * 6)+5) * 1);
col = (bit_get(fblk, (j * 6)+1) * 8) + (bit_get(fblk, (j * 6)+2) * 4) +
(bit_get(fblk, (j * 6)+3) * 2) + (bit_get(fblk, (j * 6)+4) * 1);
sblk = (unsigned char)DesSbox[j][row][col];
for (k = 4; k < 8; k++)
{
bit_set(fblk, p, bit_get(&sblk, k));
p++;
}
}
permute(fblk, DesPbox, 32);
bit_xor(lblk, fblk, xblk, 32);
memcpy(lblk, rblk, 4);
memcpy(rblk, xblk, 4);
}
memcpy(&target[0], rblk, 4);
memcpy(&target[4], lblk, 4);
permute(target, DesFinal, 64);
return 0;
}
static定义的变量属于模块级别变量,同一个模块(同一个.c文件)可以访问,并在同一个模块中是属于全部变量。变量会被放在程序的全局存储区中,而不是栈或者堆。
如果static声明写在某个函数中,虽然它仍然是模块级别的变量,但是编译器限制了其只能有这个函数访问。注意仅仅是编译器在编译时限制,你仍然可以通过返回static变量的地址等手段,在函数外部访问。
static的变量只会初始化一次。
具体到你这个问题,des_main函数利用内部定义的static unsigned char subkeys16;将上一次的运算结果subkeys利用静态变量保存在程序的全局存储区中,以备后用。这种方法是合理的。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。