上源码,请大人们一定帮忙看看!!!!!!!!!!!!
final class DES
{
  /* Tables defined in the Data Encryption Standard documents */  /* initial permutation IP */
  private static final int ip[] = {
      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
  };  /* final permutation IP^-1 */
  private static final int fp[] = {
      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
  };
  /* expansion operation matrix   */  private static final int ei[] = {
        32,  1,  2,  3,  4,  5,
         4,  5,  6,  7,  8,  9,
         8,  9, 10, 11, 12, 13,
        12, 13, 14, 15, 16, 17,
        16, 17, 18, 19, 20, 21,
        20, 21, 22, 23, 24, 25,
        24, 25, 26, 27, 28, 29,
        28, 29, 30, 31, 32,  1
    };
    /* permuted choice table (key) */
   private static final int pc1[] = {
        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
    };    /* number left rotations of pc1 */
    private static final int totrot[] = {
        1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
    };    /* permuted choice key (table) */
    private static final int pc2[] = {
        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
    };    /* The famous S-boxes */
    private static final int sbox[][][] =
        {
            {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
             {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
             {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
             {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
            },
            {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
             {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
             {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
             {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
            },
            {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
             {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
             {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
             {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
            },
            {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
             {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
             {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
             {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
            },
            {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
             {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
             {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
             {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
            },
            {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
             {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
             {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
             {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
            },
            {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
             {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
             {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
             {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
            },
            {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
             {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
             {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
             {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
            }
        };
    /* 32-bit permutation function P used on the output of the S-boxes */
    private static final int p32i[] = {
        16, 7, 20, 21,
        29, 12, 28, 17,
        1, 15, 23, 26,
        5, 18, 31, 10,
        2, 8, 24, 14,
        32, 27, 3, 9,
        19, 13, 30, 6,
        22, 11, 4, 25
    };
    /* End of DES-defined tables */  /**key64 saves the original 64-bit key*/
  private char[] key64 = new char[8];  /**key56 saves the compressed and extended 56-bit key,key64->key56*/
  private int[] key56;  private int[][] keys16 = new int[16][48];  /**it saves the input data*/
  private char[] sourcechar = new char[8];  /**it saves the binary matrix transformed from origin array*/
  private int[] source;  /**it saves the 0-32 bits of the source*/
  private int[] sourceLeft = new int[32];  /**it saves the 33-63 bits of the source*/
  private int[] sourceRight = new int[32];  private int[] result;  /**cryptography saves the result of the */
  private char[] resultchar = new char[8];

解决方案 »

  1.   

    /**
       * Encrypts/Decrypts plain text, this constructor collects
       *  all the parameters and makes essential transaction.
       * @param encrypt    choose to encrypt or decrypt
       * @param key        input the key
       * @param plaintext   plaintext
       */
      public DES(char[] key, char[] originchar)
      {
        setKeyAndPlaintext(key, originchar);
      }  /**
       *  use 64-bit inputted key to make 16 keys of 48-bit
       */
      private void makeKey()
      {
        int[] intKey64Temp = convert(key64);    //convert 64-bit key from char to int
        key56 = permutation(intKey64Temp, pc1); //use pc1 to permute, get 56 bit key
        intKey64Temp = null;
        int[] intKeyLeft = new int[28];
        int[] intKeyRight = new int[28];
        for(int i=0; i<28;i++)          // seperate key56 into two parts
        {
          intKeyLeft[i] = key56[i];
          intKeyRight[i] = key56[i+28];
        }
        for(int i =0; i<16;i++)   //make 16 keys
        {
          //bitwise operate
          int temp1 = intKeyLeft[0];   //save the first left bit of intKeyLeft
          int temp2 = intKeyRight[0];  //save the first left bit of intKeyRight
          for(int j=0;j<27;j++)   //shift two parts of key
          {
            intKeyLeft[j] = intKeyLeft[j+1];
            intKeyRight[j] = intKeyRight[j+1];
          }
          intKeyLeft[27] = temp1;
          intKeyRight[27] = temp2;
          if(totrot[i]==2)    //if totrot[i]==2, do shift again
          {
             temp1 = intKeyLeft[0];
             temp2 = intKeyRight[0];
             for (int j = 0; j < 27; j++)
             {
               intKeyLeft[j] = intKeyLeft[j + 1];
               intKeyRight[j] = intKeyRight[j + 1];
             }
             intKeyLeft[27] = temp1;
             intKeyRight[27] = temp2;
          }
          for(int j=0; j<28; j++)   //joint left and right parts to a key
          {
            key56[j] = intKeyLeft[j];
            key56[j+28] = intKeyRight[j];
          }
          keys16[i] = permutation(key56,pc2);
        }
      }  /**
       * This method is to do most work of encryption. 
       * @param encrypt     choose to encrypt or decrypt
       */
      public char[] excute(boolean encrypt)
      {
        initialPermutation();
        seperateSource();
        if(encrypt)
          encrypt();
        else
          decrypt();
        combineResult();
        finalPermutation();
        makeResult();
        return resultchar;
      }  /**
       * to do initial permutation
       * this is not essential part of the algorithm
       */
      private void initialPermutation()
      {
        source = permutation(source,ip);
      }  /**
       * to do final permutation
       * this is not essential part of the algorithm
       */
      private void finalPermutation() 
      {
        result = permutation(result,fp);
      }  /**
       * Do enctyption, using key 0-16
       */
      private void encrypt()
      {
        for(int i=0;i<16;i++)
          {
            f(keys16[i]);
          }
      }
      /**
       * Do decryption, using key 16-0
       */
      private void decrypt()
      {
        for(int i=15;i>=0;i--)
          f(keys16[i]);
      }  private void f(int[] key)
      {
        //extend the right part from 32bits to 48bits
        int[] extended = permutation(sourceRight,ei); 
        for(int i=0;i<key.length;i++)
          extended[i]^=key[i];
        int[] sub = new int[32];
        for(int i=0;i<8;i++)         //mapping by s-box
        {
          int row, column;
          row = extended[i*6]*2 +extended[i*6+5];
          column = extended[i*6+1]*8 + extended[i*6+2]*4
              + extended[i*6+3]*2 + extended[i*6+4];
          sub[i*4] = (sbox[i][row][column]/8)%2;
          sub[i*4+1] = (sbox[i][row][column]/4)%2;
          sub[i*4+2] = (sbox[i][row][column]/2)%2;
          sub[i*4+3] = sbox[i][row][column]%2;
        }
        sub = permutation(sub,p32i);   // P permutation
        int[] temp = new int[32];
        for(int i=0;i<32;i++)
          temp[i] = sourceLeft[i];
        for(int i=0;i<32;i++)
          sourceLeft[i] = sourceRight[i];
        for(int i=0;i<32;i++)
        {
          sourceRight[i] = temp[i]^sub[i];
        }
      }  /**
       * Convert char array/matrix to intteger array/matrix
       * <p>  char 8bit   0   1     2     3     4     5     6     7</p>
       * <p>  int[]       8*i 8*i+1 8*i+2 8*i+3 8*i+4 8*i+5 8*i+6 8*i+7</p>
       * @param ch   it's a char array(the plaintext or key input)
       * @return     bit[] has 64 or 48 members which is 1 or 0
       */
      private int[] convert(char[] ch)
      {
        int bit[] = new int[ch.length*8];
        for(int i=0;i<ch.length;i++)
        {
          int temp = (int)ch[i];
          bit[8*i] = (temp/128)%2;
          bit[8*i+1] = (temp/64)%2;
          bit[8*i+2] = (temp/32)%2;
          bit[8*i+3] = (temp/16)%2;
          bit[8*i+4] = (temp/8)%2;
          bit[8*i+5] = (temp/4)%2;
          bit[8*i+6] = (temp/2)%2;
          bit[8*i+7] =  temp%2;
        }
        return bit;
      }  /**
       * Permutation by template matrix defined at the beginning
       * @param initial    the original matrix to be transformed
       * @param perm       the mapping matrix this permutation used
       * @return           the final transformed matrix
       */
      private int[] permutation(int[] initial, int[] perm)
      {
        int[] result = new int[perm.length];
        for(int i=0; i<result.length; i++)
        {
          result[i]=initial[perm[i]-1];
        }
        return result;
      }  /**
       *  Seperate source 64bits array into 2 32bits arrays
       */
      private void seperateSource()
      {
        for(int i=0;i<32;i++)
        {
          sourceLeft[i]=source[i];
          sourceRight[i]=source[i+32];
        }
      }  /**
       *  Combine the two parts of result to a 64bits array
       */
      private void combineResult()
      {
        result = new int[64];
        for(int i=0;i<32;i++)
        {
          result[i] = sourceLeft[i];
          result[i+32] = sourceRight[i];
        }
      }  /**
       * Convert int result matrix to char array
       */
      private void makeResult()
      {
        for(int i=0;i<8;i++)
        {
          int x =
              result[8*i]*128 + result[8*i+1]*64 + result[8*i+2]*32 +
              result[8*i+3]*16 +result[8*i+4]*8 + result[8*i+5]*4 +
              result[8*i+6]*2 + result[8*i+7];
          resultchar[i]=(char)x;
        }
      }
     /**
       * Set to essential parameters of this encryotion
       * @param key              char array
       * @param originchar       plaintext or cryptography, also char array
       */
      public void setKeyAndPlaintext(char[] key, char[] originchar)
      {
        //1. chech if these two input arrays need to be paded
        if(key.length<8)               //if the key less than 64-bits
        {
          for(int i=0;i<8;i++)         //copy key
            key64[i] = key[i];
          for(int i=key.length;i<8;i++) //add bits with 1
            key64[i] = 0xF;
        }
        else                        //only copy 64 bits
        {
          for(int i=0;i<8;i++)
            key64[i] = key[i];
        }
        //2. compute 16 keys
        makeKey();
        //3. chech if the data need to be cut or.....
        if(originchar.length<=8)
        {
          sourcechar = new char[8];
          for(int i=0;i<originchar.length;i++)
            sourcechar[i] = originchar[i];
          for(int i=originchar.length;i<8;i++)
            sourcechar[i] = 0;
        }
        else
        {
          for(int i=0;i<8;i++)
            sourcechar[i] = originchar[i];
        }
        //4. convert source from char to integer
        source = convert(sourcechar);
      }  private void printMatrix(int[] data)
      {
        for(int i=0;i<(data.length/8);i++)
          {
            for(int j=0;j<8;j++)
              System.out.print(data[i*8+j]);
            System.out.print("\n");
          }
        System.out.print("\n");
      }
    }
      

  2.   

    我知道写得有点罗嗦:P
    setKeyAndPlaintext方法首先处理key和明文这两个参数,然后先做makeKey(),生成16个key
    加密基本是excute(boolean)函数调用其他的函数
    IP
    调用16次f()
    FP基本思路就是这样,和书上写得流程应该是吻合的。就是现在不知道错在哪里。
    我觉得最有可能出错的就是两个关键的方法f和makeKey,但具体不好定位,难道真的要我手算?5555555555各位大哥,救救我吧!