Java 字节到字符串,反之亦然

Java 字节到字符串,反之亦然,java,encoding,character-encoding,bytearray,Java,Encoding,Character Encoding,Bytearray,我需要转换随机生成的salt值并将其存储在数据库中。为了将其存储在数据库中,我将其转换为字符串。然后为了检索原始值,我将其转换回字节。但这两个值并不匹配。我试过“UTF-8”,“UTF-16”,Base64编码器 SecureRandom ranGen = new SecureRandom(); byte[] aesKey = new byte[16]; // 16 bytes = 128 bits ranGen.nextBytes(aesKey); System.out.println(

我需要转换随机生成的salt值并将其存储在数据库中。为了将其存储在数据库中,我将其转换为字符串。然后为了检索原始值,我将其转换回字节。但这两个值并不匹配。我试过“UTF-8”,“UTF-16”,Base64编码器

SecureRandom ranGen = new SecureRandom();
byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
ranGen.nextBytes(aesKey);   
System.out.println(aesKey);

String a=new String(aesKey,"UTF-16");
byte[] b=new byte[16];
b=a.getBytes("UTF-16");
System.out.println(b);
上述代码的输出(执行2次):

您真的应该使用它将二进制数据转换为字符串。有很多可用的免费实现,例如中的一个

此外,它非常易于使用,例如:

对于编码:

import org.apache.commons.codec.binary.Base64;
...
byte[] abValue = {...}; // Your data to encode
Base64 base64 = new Base64();
String strEncodedData = base64.encodeToString(abValue).trim();
解码:

import org.apache.commons.codec.binary.Base64;
...
String strEncodedData = "..."; // Your previously encoded data
Base64 base64 = new Base64();
byte[] abValue = base64.decode(strValue);
您真的应该使用它将二进制数据转换为字符串。有很多可用的免费实现,例如中的一个

此外,它非常易于使用,例如:

对于编码:

import org.apache.commons.codec.binary.Base64;
...
byte[] abValue = {...}; // Your data to encode
Base64 base64 = new Base64();
String strEncodedData = base64.encodeToString(abValue).trim();
解码:

import org.apache.commons.codec.binary.Base64;
...
String strEncodedData = "..."; // Your previously encoded data
Base64 base64 = new Base64();
byte[] abValue = base64.decode(strValue);

在上面编写代码时,先打印
aesKey
,然后打印
b
,实际打印的是数组对象的
toString
方法的输出,这只是默认对象
toString
方法。所以我不明白你怎么能期望他们是一样的

如果你真的想检查它们是否相同,你应该逐字节比较它们

关于在DB中将字节[]存储为字符串的实际问题,最好的办法是对其进行Base64编码。我建议为此使用ApacheCommons编解码器库。看

编辑:

使用您提到的BASE64Encode和BASE64Decoder,代码如下所示:

    SecureRandom ranGen = new SecureRandom();
    byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
    ranGen.nextBytes(aesKey);
    String a = new BASE64Encoder().encode(aesKey);

    System.out.println(a);

    byte[] b = new BASE64Decoder().decodeBuffer(a);
    System.out.println(new BASE64Encoder().encode(b));

    for (int i = 0; i < aesKey.length; i++) {
        System.out.println(aesKey[i] + " " + b[i]);
    }
SecureRandom ranGen=new SecureRandom();
字节[]aesKey=新字节[16];//16字节=128位
下字节范围(aesKey);
字符串a=新BASE64Encoder().encode(aesKey);
系统输出打印项次(a);
字节[]b=新的BASE64Decoder().decodeBuffer(a);
System.out.println(新的BASE64Encoder().encode(b));
for(int i=0;i

这里,我还分别循环遍历了字节,以表明它们确实相等。

当您的代码写在上面时,打印
aesKey
,然后打印
b
,您实际打印的是数组对象的
toString
方法的输出,这只是默认的对象
toString
方法。所以我不明白你怎么能期望他们是一样的

如果你真的想检查它们是否相同,你应该逐字节比较它们

关于在DB中将字节[]存储为字符串的实际问题,最好的办法是对其进行Base64编码。我建议为此使用ApacheCommons编解码器库。看

编辑:

使用您提到的BASE64Encode和BASE64Decoder,代码如下所示:

    SecureRandom ranGen = new SecureRandom();
    byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
    ranGen.nextBytes(aesKey);
    String a = new BASE64Encoder().encode(aesKey);

    System.out.println(a);

    byte[] b = new BASE64Decoder().decodeBuffer(a);
    System.out.println(new BASE64Encoder().encode(b));

    for (int i = 0; i < aesKey.length; i++) {
        System.out.println(aesKey[i] + " " + b[i]);
    }
SecureRandom ranGen=new SecureRandom();
字节[]aesKey=新字节[16];//16字节=128位
下字节范围(aesKey);
字符串a=新BASE64Encoder().encode(aesKey);
系统输出打印项次(a);
字节[]b=新的BASE64Decoder().decodeBuffer(a);
System.out.println(新的BASE64Encoder().encode(b));
for(int i=0;i


在这里,我还分别循环了字节,以表明它们确实相等。

两个系统输出的输出是什么?正如我在回答中所说,这里打印的是对象到字符串输出,默认情况下是getClass().getName()+“@”+Integer.toHexString(hashCode())。因此,由于您有两个不同的字节数组(即,不是同一个对象),因此输出是不同的。正如DaveJohnston所暗示的,在java语言中使用toString()时,您应该小心。这两个系统输出的输出是什么?正如我在回答中所说,您在这里打印的是对象toString输出,默认情况下是getClass().getName()+“@”+整数.toHexString(hashCode())。因此,由于您有两个不同的字节数组(即,不是同一个对象),因此输出是不同的。正如DaveJohnston所暗示的,在java语言中使用toString()时应该小心。如果我错了,请纠正我。如果两个字节在任何意义上都相等。然后,即使是默认对象toString,它们也应该给出相同的值。它们是字节数组,并且它们不是相同的对象,因此默认toString方法不会返回相同的结果。如果它返回它们的对象地址,它将写入:getClass().getName()+“@”+Integer.toHexString(hashCode())对象中的hashCode方法是本机的,据我所知,并不是记忆中物体的确切地址,而是与之相关的东西。如果我错了,请纠正我。如果两个字节在任何意义上都相等。然后,即使是默认对象toString,它们也应该给出相同的值。它们是字节数组,并且它们不是相同的对象,因此默认toString方法不会返回相同的结果。如果它返回它们的对象地址,它将写入:getClass().getName()+“@”+Integer.toHexString(hashCode())对象中的hashCode方法是本机的,据我所知,并不是内存中对象的确切地址,而是与之相关的东西。在Java64中,我的import语句应该是什么。您还需要将commons codec jar添加到项目库中。您还需要将commons编解码器jar添加到项目库中。