熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

JAVA編程語言開發DES算法理論

2013-11-23 19:21:03  來源: Java核心技術 

  [java]

  /**

  * DES算法理論

  本世紀五十年代以來密碼學研究領域出現了最具代表性的兩大成就其中之一就是年美國學者塔奇曼 (Tuchman)和麥耶(Meyer)根據信息論創始人香農(Shannon)提出的「多重加密有效性理論」創立的後於年由美國國家標准局頒布的數據加密標准

  DES密碼實際上是Lucifer密碼的進一步發展它是一種采用傳統加密方法的區組密碼它的算法是對稱的既可用於加密又可用於解密

  美國國家標准局年開始研究除國防部外的其它部門的計算機系統的數據加密標准日和日先後兩次向公眾發出了徵求加密算法的公告 加密算法要達到的目的通常稱為DES密碼算法要求主要為以下四點

  提供高質量的數據保護防止數據未經授權的洩露和未被察覺的修改具有相當高的復雜性使得破譯的開銷超過可能獲得的利益同時又要便於理解和掌握 DES密碼體制的安全性應該不依賴於算法的保密其安全性僅以加密密鑰的保密為基礎實現經濟運行有效並且適用於多種完全不同的應用

  美國政府頒布采納IBM公司設計的方案作為非機密數據的正式數據加密標准(DES棗Data Encryption Standard)

  目前在這裡隨著三金工程尤其是金卡工程的啟動DES算法在POSATM磁卡及智能卡(IC卡)加油站高速公路收費站等領域被廣泛應用以此來實現關鍵數據的保密如信用卡持卡人的PIN的加密傳輸IC卡與POS間的雙向認證金融交易數據包的MAC校驗等均用到DES算法

  DES算法的入口參數有三個KeyDataMode其中Key為個字節共是DES算法的工作密鑰Data也為個字節是要被加密或被解密的數據Mode為DES的工作方式有兩種加密或解密

  DES算法是這樣工作的如Mode為加密則用Key 去把數據Data進行加密 生成Data的密碼形式(位)作為DES的輸出結果如Mode為解密則用Key去把密碼形式的數據Data解密還原為Data的明碼形式(位)作為DES的輸出結果在通信網絡的兩端雙方約定一致的Key在通信的源點用Key對核心數據進行DES加密然後以密碼形式在公共通信網(如電話網)中傳輸到通信網絡的終點數據到達目的地後用同樣的Key對密碼數據進行解密便再現了明碼形式的核心數據這樣便保證了核心數據(如PINMAC等)在公共通信網中傳輸的安全性和可靠性

  通過定期在通信網絡的源端和目的端同時改用新的Key便能更進一步提高數據的保密性這正是現在金融交易網絡的流行做法

  DES算法詳述

  DES算法把位的明文輸入塊變為位的密文輸出塊它所使用的密鑰也是其功能是把輸入的位數據塊按位重新組合並把輸出分為LR兩部分每部分各長其置換規則見下表

  

  

  

  

  即將輸入的第位換到第一位位換到第依此類推最後一位是原來的第LR則是換位輸出後的兩部分L是輸出的左R 是右設置換前的輸入值為DDD……D則經過初始置換後的結果為L=D…D;R=DD…D

  經過次迭代運算後得到LR將此作為輸入進行逆置換即得到密文輸出逆置換正好是初始置的逆運算例如位經過初始置換後處於第而通過逆置換又將第位換回到第其逆置換規則如下表所示

  

  

  

  

  放大換位表

  

  

  

  單純換位表

  

  

  在f(RiKi)算法描述圖中SS…S為選擇函數其功能是把bit數據變為bit數據下面給出選擇函數Si(i=……)的功能表

  選擇函數Si

  S:

  

  

  

  

  S:

  

  

  

  

  S:

  

  

  

  

  S:

  

  

  

  

  S:

  

  

  

  

  S:

  

  

  

  

  S:

  

  

  

  

  S:

  

  

  

  

  在此以S為例說明其功能我們可以看到在S共有行數據命名為每行有命名為……

  現設輸入為 D=DDDDDD

  令列=DDDD

  行=DD

  然後在S表中查得對應的數位二進制表示此即為選擇函數S的輸出下面給出子密鑰Ki(bit)的生成算法

  從子密鑰Ki的生成算法描述圖中我們可以看到初始Key值為但DES算法規定其中第……位是奇偶校驗位不參與DES運算故Key 實際可用位數便只有經過縮小選擇換位表的變換後Key 的位數由 位變成了位分為CD兩部分然後分別進行第次循環左移得到CD將C位)D位)合並得到再經過縮小選擇換位從而便得到了密鑰K位)依此類推便可得到KK……K不過需要注意的是次循環左移對應的左移位數要依據下述規則進行

  循環左移位數

  

  以上介紹了DES算法的加密過程DES算法的解密過程是一樣的區別僅僅在於第一次迭代時用子密鑰K第二次K……最後一次用K算法本身並沒有任何變化

  DES算法具有極高安全性到目前為止除了用窮舉搜索法對DES算法進行攻擊外還沒有發現更有效的辦法位長的密鑰的窮舉空間為這意味著如果一台計算機的速度是每一秒種檢測一百萬個密鑰則它搜索完全部密鑰就需要將近年的時間可見這是難以實現的當然隨著科學技術的發展當出現超高速計算機後我們可考慮把DES密鑰的長度再增長一些以此來達到更高的保密程度

  由上述DES算法介紹我們可以看到DES算法中只用到位密鑰中的其中而第……個位並未參與DES運算這一點向我們提出了一個應用上的要求即DES的安全性是基於除了……位外的其余位的組合變化才得以保證的因此在實際應用中我們應避開使用第……位作為有效數據位而使用其它的位作為有效數據位才能保證DES算法安全可靠地發揮作用如果不了解這一點把密鑰Key的…… 位作為有效數據使用將不能保證DES加密數據的安全性對運用DES來達到保密作用的系統產生數據被破譯的危險這正是DES算法在應用上的誤區是各級技術人員各級領導在使用過程中應絕對避免的而當今各金融部門及非金融部門在運用DES工作掌握DES工作密鑰Key的領導主管們極易忽略給使用中貌似安全的系統留下了被人攻擊被人破譯的極大隱患

  DES算法應用誤區的驗證數據

  筆者用Turbo C編寫了DES算法程序並在PC機上對上述的DES 算法的應用誤區進行了骓其驗證數據如下

  Key: x x x x……x個字節)

  Data: x x x x……x個字節)

  Mode: Encryption

  結果 e a cf f

  如果把上述的Key換為個字節的x而Data和Mode均不變則執行DES 後得到的密文完全一樣類似地用Key:x和用Key:x 去加密Data (x二者的圖文輸出也是相同的e c ac e b ba

  我們可以得到出結論

  Key用x與用x是一樣的

  Key用x與用x是一樣的……

  當Key由x換成x貌似換成了新的Key但由於xx僅僅是在第……有變化而DES算法並不使用Key的第……位作為Key的有效數據位加密出的結果是一樣的

  DES解密的驗證數據

  Key: x x……xx

  Data: e a cf f

  Mode: Decryption

  結果x x……xx

  由以上看出DES算法加密與解密均工作正確唯一需要避免的是在應用中避開使用Key的第……位作為有效數據位從而便避開了DES 算法在應用中的誤區

  避開DES算法應用誤區的具體操作

  在DES密鑰Key的使用管理及密鑰更換的過程中應絕對避開DES 算法的應用誤區絕對不能把Key的第……位作為有效數據位來對Key 進行管理這一點特別推薦給金融銀行界及非金融業界的領導及決策者們尤其是負責管理密鑰的人要對此點予以高度重視有的銀行金融交易網絡利用定期更換DES密鑰Key的辦法來進一步提高系統的安全性和可靠性如果忽略了上述應用誤區那麽更換新密鑰將是徒勞的對金融交易網絡的安全運行將是十分危險的所以更換密鑰一定要保證新Key與舊Key真正的不同即除了第位外其它位數據發生了變化請務必對此保持高度重視!

  * @author zy

  */

  /**

  * 本類實現的是基本數據類型上的算法運算

  */

  public class DES {

  // 密鑰

  private String key;

  // 為了字節數組與字符串互換而使用的

  private static final String BASE_CHARS = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz*;

  private static final char[] BASE_CHARSET = BASE_CHARStoCharArray()

  // 聲明常量字節數組

  /**

  * DES算法把位的明文輸入塊變為位的密文輸出塊它所使用的密鑰也是 其功能是把輸入的位數據塊按位重新組合

  * 並把輸出分為LR兩部分每部分各長其置換規則見下表 即將輸入的第位換到第一位位換到第依此類推

  * 最後一位是原來的第LR則是換位輸出後的兩部分 L是輸出的左R 是右

  * 例設置換前的輸入值為DDD……D 則經過初始置換後的結果為L=D…D;R=DD…D

  */

  private static final int[] IP = { // OK

  

  

  

   }; //

  /**

  * 經過次迭代運算後得到LR將此作為輸入進行逆置換即得到密文輸出

  * 逆置換正好是初始置的逆運算例如位經過初始置換後處於第 而通過逆置換又將第位換回到第其逆置換規則如下表所示

  */

  private static final int[] IP_ = { // OK

  

  

  

   }; //

  /**

  * PC置換

  */

  private static final int[] PC_ = {

  

  

   }; //

  /**

  * PC置換

  */

  private static final int[] PC_ = {

  

  

   }; //

  /**

  * 放大換位表

  */

  private static final int[] E = { // OK

  

  

   }; //

  /**

  * 單純換位表

  */

  private static final int[] P = { // OK

  

   }; //

  /**

  * 在f(RiKi)算法描述圖中SS…S為選擇函數其功能是把bit數據變為bit數據

  * 下面給出選擇函數Si(i=……)的功能表選擇函數Si

  */

  private static final int[][][] S_Box = {

  {// S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } }

  { // S_Box[] OK

  { }

  { }

  { }

  { } } };

  /**

  * 循環左移位數

  */

  private static final int[] LeftMove = {

   }; // 左移位置列表

  // 構造函數初始化密鑰

  public DES(String key) {

  thiskey = key;

  }

  /**

  *

  * @param des_key

  *            個字節的密鑰字節數組

  * @param des_data

  *            個字節的數據字節數組

  * @param flag

  *            為加密為解密

  * @return 個字節的字節數組

  */

  private byte[] UnitDes(byte[] des_key byte[] des_data int flag) {

  // 檢測輸入參數格式是否正確錯誤直接返回空值(null)

  if ((des_keylength != ) || (des_datalength !=

  || ((flag != ) && (flag != ))) {

  throw new RuntimeException(Data Format Error !

  }

  int flags = flag;

  // 二進制加密數據

  int[] encryptdata = new int[];

  // 加密操作完成後的字節數組

  byte[] EncryptCode = new byte[];

  encryptdata = ReadDataToBirnaryIntArray(des_data)

  // 執行加密解密操作

  EncryptCode = Encrypt(encryptdata flags KeyArray)

  return EncryptCode;

  }

  /**

  * 初試化密鑰為二維密鑰數組

  *

  * @param key

  *            int[]二進制的密鑰數組

  * @param keyarray

  *            new int[][]

  */

  private void KeyInitialize(int[] key int[][] keyarray) {

  int i;

  int j;

  int[] K = new int[];

  // 特別注意xxx[IP[i]]等類似變換

  for (i = ; i < ; i++) {

  K[i] = key[PC_[i] ]; // 密鑰進行PC變換

  }

  for (i = ; i < ; i++) {

  LeftBitMove(K LeftMove[i])

  // 特別注意xxx[IP[i]]等類似變換

  for (j = ; j < ; j++) {

  keyarray[i][j] = K[PC_[j] ]; // 生成子密鑰keyarray[i][j]

  }

  }

  }

  /**

  * 執行加密解密操作

  *

  * @param timeData

  *            (int[])二進制加密數據

  * @param flag

  *            為加密為解密

  * @param keyarray

  *            new int[][]

  * @return 長度為的字節數組

  */

  private byte[] Encrypt(int[] timeData int flag int[][] keyarray) {

  int i;

  byte[] encrypt = new byte[];

  int flags = flag;

  int[] M = new int[];

  int[] MIP_ = new int[];

  // 特別注意xxx[IP[i]]等類似變換

  for (i = ; i < ; i++) {

  M[i] = timeData[IP[i] ]; // 明文IP變換

  }

  if (flags == ) { // 加密

  for (i = ; i < ; i++) {

  LoopF(M i flags keyarray)// S盒處理

  }

  } else if (flags == ) { // 解密

  for (i = ; i > ; i) {

  LoopF(M i flags keyarray)// S盒處理

  }

  }

  for (i = ; i < ; i++) {

  MIP_[i] = M[IP_[i] ]; // 進行IP運算

  }

  // 將(int[]二進制數據字節數組經過IPS盒IP處理後得到的新的)int[]二進制數據字節數組轉換成byte[]的字節數組

  GetEncryptResultOfByteArray(MIP_ encrypt)

  // 返回加密數據

  return encrypt;

  }

  /**

  * 轉換個字節長度的數據字節數組為二進制數組 (一個字節轉換為個二進制)

  *

  * @param intdata

  *            個字節的數據字節數組

  * @return 長度為的二進制數組

  */

  private int[] ReadDataToBirnaryIntArray(byte[] intdata) {

  int i;

  int j;

  // 將數據轉換為二進制數存儲到數組

  int[] IntDa = new int[];

  for (i = ; i < ; i++) {

  IntDa[i] = intdata[i];// intdata[i]為byte范圍是~

  if (IntDa[i] < ) {// 故IntDa[i]范圍是~

  IntDa[i] += ;// IntDa[i]永遠不會超過

  IntDa[i] %= ;// 所以該處不需要取模取模後結果還是自己

  }

  }

  int[] IntVa = new int[];

  for (i = ; i < ; i++) {

  for (j = ; j < ; j++) {

  IntVa[((i * ) + j] = IntDa[i] % ;

  IntDa[i] = IntDa[i] / ;

  }

  }

  return IntVa;

  }

  /**

  * int[]二進制數據字節數組轉換成byte[]的字節數組

  *

  * @param data

  *            int[]二進制數據字節數組

  * @param value

  *            byte[] byte[]的字節數組

  */

  private void GetEncryptResultOfByteArray(int[] data byte[] value) {

  int i;

  int j;

  // 將存儲位二進制數據的數組中的數據轉換為八個整數(byte)

  for (i = ; i < ; i++) {

  for (j = ; j < ; j++) {

  value[i] += (byte) (data[(i 《 ) + j] 《 ( j))

  }

  }

  for (i = ; i < ; i++) {

  value[i] %= ;

  if (value[i] > ) {

  value[i] = ;

  }

  }

  }

  /**

  * 左移

  *

  * @param k

  * @param offset

  */

  private void LeftBitMove(int[] k int offset) {

  int i;

  // 循環移位操作函數

  int[] c = new int[];

  int[] d = new int[];

  int[] c = new int[];

  int[] d = new int[];

  for (i = ; i < ; i++) {

  c[i] = k[i];

  d[i] = k[i + ];

  }

  if (offset == ) {

  for (i = ; i < ; i++) { // 循環左移一位

  c[i] = c[i + ];

  d[i] = d[i + ];

  }

  c[] = c[];

  d[] = d[];

  } else if (offset == ) {

  for (i = ; i < ; i++) { // 循環左移兩位

  c[i] = c[i + ];

  d[i] = d[i + ];

  }

  c[] = c[];

  d[] = d[];

  c[] = c[];

  d[] = d[];

  }

  for (i = ; i < ; i++) {

  k[i] = c[i];

  k[i + ] = d[i];

  }

  }

  /**

  * S盒處理

  *

  * @param M

  * @param times

  * @param flag

  * @param keyarray

  */

  private void LoopF(int[] M int times int flag int[][] keyarray) {

  int i;

  int j;

  int[] L = new int[];

  int[] R = new int[];

  int[] L = new int[];

  int[] R = new int[];

  int[] RE = new int[];

  int[][] S = new int[][];

  int[] sBoxData = new int[];

  int[] sValue = new int[];

  int[] RP = new int[];

  for (i = ; i < ; i++) {

  L[i] = M[i]; // 明文左側的初始化

  R[i] = M[i + ]; // 明文右側的初始化

  }

  for (i = ; i < ; i++) {

  RE[i] = R[E[i] ]; // 經過E變換擴充位變為

  RE[i] = RE[i] + keyarray[times][i]; // 與KeyArray[times][i]按位作不進位加法運算

  if (RE[i] == ) {

  RE[i] = ;

  }

  }

  for (i = ; i < ; i++) { // 位分成

  for (j = ; j < ; j++) {

  S[i][j] = RE[(i * ) + j];

  }

  // 下面經過S盒得到個數

  sBoxData[i] = S_Box[i][(S[i][] 《 ) + S[i][]][(S[i][] 《

  + (S[i][] 《 ) + (S[i][] 《 ) + S[i][]];

  // 個數變換輸出二進制

  for (j = ; j < ; j++) {

  sValue[((i * ) + j] = sBoxData[i] % ;

  sBoxData[i] = sBoxData[i] / ;

  }

  }

  for (i = ; i < ; i++) {

  RP[i] = sValue[P[i] ]; // 經過P變換

  L[i] = R[i]; // 右邊移到左邊

  R[i] = L[i] + RP[i];

  if (R[i] == ) {

  R[i] = ;

  }

  // 重新合成M返回數組M

  // 最後一次變換時左右不進行互換此處采用兩次變換實現不變

  if (((flag == ) && (times == )) || ((flag == ) && (times == ))) {

  M[i] = R[i];

  M[i + ] = L[i];

  } else {

  M[i] = L[i];

  M[i + ] = R[i];

  }

  }

  }

  /**

  * 把一個字節數組的元素拷貝到另一個字節數組中

  *

  * @param src

  * @param srcPos

  * @param dest

  * @param destPos

  * @param length

  */

  private void arraycopy(byte[] src int srcPos byte[] dest int destPos

  int length) {

  if (dest != null && src != null) {// 當兩個都不為空時

  byte[] temp = new byte[length];

  for (int i = ; i < length; i++) {

  temp[i] = src[srcPos + i];

  }

  for (int i = ; i < length; i++) {

  dest[destPos + i] = temp[i];

  }

  }

  }

  /**

  * 格式化字節數組使其的長度為的倍數那些不足的部分元素用填充

  *

  * @return 一個新的字節數組其長度比原數組長

  */

  private byte[] ByteDataFormat(byte[] data) {

  int len = datalength;

  int padlen = (len % // 要格式化的字節數組的長度與的倍數的差值

  int newlen = len + padlen;

  byte[] newdata = new byte[newlen];

  arraycopy(data newdata len)

  for (int i = len; i < newlen; i++)

  newdata[i] = ;

  return newdata;

  }

  /**

  * 加密解密(主要方法)

  *

  * @param des_key

  *            密鑰字節數組

  * @param des_data

  *            要處理的數據字節數組

  * @param flag

  *            (為加密為解密

  * @return 處理後的數據

  */

  private byte[] DesEncrypt(byte[] des_key byte[] des_data int flag) {

  byte[] format_key = ByteDataFormat(des_key)// 補齊密鑰字節數組的長度為的倍數不足元素用

  byte[] format_data = ByteDataFormat(des_data)// 補齊原始數據字節數組的長度為的倍數不足元素用

  int datalen = format_datalength;// 補齊後的原始數據字節數組的長度

  int unitcount = datalen / ;// 補齊後的原始數據字節數組長度是的多少倍

  byte[] result_data = new byte[datalen];// 用於盛放加密後的結果

  //        Logv(unitcount unitcount +

  byte[] tmpkey = new byte[];// 真正起作用的密鑰字節數組只有個字節

  arraycopy(format_key tmpkey

  byte[] tmpdata = new byte[];// 用於參與操作的數據字節數組只有個字節

  createKey(tmpkey)

  // 每一次循環都操作個字節(加密解密)

  for (int i = ; i < unitcount; i++) {

  //            if (i % ==

  //                Logv(i i +

  arraycopy(format_data i * tmpdata

  byte[] tmpresult = UnitDes(tmpkey tmpdata flag)// 執行操作

  arraycopy(tmpresult result_data i *

  }

  return result_data;

  }

  // 密鑰初試化成二維數組

  int[][] KeyArray = new int[][];

  private void createKey(byte[] des_key) {

  // 二進制加密密鑰

  int[] keydata = new int[];

  // 將密鑰字節數組轉換成二進制字節數組

  keydata = ReadDataToBirnaryIntArray(des_key)

  // 初試化密鑰為二維密鑰數組

  KeyInitialize(keydata KeyArray)

  // 將加密數據字節數組轉換成二進制字節數組

  }

  /**

  * DES加密

  *

  * @param data

  *            原始數據

  * @return 加密後的數據字節數組

  */

  public String encrypt(String data) {

  String dataLength = datalength() + ;// 原始數據長度

  String datal = dataLength;

  // 原始數據長度不滿位的加補滿

  for (int i = ; i < datallength() i++) {

  dataLength = + dataLength;

  }

  //        Systemoutprintln(dataLength = + dataLength)

  String sbDate = dataLength + data;// 保證原始數據的前位為該數據的長度

  byte[] bytekey = keygetBytes()// 密鑰字節數組

  byte[] bytedata = sbDategetBytes()// 原始數據字節數組

  byte[] result = new byte[(bytedatalength + (bytedatalength % )];// 能包含原始數據字節數組的長度是的倍數的最小字節數組

  result = DesEncrypt(bytekey bytedata

  return toBase(result)

  }

  /**

  * DES解密

  *

  * @param encryptData

  *            加密後的數據字節數組

  * @return 還原後的數據字符串

  */

  public String decrypt(String encryptData) {

  try {

  byte[] encryptByteArray = fromBase(encryptData)

  byte[] bytekey = keygetBytes()

  byte[] result = new byte[encryptByteArraylength];

  result = DesEncrypt(bytekey encryptByteArray

  String deResult = new String(result)

  int dataLength = IntegerparseInt(deResultsubstring( ))

  return deResultsubstring( dataLength +

  } catch (Exception e) {

  return ;

  }

  }

  /**

  * 字節數組轉換為字符串

  *

  * @param buffer

  * @return

  */

  private String toBase(byte[] buffer) {

  int len = bufferlength pos = len % ;

  byte b = b = b = ;

  switch (pos) {

  case :

  b = buffer[];

  break;

  case :

  b = buffer[];

  b = buffer[];

  break;

  }

  String returnValue = ;

  int c;

  boolean notleading = false;

  do {

  // c = (b & xFC) >>> ;

  c = (b & xFC) 》 ;

  if (notleading || c != ) {

  returnValue += BASE_CHARSET[c];

  notleading = true;

  }

  // c = ((b & x) 《 ) | ((b & xF) >>>

  c = ((b & x) 《 ) | ((b & xF) 》

  if (notleading || c != ) {

  returnValue += BASE_CHARSET[c];

  notleading = true;

  }

  // c = ((b & xF) 《 ) | ((b & xC) >>>

  c = ((b & xF) 《 ) | ((b & xC) 》

  if (notleading || c != ) {

  returnValue += BASE_CHARSET[c];

  notleading = true;

  }

  c = b & xF;

  if (notleading || c != ) {

  returnValue += BASE_CHARSET[c];

  notleading = true;

  }

  if (pos >= len) {

  break;

  } else {

  try {

  b = buffer[pos++];

  b = buffer[pos++];

  b = buffer[pos++];

  } catch (Exception x) {

  break;

  }

  }

  } while (true)

  if (notleading) {

  return returnValue;

  }

  return ;

  }

  /**

  * 字符串轉換為字節數組

  *

  * @param str

  * @return

  * @throws Exception

  */

  private byte[] fromBase(String str) throws Exception {

  int len = strlength()

  if (len == ) {

  throw new Exception(Empty string

  }

  byte[] a = new byte[len + ];

  int i j;

  for (i = ; i < len; i++) {

  try {

  a[i] = (byte) BASE_CHARSindexOf(strcharAt(i))

  } catch (Exception x) {

  throw new Exception(Illegal character at # + i)

  }

  }

  i = len ;

  j = len;

  try {

  while (true) {

  a[j] = a[i];

  if (i < ) {

  break;

  }

  a[j] |= (a[i] & x) 《 ;

  j;

  // a[j] = (byte)((a[i] & xC) >>>

  a[j] = (byte) ((a[i] & xC) 》

  if (i < ) {

  break;

  }

  a[j] |= (a[i] & xF) 《 ;

  j;

  // a[j] = (byte)((a[i] & x) >>>

  a[j] = (byte) ((a[i] & x) 》

  if (i < ) {

  break;

  }

  a[j] |= (a[i] 《

  j;

  a[j] = ;

  if (i < ) {

  break;

  }

  }

  } catch (Exception ignored) {

  }

  try { // ignore leading bytes

  while (a[j] == ) {

  j++;

  }

  } catch (Exception x) {

  return new byte[]; // one byte

  }

  byte[] result = new byte[len j + ];

  arraycopy(a j result len j +

  return result;

  }

  public byte[] eCode(byte[] bytes){

  DesEncrypt(keygetBytes() bytes

  return new byte [];

  }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26705.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.