package com.langchao.tax.gbsk.ic ;public class DES2 {
  private byte[] result = new byte[16]; //分散密钥 /**
  * 获得加密结果
  * @return
  */
  public String getResult(){
        String tmpStr = new String();
        int tmpInt =0;
        for (int i=0; i<16; i++){
          if((int)result[i]<0){
                tmpInt = 256+(int)result[i];
          }else {
                tmpInt =(int)result[i];
          }
          tmpStr = tmpStr + (Integer.toHexString(tmpInt).length() > 1
                                                 ? Integer.toHexString(tmpInt)
                                                 : "0" + Integer.toHexString(tmpInt));
        }
        return tmpStr;
  }  /**
   * 获得解密结果
   * @return
   */
  public String getResult2() {
    String tmpStr = new String();
    int tmpInt =0;
    for (int i=0; i<8; i++){
      if((int)result[i]<0){
        tmpInt = 256+(int)result[i];
      }else {
        tmpInt =(int)result[i];
      }
      tmpStr = tmpStr + (Integer.toHexString(tmpInt).length() > 1
                         ? Integer.toHexString(tmpInt)
                         : "0" + Integer.toHexString(tmpInt));
    }
    return tmpStr;
  }  public static void main(String args[]) {
        System.out.println("key:" +"0DB01BA4F4D4AED6DDD8AD525B0F2C87" );
    DES2 des = new DES2("0DB01BA4F4D4AED6DDD8AD525B0F2C87",
                      "1234569812345678", true);
    System.out.println("result1-16:" + des.getResult());        DES2 des2 = new DES2("0DB01BA4F4D4AED6DDD8AD525B0F2C87",
                                           des.getResult(), false);
        System.out.println("result2:" + des2.getResult2());
  }
  /**
   * 推导用户卡和税控卡的各种密钥
   * @param pKey  密钥, 长度为32的字符串
   * @param pData 待加密的数据(用户卡卡号或税控卡卡号), 长度为16的字符串
   * @param t  true: 加密; false: 解密
   */
  public DES2(String pKey, String pData, boolean t) {
        byte[] key = new byte[8]; //计算的临时变量
        byte[] data = new byte[8]; //计算的临时变量    //将密钥字符串解释为16进制数存放入数组变量中
        int count = 0;
        byte[] ikey = new byte[16];  // 16个字节存放
    for (int i = 0; i < 16; i++) {
      int a = Integer.decode("0X" + pKey.substring(count, (count + 2))).
          intValue();
      ikey[i] = (byte) a;
      count = count + 2;
    }    // 将加密数据(用户卡或税控卡卡号)解释为16进制数据存放入数组变量中
    count = 0;
        byte[] idata = new byte[8]; // 8字节,存放16进制的用户卡或税控卡卡号
        for (int i = 0; i < 8; i++) {
          int a = Integer.decode("0x" + pData.substring(count, (count + 2))).
                  intValue();
          idata[i] = (byte) a;
          count = count + 2;
        }
        // 存放加密过程中的中间结果
    byte[] tmp = new byte[8];    // 创建一个基本DES对象
    Des des = new Des();
        //==================================//
        //       取分散密钥的左半不部分     //
        //==================================//    //取主密钥的左8个字节
    for (int i = 0; i < 8; i++) {
      key[i] = ikey[i];
    }    // 第一次DES运算,加密
    des.setKey(key);
    des.encode(idata, tmp, t);        // 将第一次的运算结果保存到临时变量中
        data = tmp;
    // 取主密钥的右8个字节
    for (int i = 0; i < 8; i++) {
      key[i] = ikey[i + 8];
    }        // 第二次DES运算,解密
    des.setKey(key);
    des.encode(data, tmp, !t);
        // 将第二次的运算结果保存到临时变量中
        data = tmp;    // 再次取主密钥的左8个字节
        for (int i = 0; i < 8; i++) {
          key[i] = ikey[i];
        }        // 第三次DES运算,加密
        des.setKey(key);
        des.encode(data, tmp, t);        // 将结果作为最终结果的左半部分
        for (int i = 0; i < 8; i++) {
          result[i] = tmp[i];
        }    //==================================//
    //       取分散密钥的右半部分     //
    //==================================//    //  将被加密的数据取反
    for (int i=0; i<8;i++){
            Byte bb= new Byte(idata[i]);
                idata[i] = this.getNot(bb.intValue());
    }        // 取主密钥的左8个字节
          for (int i = 0; i < 8; i++) {
                key[i] = ikey[i];
          }          // 第一次DES运算,加密
          des.setKey(key);
          des.encode(idata, tmp, t);          // 将第一次的运算结果保存到临时变量中
          data = tmp;          // 取主密钥的右8个字节
          for (int i = 0; i < 8; i++) {
                key[i] = ikey[i + 8];
          }          // 第二次DES运算,解密
          des.setKey(key);
          des.encode(data, tmp, !t);
          // 将第二次的运算结果保存到临时变量中
          data = tmp;          // 再次取主密钥的左8个字节
          for (int i = 0; i < 8; i++) {
                key[i] = ikey[i];
          }          // 第三次DES运算,加密
          des.setKey(key);
          des.encode(data, tmp, t);          // 将结果作为最终结果的左半部分
          for (int i = 0; i < 8; i++) {
                result[i+8] = tmp[i];
          }
  }  private  byte getNot(int istr){
          //将str视为16进制数进行解释
          //int istr=Integer.decode("0x"+str).intValue();
          int ii=0;
          int ww=0;
          for (int i=7;i>=0;i--){
                  int t= new Double(Math.pow(2,i)).intValue();
//   System.out.println("(istr & Math.pow(2,i)): "+ (istr & t));
//   System.out.println("(istr & Math.pow(2,i))/Math.pow(2,i): "+ (istr & t)/t);
                  ww=(istr & t)/t;
                  if (ww==1){
                          ww=0;
                  }else{
                          ww=1;
                  }
                  ii=ww*(new Double(Math.pow(2,i)).intValue())+ii;
//   System.out.println("ii2:"+ii);
          }
          return new Integer(ii).byteValue();
  }
}