2

我目前正在尝试实现加密方案 DES,但我很早就遇到了问题。这是我第一次在程序中执行按位操作,而且我对 C 也不是很精通。我应用排列及其逆,结果与输入不同。

我想要做的是在 64 位块上应用初始排列和逆排列。我有我想要在数组输入中加密的 64 位块。根据排列表 IP,我取第一个字节中的第一位并将其作为排列中的第 58 位。第 2 位被发送到第 50 位,依此类推。在排列之后,结果被分成两半并交换边。这将使它能够使用相同的算法但使用 IPinverse 表放回原处。

include <stdio.h>
include <stdlib.h>

static unsigned char Positions[8] = {1,2,4,8,16,32,64,128};

int main()
{
  unsigned char input[8] = {'a','b','c','d','e','f','g','h'};
  unsigned char permutation[8];
  unsigned char inverse[8];
  int i;
  for (i = 0; i < 8; i++) {
        permutation[i] = 0;
        inverse[i] = 0;
  }

  int IP[8][8] ={{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}};

  int IPinverse[8][8] ={{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}};

  printf("\n Before: \n");
  for (i = 0; i < 8; i++) {
        printf(" %c", input[i]);
  }

  // Initial permutation
  int bit, newpos;
  unsigned char desiredbit;
  for (bit = 0; bit < 64; bit++) {
        // Get the location for where the bit will be sent and translate it to array index
        newpos = ((int)IP[bit/8][bit%8])-1;
        // examine the bit we're currently considering
        desiredbit = input[bit/8] & Positions[bit%8];
        // if equal to zero that means no change necessary
        if (desiredbit != 0) {
              // else it was a 1 and we need to set the appropriate bit to 1
              desiredbit = Positions[newpos%8];
              permutation[newpos/8] = desiredbit ^ permutation[newpos/8];
        }
  }

  printf("\n Permutation: \n");
  for (i = 0; i < 8; i++) {
        printf(" %c", permutation[i]);
  }

  // Perform swap
  unsigned char tempcopy[4] = {0,0,0,0};
  int j;
  for (j = 0; j < 4; j++) {
        tempcopy[j] = permutation[j+4];
  }
  for (j = 0; j < 4; j++) {
        permutation[j+4] = permutation[j];
        permutation[j] = tempcopy[j];
  }

  // Reverse Permutation, remember to swap left side with right
  for (bit = 0; bit < 64; bit++) {
        newpos = ((int)IPinverse[bit/8][bit%8])-1;
        desiredbit = permutation[bit/8] & Positions[bit%8];
        if (desiredbit != 0) {
              desiredbit = Positions[newpos%8];
              inverse[newpos/8] = desiredbit ^ inverse[newpos/8];
        }
  }

 printf("\n Reverse Permutation: \n");
  for (i = 0; i < 8; i++) {
        printf(" %c", inverse[i]);
  }

  return 0;

}

4

1 回答 1

1
  1. 您的排列包含从 1 到 64 的索引,但您使用它们的方式应该是 0 到 63。
  2. 交换是为了什么?如果你置换,交换,然后置换回来,你将不会到达同一个地方。
  3. 您需要验证排列和反转确实是相反的。我肯定不会检查所有数字并进行验证。
于 2012-02-07T19:05:16.533 回答