在Java中,如何正确地将byte[]转成String再转成byte[]?
In Java, how to convert correctly byte[] to String to byte[] again?
我想将 TEA 加密的结果(byte[])转换为 String,然后再次将其转换为 byte[] 并检索相同的 byte[]。
//Encryption in the sending side
String stringToEncrypt = "blablabla"
byte[] encryptedDataSent = tea.encrypt(stringToEncrypt.getBytes());
String dataToSend = new BigInteger(encryptedDataSent).toString());
//Decryption side in the reception side
byte[] encryptedDataReceived = new BigInteger(dataToSend).toByteArray();
但是,当我尝试这样做时:
System.out.println(new String(encryptedDataSent));
System.out.println(new String(encryptedDataReceived));
boolean equality = Arrays.equals(encryptedDataReceived,encryptedDataSent);
System.out.println("Are two byte arrays equal ? : " + equality);
输出为:
&h�7�"�PAtj݄�I��Z`H-jK�����f
&h�7�"�PAtj݄�I��Z`H-jK�����f
Are two byte arrays equal ? : false
所以,当我们打印它时,两个 byte[] 看起来是相同的,但它们与我们看到的并不完全相同 "false",这是我之后执行的解密的问题.
我也试过发送一个 String with new String(byte[])
但是当我们想把它转换回一个字节时它有同样的问题[]
我想在转换byte[]->String->byte[]
的开头和转换后有完全相同的byte[]
您有解决方案或了解我在转换过程中做错了什么吗?
你不能。 String
不是二进制数据的容器。它是 UTF-16 字符的容器。字符和字节之间的往返无法保证。
不要尝试将 byte[]
转换为 String
,就好像它是常规编码的文本数据一样 - 它不是。这是一个任意字节数组。
最简单的方法是将其转换为 base64 或十六进制 - 这将生成可逆解码回相同二进制数据的 ASCII 文本。例如,使用 public domain base64 encoder:
String dataToSend = Base64.encodeBytes(encryptedDataSent);
...
byte[] encryptedDataReceived = Base64.decode(receivedText);
尝试在解密中使用
byte[] 编码 = Base64.encode(bytesToStore, Base64.DEFAULT)
尝试明确指定字符集。 UTF-8 适用于主要情况:
public static void main(String[] args) {
String in = "幸福";
try {
byte[] bytes = in.getBytes("utf-8");
String out = new String(bytes, "utf-8");
System.out.println(in + " -> " + out);
System.out.println("equals: " + out.equals(in));
} catch (UnsupportedEncodingException unsupportedEncodingException) {
// do something
}
}
请注意,当字节数组保持不变时,您将得到完全相同的结果。
我想将 TEA 加密的结果(byte[])转换为 String,然后再次将其转换为 byte[] 并检索相同的 byte[]。
//Encryption in the sending side
String stringToEncrypt = "blablabla"
byte[] encryptedDataSent = tea.encrypt(stringToEncrypt.getBytes());
String dataToSend = new BigInteger(encryptedDataSent).toString());
//Decryption side in the reception side
byte[] encryptedDataReceived = new BigInteger(dataToSend).toByteArray();
但是,当我尝试这样做时:
System.out.println(new String(encryptedDataSent));
System.out.println(new String(encryptedDataReceived));
boolean equality = Arrays.equals(encryptedDataReceived,encryptedDataSent);
System.out.println("Are two byte arrays equal ? : " + equality);
输出为:
&h�7�"�PAtj݄�I��Z`H-jK�����f
&h�7�"�PAtj݄�I��Z`H-jK�����f
Are two byte arrays equal ? : false
所以,当我们打印它时,两个 byte[] 看起来是相同的,但它们与我们看到的并不完全相同 "false",这是我之后执行的解密的问题.
我也试过发送一个 String with new String(byte[])
但是当我们想把它转换回一个字节时它有同样的问题[]
我想在转换byte[]->String->byte[]
的开头和转换后有完全相同的byte[]您有解决方案或了解我在转换过程中做错了什么吗?
你不能。 String
不是二进制数据的容器。它是 UTF-16 字符的容器。字符和字节之间的往返无法保证。
不要尝试将 byte[]
转换为 String
,就好像它是常规编码的文本数据一样 - 它不是。这是一个任意字节数组。
最简单的方法是将其转换为 base64 或十六进制 - 这将生成可逆解码回相同二进制数据的 ASCII 文本。例如,使用 public domain base64 encoder:
String dataToSend = Base64.encodeBytes(encryptedDataSent);
...
byte[] encryptedDataReceived = Base64.decode(receivedText);
尝试在解密中使用 byte[] 编码 = Base64.encode(bytesToStore, Base64.DEFAULT)
尝试明确指定字符集。 UTF-8 适用于主要情况:
public static void main(String[] args) {
String in = "幸福";
try {
byte[] bytes = in.getBytes("utf-8");
String out = new String(bytes, "utf-8");
System.out.println(in + " -> " + out);
System.out.println("equals: " + out.equals(in));
} catch (UnsupportedEncodingException unsupportedEncodingException) {
// do something
}
}
请注意,当字节数组保持不变时,您将得到完全相同的结果。