字节数组到字符串和反转:恢复的字节数组与 Java 中的原始字节数组不匹配
byte array to string and inverse : recoverded byte array is NOT match to original byte array in Java
我按如下方式将字节数组转换为字符串,在 Java:
String str_bytearray = new String(bytearray_original);
然后,我用字符串恢复了原来的字节数组,如下:
byte[] bytearray_recovered = str_bytearray.getBytes();
但我在比较 bytearray_original 和 bytearray_recovered 时想知道。结果如下:
[48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, 100, -27, 48, -31, 13, -33, 107, -90, 91, -9, 119, 121, -73, 83, -105, 51, -87, -109, -84, 99, 115, -123, 119, -117, -1, -62, 71, -32, 99, 4, -103, -115, -47, 113, -83, 8, -91, 14, -74, 113, -40, -26, 50, 111, 95, 71, -9, 112, 120, 16, 0, 113, -80, 124, -71, 53, -97, 69, -85, 38, -112, -30, -110, 115]
[48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, 100, -27, 48, -31, 13, -33, 107, -90, 91, -9, 119, 121, -73, 83, -105, 51, -87, -109, -84, 99, 115, -123, 119, -117, -1, -62, 71, -32, 99, 4, -103, 63, -47, 113, -83, 8, -91, 14, -74, 113, -40, -26, 50, 111, 95, 71, -9, 112, 120, 16, 0, 113, -80, 124, -71, 53, -97, 69, -85, 38, 63, -30, -110, 115]
可以看到,有两个字节不同于原来的字节数组,即-115 to 63
和-112 to 63
。
有没有可能解决这个问题?
注意:实际上原始字节数组和恢复的字节数组都是一个public键。首先将public密钥转换为字符串保存在文件中,然后读取public密钥的字符串值后,将其恢复以验证签名。
bytearray_original生成如下:
PublicKey signPublicKey = keypair.getPublic();
byte [] bytearray_original = signPublicKey.getEncoded();
感谢任何帮助。
此致
指定编码可能会有所帮助,例如 UTF-8。
String 构造函数和 getBytes 都可以让您这样做,例如:
String str_bytearray = new String(bytearray_original, "UTF-8");
byte[] bytearray_recovered = str_bytearray.getBytes("UTF-8");
这应该会产生相同的字节数组。
编辑:正如 RealSkeptic 指出的那样,您需要弄清楚原始字节数组是哪种编码,并用它代替上面代码中的 "UTF-8"。
您不能将任意字节序列转换为 String
并期望反向转换有效。您将需要使用 Base64
之类的编码来保留任意字节序列。 (这可以从几个地方获得——内置于 Java 8,也可以从 Guava 和 Apache Commons 获得。)
例如,Java 8,
String encoded = Base64.getEncoder().encodeToString(myByteArray);
可逆于
byte[] decoded = Base64.getDecoder().decode(encoded);
作为 Louis Wasserman 答案的替代方案,只要您的项目中有 BouncyCastle,您就可以使用 org.bouncycastle.util.encoders.Hex
实用程序 class:
import org.bouncycastle.util.encoders.Hex;
import java.util.Arrays;
class EncodingTest {
public static void main(String[] args) {
byte[] bytearray_original = new byte[]{48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, 100, -27, 48, -31, 13, -33, 107, -90, 91, -9, 119, 121, -73, 83, -105, 51, -87, -109, -84, 99, 115, -123, 119, -117, -1, -62, 71, -32, 99, 4, -103, -115, -47, 113, -83, 8, -91, 14, -74, 113, -40, -26, 50, 111, 95, 71, -9, 112, 120, 16, 0, 113, -80, 124, -71, 53, -97, 69, -85, 38, -112, -30, -110, 115};
String str_bytearray = Hex.toHexString(bytearray_original);
byte[] bytearray_recovered = Hex.decode(str_bytearray);
System.out.println("Results are equal: " + Arrays.equals(bytearray_original, bytearray_recovered));
}
}
此选项需要外部库,但不需要 Java 8.
我按如下方式将字节数组转换为字符串,在 Java:
String str_bytearray = new String(bytearray_original);
然后,我用字符串恢复了原来的字节数组,如下:
byte[] bytearray_recovered = str_bytearray.getBytes();
但我在比较 bytearray_original 和 bytearray_recovered 时想知道。结果如下:
[48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, 100, -27, 48, -31, 13, -33, 107, -90, 91, -9, 119, 121, -73, 83, -105, 51, -87, -109, -84, 99, 115, -123, 119, -117, -1, -62, 71, -32, 99, 4, -103, -115, -47, 113, -83, 8, -91, 14, -74, 113, -40, -26, 50, 111, 95, 71, -9, 112, 120, 16, 0, 113, -80, 124, -71, 53, -97, 69, -85, 38, -112, -30, -110, 115]
[48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, 100, -27, 48, -31, 13, -33, 107, -90, 91, -9, 119, 121, -73, 83, -105, 51, -87, -109, -84, 99, 115, -123, 119, -117, -1, -62, 71, -32, 99, 4, -103, 63, -47, 113, -83, 8, -91, 14, -74, 113, -40, -26, 50, 111, 95, 71, -9, 112, 120, 16, 0, 113, -80, 124, -71, 53, -97, 69, -85, 38, 63, -30, -110, 115]
可以看到,有两个字节不同于原来的字节数组,即-115 to 63
和-112 to 63
。
有没有可能解决这个问题?
注意:实际上原始字节数组和恢复的字节数组都是一个public键。首先将public密钥转换为字符串保存在文件中,然后读取public密钥的字符串值后,将其恢复以验证签名。
bytearray_original生成如下:
PublicKey signPublicKey = keypair.getPublic();
byte [] bytearray_original = signPublicKey.getEncoded();
感谢任何帮助。
此致
指定编码可能会有所帮助,例如 UTF-8。
String 构造函数和 getBytes 都可以让您这样做,例如:
String str_bytearray = new String(bytearray_original, "UTF-8");
byte[] bytearray_recovered = str_bytearray.getBytes("UTF-8");
这应该会产生相同的字节数组。
编辑:正如 RealSkeptic 指出的那样,您需要弄清楚原始字节数组是哪种编码,并用它代替上面代码中的 "UTF-8"。
您不能将任意字节序列转换为 String
并期望反向转换有效。您将需要使用 Base64
之类的编码来保留任意字节序列。 (这可以从几个地方获得——内置于 Java 8,也可以从 Guava 和 Apache Commons 获得。)
例如,Java 8,
String encoded = Base64.getEncoder().encodeToString(myByteArray);
可逆于
byte[] decoded = Base64.getDecoder().decode(encoded);
作为 Louis Wasserman 答案的替代方案,只要您的项目中有 BouncyCastle,您就可以使用 org.bouncycastle.util.encoders.Hex
实用程序 class:
import org.bouncycastle.util.encoders.Hex;
import java.util.Arrays;
class EncodingTest {
public static void main(String[] args) {
byte[] bytearray_original = new byte[]{48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, 100, -27, 48, -31, 13, -33, 107, -90, 91, -9, 119, 121, -73, 83, -105, 51, -87, -109, -84, 99, 115, -123, 119, -117, -1, -62, 71, -32, 99, 4, -103, -115, -47, 113, -83, 8, -91, 14, -74, 113, -40, -26, 50, 111, 95, 71, -9, 112, 120, 16, 0, 113, -80, 124, -71, 53, -97, 69, -85, 38, -112, -30, -110, 115};
String str_bytearray = Hex.toHexString(bytearray_original);
byte[] bytearray_recovered = Hex.decode(str_bytearray);
System.out.println("Results are equal: " + Arrays.equals(bytearray_original, bytearray_recovered));
}
}
此选项需要外部库,但不需要 Java 8.