Jon*_*Jon 4 java string bytearray
我想存储一个包装在String对象中的字节数组.这是场景
这是一段代码,描述了我在说什么.
String s = "test123";
byte[] a = s.getBytes();
byte[] b = env.encrypt(a);
String t = new String(b);
byte[] c = t.getBytes();
byte[] d = env.decrypt(c);
Run Code Online (Sandbox Code Playgroud)
其中env.encrypt()和env.decrypt()执行加密和解密.我遇到的问题是b数组的长度为8,c数组的长度为16.我认为它们是相等的.这里发生了什么?我试着修改代码如下
String s = "test123";
Charset charset = Charset.getDefaultCharset();
byte[] a = s.getBytes(charset);
byte[] b = env.encrypt(a);
String t = new String(b, charset);
byte[] c = t.getBytes(charset);
byte[] d = env.decrypt(c);
Run Code Online (Sandbox Code Playgroud)
但这没有帮助.
有任何想法吗?
Jon*_*han 17
将二进制数据存储在String对象中并不是一个好主意.你最好使用类似Base64编码的东西,它旨在将二进制数据转换为可打印的字符串,并且完全可逆.
事实上,我刚刚为Java找到了一个公共域base64编码器:http://iharder.sourceforge.net/current/java/base64/
Mr.*_* 安宇 11
有几个人指出这不是String(byte[])构造函数的正确使用.重要的是要记住,在Java中,a String由字符组成,恰好是16位,而不是8位,就像字节一样.你也忘记了字符编码.请记住,角色通常不是一个字节.
让我们一点一点地分解它:
String s = "test123";
byte[] a = s.getBytes();
Run Code Online (Sandbox Code Playgroud)
此时你的字节数组最有可能包含8个字节,如果你的系统默认字符编码Windows-1252或iso-8859-1或UTF-8.
byte[] b = env.encrypt(a);
Run Code Online (Sandbox Code Playgroud)
现在b包含一些看似随机的数据,具体取决于您的加密,甚至不保证一定的长度.许多加密引擎填充输入数据,以便输出匹配特定的块大小.
String t = new String(b);
Run Code Online (Sandbox Code Playgroud)
这是随机字节,并要求Java将它们解释为字符数据.这些字符可能显示为乱码,并且某些位序列对于每个编码都不是有效字符.Java尽职尽责并创建一系列16位字符.
byte[] c = t.getBytes();
Run Code Online (Sandbox Code Playgroud)
b根据编码的不同,这可能会也可能不会提供相同的字节数组.您在问题描述中声明您看到c长度为16个字节; 这可能是因为t中的垃圾在默认字符编码中转换不好.
byte[] d = env.decrypt(c);
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为c不是您期望的数据,而是腐败.
解决方案:
获取字节数组数据并使用Base64或十六进制数字对其进行编码并存储该字符串:
byte[] cypherBytes = env.encrypt(getBytes(plainText));
StringBuffer cypherText = new StringBuffer(cypherBytes.length * 2);
for (byte b : cypherBytes) {
String hex = String.format("%02X", b); //$NON-NLS-1$
cypherText.append(hex);
}
return cypherText.toString();
Run Code Online (Sandbox Code Playgroud)字符编码:
用户的密码可能不是ASCII,因此您的系统容易出错,因为您没有指定编码.
相比:
String s = "tést123";
byte[] a = s.getBytes();
byte[] b = env.encrypt(a);
Run Code Online (Sandbox Code Playgroud)
同
String s = "tést123";
byte[] a = s.getBytes("UTF-8");
byte[] b = env.encrypt(a);
Run Code Online (Sandbox Code Playgroud)
字节数组a的UTF-8编码值与系统默认值不同(除非您的系统默认值为UTF-8).只要A)你是一致的并且B)你的编码可以代表你的数据的所有允许字符,你使用什么编码并不重要.您可能无法以系统默认编码存储中文文本.如果您的应用程序曾部署在多台计算机上,并且其中一台计算机具有不同的系统默认编码,则在一个系统上加密的密码将在另一台系统上变得乱码.
故事的道德:字符不是字节,字节不是字符.你必须记住你正在处理的是什么,以及如何在它们之间来回转换.
| 归档时间: |
|
| 查看次数: |
19425 次 |
| 最近记录: |