2012-10-02 16 views
3

我正面臨這個奇怪的問題。我使用"Character.reverseBytes(char ch)"方法進行加密。它運行良好,當在NetBeans內運行。但是每當我試圖在外面運行它時,它都會產生奇怪的結果。問題在Java字符reverseBytes

我認爲這個問題是有兩種情況,它使用兩種不同的編碼方法(或類似的東西)。下面的代碼演示了這個問題。

import java.io.File; 
import java.io.PrintWriter; 
import java.util.ArrayList; 

public class Encryptor { 

    public static String encode(String in) { 
     ArrayList<Character> list = new ArrayList<Character>(); 
     for (int i = 0; i < in.length(); i++) { 
      list.add(Character.reverseBytes(in.charAt(i))); 
     } 
     return arrayToString(list); 
    } 

    public static String decode(String in) { 
     ArrayList<Character> list = new ArrayList<Character>(); 
     for (int i = 0; i < in.length(); i++) { 
      list.add(Character.reverseBytes(in.charAt(i))); 
     } 
     return arrayToString(list); 
    } 

    private static String arrayToString(ArrayList<Character> list) { 
     char[] ch = new char[list.size()]; 
     for (int i = 0; i < list.size(); i++) { 
      ch[i] = list.get(i); 
     } 
     return String.copyValueOf(ch); 
    } 

    public static void main(String[] args) throws java.io.FileNotFoundException, java.io.IOException { 
     String pass = "Password"; 
     String passEn = encode(pass); 
     File file = new File(System.getProperty("user.dir") + "/pass.txt"); 
     file.createNewFile(); 
     PrintWriter pr = new PrintWriter(file); 
     pr.write(passEn); 
     pr.flush(); 
     passEn = new java.util.Scanner(file).next(); 
     String passDe = decode(passEn); 
     String msg; 
     msg = "Initial : " + pass 
       + "\nEncrypted : " + passEn 
       + "\nDecrypted : " + passDe; 
     javax.swing.JOptionPane.showMessageDialog(null, msg); 
    } 
} 

首先我將加密的單詞保存到一個文件,然後嘗試解碼保存的單詞。這在上述兩種情況下給出了兩種不同的結果。

有什麼辦法解決這個問題嗎?

+0

你的系統上是否有不同的JRE版本,以及netbeans使用的版本? –

+5

你不會在需要任何安全性的* real *系統中使用它,對吧? –

+0

哇,很好的猜測。永遠不要回合。你知道如何檢查它嗎?我的意思是,在netbeans。我不知道多少回合.. – Anubis

回答

7

基本上,Character.reverseBytes給你一個有點任意的UTF-16編碼單元。不能保證任何後來獲得的字符將形成一個有效的字符串 - 例如,可能有「一半」替代對,或者在Unicode中沒有任何特定含義的字符。

更重要的是,當你將「文本」寫入文件並讀回來時,你會得到不同的值 - 特別是當你沒有指定編碼時。您正在使用的默認編碼很可能無法支持您最終使用的字符。

基本上,你不想做任何這樣的事情。字符串加密應該基本上可以下列形式:

  • 編碼字符串在一個固定的字節編碼(如UTF-8)
  • 加密的二進制數據(請不要推出自己; Java包含大量的加密設施)
  • 將加密的二進制數據傳遞到需要的地方。如果你需要將二進制數據表示爲一個字符串,請使用類似base64的東西來確保以後可以恢復確切的二進制數據。

然後解密,則反轉每次操作:

  • 檢索加密的二進制數據,這可能涉及基於從BASE64
  • 轉換回執行相應的解密步驟(二進制至二進制)任何之前使用的加密算法
  • 將結果(仍爲字節)轉換回字符串,使用最初使用的相同編碼

將文本中的任意二進制數據處理爲文本--正在以非常粗糙的方式實際執行 - 這是一個非常糟糕的主意。

+0

感謝您的回答! – Anubis