开发者社区> 问答> 正文

函数中声明static变量能重用数据?

书上说如果向下面的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;
}

展开
收起
a123456678 2016-06-06 18:51:22 2224 0
1 条回答
写回答
取消 提交回答
  • static定义的变量属于模块级别变量,同一个模块(同一个.c文件)可以访问,并在同一个模块中是属于全部变量。变量会被放在程序的全局存储区中,而不是栈或者堆。
    如果static声明写在某个函数中,虽然它仍然是模块级别的变量,但是编译器限制了其只能有这个函数访问。注意仅仅是编译器在编译时限制,你仍然可以通过返回static变量的地址等手段,在函数外部访问。
    static的变量只会初始化一次。
    具体到你这个问题,des_main函数利用内部定义的static unsigned char subkeys16;将上一次的运算结果subkeys利用静态变量保存在程序的全局存储区中,以备后用。这种方法是合理的。

    2019-07-17 19:29:17
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载