DES - 比特和逆的排列

时间:2012-02-07 18:48:16

标签: c bit-manipulation des

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

我想要做的是在64位块上应用初始置换和逆置换。我有64位的块,我想在数组输入中加密。根据置换表IP I,取第一个字节中的第一个比特,并将其作为置换中的第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;

}

1 个答案:

答案 0 :(得分:1)

  1. 您的排列包含1到64之间的索引,但是您使用它们的方式应该是0到63.
  2. 什么是交换?如果您置换,交换,然后置换,您就不会到达同一个地方。
  3. 您需要验证排列和反向确实是对立的。我肯定不会查看所有数字并验证它。