字节数组到字符串和反向:恢复的字节数组与Java中的原始字节数组不匹配

字节数组到字符串和反向:恢复的字节数组与Java中的原始字节数组不匹配,java,string,bytearray,Java,String,Bytearray,我用Java将字节数组转换为字符串,如下所示: String str_bytearray = new String(bytearray_original); 然后,我使用字符串恢复了原始字节数组,如下所示: byte[] bytearray_recovered = str_bytearray.getBytes(); [48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7,

我用Java将字节数组转换为字符串,如下所示:

String str_bytearray = new String(bytearray_original);
然后,我使用字符串恢复了原始字节数组,如下所示:

byte[] bytearray_recovered = str_bytearray.getBytes();
[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]
但我想知道,当我把拜特利的原版和恢复版进行比较时。结果如下:

byte[] bytearray_recovered = str_bytearray.getBytes();
[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到63
-112到63
。 有可能解决这个问题吗

注意:实际上,原始字节数组和恢复的字节数组都是公钥。首先将公钥转换为字符串以存储在文件中,然后在读取公钥的字符串值后,应恢复该公钥以验证签名

bytearray_原件生成如下:

PublicKey signPublicKey = keypair.getPublic(); 
byte [] bytearray_original = signPublicKey.getEncoded();
谢谢你的帮助


关于

它可能有助于指定编码,例如UTF-8

字符串构造函数和getBytes都允许您执行此操作,例如:

String str_bytearray = new String(bytearray_original, "UTF-8");
byte[] bytearray_recovered = str_bytearray.getBytes("UTF-8");
这将导致相同的字节数组


编辑:正如Real怀疑论者所指出的,您需要找出原始字节数组的编码方式,并用它来代替上述代码中的“UTF-8”。

您不能将任意字节序列转换为
字符串,而需要反向转换。您需要使用类似于
Base64
的编码来保留任意字节序列。(这可以从几个地方获得——内置于Java 8中,也可以从Guava和Apache Commons获得。)

例如,使用Java8

String encoded = Base64.getEncoder().encodeToString(myByteArray);
是可逆的

byte[] decoded = Base64.getDecoder().decode(encoded);

作为Louis Wasserman答案的替代方案,只要您在项目中有,您可以使用
org.bouncycastle.util.encoders.Hex
实用程序类:

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。

仅当原始字节实际上是UTF-8时才需要。它应该可以以任何方式工作,但如果字节不是UTF-8,字符串可能无法正确反映字节信息。如果希望发生这种情况,只需将“UTF-8”更改为数组中字节的编码。@Trent Small,情况更糟,即使长度不一样。结果如下:原文:[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, 107, 38, -108, 75, 125, 75, -103, -70, 68, 103, -120, 78, 113, -98, -111, 106, 38, -125, -93, -102, -22, -37, 30, 25, 61, -15, -90, -47, 76, -25, 16, -9, 14, 3, 19, -115, 27, 39, -77, -55, -12, -54, 85, 69, -76, 53, -3, 94, -107, 124, 61, 100, 49,-21,-61,-21,-54,112,-47,-16,-50,-47,-106,-13]。已恢复:[48, 89, 48, 19, 6, 7, 42, -17, -65, -67, 72, -17, -65, -67, 61, 2, 1, 6, 8, 42, -17, -65, -67, 72, -17, -65, -67, 61, 3, 1, 7, 3, 66, 0, 4, 107, 38, -17, -65, -67, 75, 125, 75, -17, -65, -67, -17, -65, -67, 68, 103, -17, -65, -67, 78, 113, -17, -65, -67, -17, -65, -67, 106, 38, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65,-67,30,25,61,-17,-65,-67,-17,-65,-67,76,-17,-65,-16,-17,-65,-67,14,3,19,-17,-65,-67,27,39,-17,-65,-67,继续,-17,-65,-17,-65,-67,-67,-17,-65,-67,-67,124,61,100,-49,-17,-65,-67,-67,-17,-65,-65,-67,-67,-112,-17,-67,-67,-65,-67-17, -65, -67, -17, -65, -67, -47, -106, -17, -65, -67]。此转换的目的是什么?您想将字节数组存储为字符串还是出于好奇?@sainaen,事实上原始字节数组和恢复的字节数组都是公钥。首先将公钥转换为字符串以存储在文件中,然后在读取公钥的字符串值后,应将其恢复以验证e signature.oh,好吧,那么您可能正在使用bouncycastle之类的东西来进行加密。您可能需要尝试类似于
org.bouncycastle.util.encoders.Hex.toHexString()和
Hex.decode()的东西
-它们适用于任意二进制数据。@sainaen,是的,没错。但我不知道如何在我自己身上使用你的代码。如果你能在我的代码中使用它,我将不胜感激。谢谢。啊,这不会被很好地编码为UTF-8字符串,因为它是一堆随机数据。相反,你应该像Louis Wa那样使用Base64对数据进行编码请给我举个例子好吗?谢谢。