昨天我問了下面的問題,但沒有得到太多的關注,因爲我沒有真正包含任何關於我的實際問題的細節。爲什麼我的簡體DES在Cp1252編碼下工作正常,但不在UTF-8下工作?
我會嘗試儘可能多的分析,以給你這是怎麼回事豁然開朗我的問題。
我有一個大學項目,我應該爲教育目的實施簡化的DES算法。該算法是使用10位密鑰來加密8位數據的加密算法。
在實現中,我想包括加密任何字符串。
因此,我編寫了8位加密的代碼,它對各種輸入都非常合適。爲了包括字符串加密支持我使用的函數String.getBytes()
,保存內的可變byte[] data
字符串的所有字節,然後我跟着此邏輯:
int i;
for(i=0; i< data.length; i++)
data[i] = encrypt(data[i]);
和用於解密我跟着此邏輯:
int i;
for(i=0; i< data.length; i++)
data[i] = encrypt(data[i]);
這裏是在main
函數的實際代碼
public static void main(String[] args){
short K = (short) Integer.parseInt("1010010001",2);
SDEncryption sdes = new SDEncryption(K); //K is the 10 bit key
String test = "INFO BOB 57674";
//let's encrypt the String test
String enc = sdes.encrypt(test.getBytes());
//let's decrypt the encrypted String of the initial String
String dec = sdes.decrypt(enc.getBytes());
}
通過使用默認編碼是Cp1252。我試圖加密字符串,得到了以下結果:
Initial Text: INFO BOB 57674
Encrypted Text: ÅO [áa[aá»j×jt
Decrypted Text: INFO BOB 57674
爲了看到實際的位表示每個I加密時間和解密我爲了顯示每個字符串的所有數據創建了以下函數的數據:
public void show(byte[] data){
//εμφάνιση των
//note how the Greek letters aren't displayed at all under Cp1252
int i;
for(i=0;i<data.length;i++){
short mask = (short) (1<<7); //10000000
while(mask>0){
if((data[i]&mask) == 0)
System.out.print("0");
else
System.out.print("1");
mask = (short) (mask >> 1);
}
if(i < data.length - 1){
System.out.print(" ");
}
}
System.out.println();
}
所以我得到了以下結果:
Initial Text(binary): 01001001 01001110 01000110 01001111 00100000 01000010 01001111 01000010 00100000 00110101 00110111 00110110 00110111 00110100
Encrypted Text(binary): 11000101 01001111 00100000 01011011 11100001 01100001 01011011 01100001 11100001 10111011 01101010 11010111 01101010 01110100
Decrypted Text(binary): 01001001 01001110 01000110 01001111 00100000 01000010 01001111 01000010 00100000 00110101 00110111 00110110 00110111 00110100
好像一切都按預期工作。爲了在代碼編輯器中支持希臘字母,我必須將編碼更改爲UTF-8。
再次運行一切後,我得到了以下結果:
Initial Text: INFO BOB 57674
Encrypted Text: �O [�a[a�j�jt
Decrypted Text: ���NFO���BOB���7���74
注意如何解密文本的某些單詞顯示正確,例如NFO
和BOB
。在我看來,就像操作位存在某種問題一樣,就好像Eclipse不能識別遵循UTF-8規則的位序列一樣。
下面是結果以二進制形式:
Initial Text(binary): 01001001 01001110 01000110 01001111 00100000 01000010 01001111 01000010 00100000 00110101 00110111 00110110 00110111 00110100
Encrypted Text(binary): 11101111 10111111 10111101 01001111 00100000 01011011 11101111 10111111 10111101 01100001 01011011 01100001 11101111 10111111 10111101 01101010 11101111 10111111 10111101 01101010 01110100
Decrypted Text(binary): 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 01001110 01000110 01001111 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 01000010 01001111 01000010 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 00110111 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 00110111 00110100
現在,我可以清楚地看到問題的礦石。看起來像UTF-8向字符串添加更多字節。但我不知道爲什麼。我的意思是初始文本似乎有相同數量的字節,所以爲什麼在加密後添加這些字節,甚至在解密後添加更多字節呢?
我會感謝您提供的任何幫助。先謝謝你!
的確,如果他用像FindBugs這樣的靜態代碼分析工具這一缺陷(使用'的getBytes( )而不是'getBytes(String)')會立即被報告。 –
不是說它有什麼不同,但[StandardCharsets](http://docs.oracle.com/javase/7/docs/api/java/nio/charset/StandardCharsets.html)類型現在提供了預定義的變量以供在類型安全的方法/構造函數。 – McDowell
非常感謝您的明確解釋,我的問題終於解決了! – ksm001