[英]When I use DES algorithm I convert byte[] to String and convert this String to byte[], and these two byte[] become different
When I use DES algorithm I convert byte[] to String and convert this String to byte[], and these two byte[] become different:当我使用 DES 算法时,我将 byte[] 转换为 String 并将这个 String 转换为 byte[],这两个 byte[] 变得不同:
String str = "lszzz";
String password = "12343213";
byte[] result = Des.encrypt(str.getBytes("utf-8"), password);
String res=new String(result,"utf-8");
System.out.println(result+" dividing line "+res.getBytes());
The running answer is运行的答案是
[B@182decdb dividing line [B@26f0a63f;
Why are these two byte[]
different, and how can I can get the same byte[]
?为什么这两个byte[]
不同,我怎样才能得到相同的byte[]
?
There are two issues here.这里有两个问题。
When you concatenate a String with a byte array (which you do twice in result + " dividing line " + res.getBytes()
) you are calling toString()
on a byte[]
.当您将 String 与字节数组连接时(您在result + " dividing line " + res.getBytes()
中执行两次),您正在调用toString()
上的byte[]
。 When you call toString()
on any array, you get a value of the form当你在任何数组上调用toString()
时,你会得到一个表单的值
[<internal-type-name>@<identity-hashcode>
This does not represent the contents of the array.这并不代表数组的内容。 It represents the identity of the array.它表示数组的标识。
So, in this case, [B@182decdb dividing line [B@26f0a63f
only tells you that these are byte arrays and that they are not the same object.所以,在这种情况下, [B@182decdb dividing line [B@26f0a63f
只告诉你这些是字节 arrays,它们不是同一个 object。 It does not explain anything.它没有解释任何东西。
The second issue is that you can't treat an arbitrary byte sequence as a UTF-8 encoding.第二个问题是您不能将任意字节序列视为 UTF-8 编码。 Not every sequence of arbitrary bytes is a valid UTF-8 encoding.并非每个任意字节序列都是有效的 UTF-8 编码。
The Des.encrypt
call is producing a byte array containing arbitrary binary bytes. Des.encrypt
调用正在生成一个包含任意二进制字节的字节数组。 When you treat an array containing arbitrary bytes as UTF-8 encoded... and decode it into a String
, the process is lossy.当您将包含任意字节的数组视为 UTF-8 编码...并将其解码为String
时,该过程是有损的。 When you then take the String
value in res
and then attempt to encode it as UTF-8, it is unlikely that the bytes you will get will be the same as the bytes that you started with.然后,当您在res
中获取String
值并尝试将其编码为 UTF-8 时,您将获得的字节不太可能与您开始使用的字节相同。
The solution depends on what you are trying to do here:解决方案取决于您在此处尝试执行的操作:
If you want to store or transmit binary data as binary:如果您想以二进制形式存储或传输二进制数据:
BLOB
database type使用BLOB
数据库类型InputStream
/ OutputStream
使用InputStream
/ OutputStream
DataInputStream
/ DataOutput
or ObjectInputStream
/ ObjectOutputStream
可能使用DataInputStream
/ DataOutput
或ObjectInputStream
/ ObjectOutputStream
If you are trying to turn the encrypted data into a robust form that can be transmitted through a "text only" channel, use Base64
encoding.如果您尝试将加密数据转换为可通过“纯文本”通道传输的可靠形式,请使用Base64
编码。
If want to pretend that your bytes are text, you could encode them as ISO-8859-1 aka LATIN-1.如果想假装你的字节是文本,你可以将它们编码为 ISO-8859-1 aka LATIN-1。 There is a 1-to-1 correspondence between the 256 codes of ISO-8859-1 and the first 256 Unicode codepoints. ISO-8859-1 的 256 个代码与前 256 个 Unicode 代码点之间存在一对一的对应关系。 So if you pretend that that your binary is ISO-8859-1, you can decode them to a string, encode them back to ISO-8859-1, and get the bytes that you started with.因此,如果您假装您的二进制文件是 ISO-8859-1,您可以将它们解码为字符串,将它们编码回 ISO-8859-1,然后获取您开始使用的字节。 (This is conceptually broken... but it works.) (这在概念上被打破了......但它有效。)
Now a strict reading of the ISO-8859-1 spec says that the "conceptually broken" approach should not work .现在,对 ISO-8859-1 规范的严格阅读表明,“概念上的破坏”方法不应该起作用。 However, the following test code demonstrates that it does.但是,以下测试代码证明了它确实如此。
public class Test {
public static void main (String[] args) throws Exception {
byte[] data = new byte[256];
for (int i = 0; i < 256; i++) {
data[i] = (byte) i;
}
String s = new String(data, "ISO-8859-1");
data = s.getBytes("ISO-8859-1");
for (int i = 0; i < 256; i++) {
if (data[i] != ((byte) i)) {
System.out.println("mismatch: " + data[i] + " != " +
((byte) i));
}
}
}
}
We can put this down to the way that the ISO-8859-1 encoder / decoder classes are implemented in Java.我们可以将其归结为 ISO-8859-1 编码器/解码器类在 Java 中实现的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.