java - 關于字符串編碼。
問題描述
public static void main(String[] args) throws Exception { String str = 'resource'; System.out.println(Arrays.toString(getHash(str,'MD5').getBytes()));//使用默認解碼后輸出}public static String getHash(String str, String hashType) { try {MessageDigest digest = MessageDigest.getInstance(hashType);digest.reset();byte[] b = digest.digest(str.getBytes());System.out.println(Arrays.toString(b)); //編碼前輸出return new String(b); //使用默認編碼 } catch (NoSuchAlgorithmException e) {e.printStackTrace(); } return str;}
輸出:[-106, -85, 78, 22, 63, 78, -32, 58, -86, 77, 16, 81, -86, 81, -46, 4]
[-17, -65, -67, -17, -65, -67, 78, 22, 63, 78, -17, -65, -67, 58, -17, -65, -67, 77, 16, 81, -17, -65, -67, 81, -17, -65, -67, 4]
為什么編碼前和編碼后再解碼所輸出的不一樣?
問題解答
回答1:你可能認為(new String(b)).getBytes().equals(b),實際上并非如此。(盡管new String(s.getBytes()).equals(s)一定是。)
因為byte[]轉換成String時,有些字節是未必能轉換成字符的,比如第一個-106、第二個-85就是,所以轉換成String時前兩個就變成了未知字符(表面上會顯示?,但實際上是一個Unicode字符),再轉成byte[](你這邊defaultCharset應該是UTF-8吧),每個未知字符就變成3個字節了。
如果用GBK的話,情況還算好,但還是略有不同:
[-106, -85, 78, 22, 63, 78, -32, 58, -86, 77, 16, 81, -86, 81, -46, 4][-106, -85, 78, 22, 63, 78, 63, 58, -86, 77, 16, 81, -86, 81, 63, 4]
所以結論是:如果用String表示一個Hash值,不能把byte[]強轉換成String,而是按慣例轉換成16進制表示。
相關文章:
1. node.js - webpack-dev-server正常運行,webpack打包卻出錯,怎么辦?2. node.js - nodejs,express搭建,為什么ejs模板被解析成pre了?3. javascript - 關于iscroll的一段代碼,希望有人解釋4. 我何時應該在Java中使用JFrame.add(component)和JFrame.getContentPane()。add(component)5. javascript - 不定高度動畫怎么實現?6. android - 哪位大神知道java后臺的api接口的對象傳到前端后輸入日期報錯,是什么情況?求大神指點7. html5 - 請問一下寫H5的時候 你們都是兼容那些手機8. 輸入地址報以下截圖錯誤,怎么辦?9. php自學從哪里開始?10. mysql - 瞬間流量很高的網站,要頻繁的插入數據到數據庫,應該怎么解決這個問題?
