byte []再次转换为字符串[]

时间:2013-02-28 22:10:50

标签: java bytearray

这是我想要做的。我有一个byte [],我需要用密钥存储在Redis中(比如key1)Redis会将它存储为String。我需要在通过key1

检索值时重建byte []
    //here is a byte array
    byte[] bArr = new byte[] {83, 71, 86, 115, 98, 71, 56, 103, 84, 88, 73, 117, 73, 69, 104, 118, 100, 121, 66, 107, 98, 121, 66, 53, 98, 51, 85, 103, 90, 71, 56, 47}; //"Hello World"; 

    // I will have to store this as a byte string into redis
    //Base64 encoding
    bArr = Base64.encodeBase64(bArr);
    String storeStr = Arrays.toString(bArr) ;
    // storeStr is what gets stored in redis
    System.out.println("storeStr>>" + storeStr+ "<<");
    // I will get this string back from redis
    // now trying to reconstruct the byte[]
    byte[] aArr = Base64.decodeBase64(storeStr); 
    System.out.println("readStr>>" + Arrays.toString(aArr)+ "<<");  

但我得到以下输出:

  

storeStr&gt;&gt; [85,48,100,87,99,50,74,72,79,71,100,85,87,69,   108,49,83,85,86,111,100,109,82,53,81,109,116,105,101,   85,73,49,89,106,78,86,90,49,112,72,79,67,56,61]&lt;&lt;   readStr&gt;&gt; [ - 13,-98,60,-41,77,60,-17,-33,121,-45,-66,59,-37,-65,123,-41,93,52 ,-13,-97,59,-21,-35,116,-13,-113,124,-33,-50,124,-21,93,117,-41,77,53,-45, -33,54,-25,127,53,-41,79,117,-41,-83,116,-25,93,53,-13,-98,-9,-29,-33,61 ,-41,78,-69,-13,-50,-67,-45,-113,117,-41,110,-10,-17,-34,-69,-25,-82, - 75]&LT;&LT;

我做错了什么?有没有更好的解决方案?

5 个答案:

答案 0 :(得分:5)

Arrays.toString()不会将字节数组转换为字符串。它给出了一个字节数组的字符串表示,用于调试目的,如List<Byte>.toString()那样。

Base64.encode()应该将字节数组转换为String。并且Base64.decode()应该将base64字符串转换为相应的字节数组。我见过的所有Base64库都内置了这样的方法。你的可能也有一个。如果没有,Base64包含ASCII字符,你可以简单地使用

String storeStr = new String(base64Array, "ASCII");

byte[] bytes = storeStr.getBytes("ASCII");

答案 1 :(得分:1)

我不知道你正在使用什么base64编码器,但是使用base64编码字节数组的结果应该已经String ...同样当你解码时,它应该将String转换为byte[]。不幸的是,一些base64 API在这方面的设计并不是非常好 -

我建议您查看具有更合理API的public domain library

byte[] binary = ...;
String encoded = Base64.encodeBytes(binary);

// Send encoded to Redis...

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

答案 2 :(得分:1)

您可以使用构造函数从byte []创建一个String:

//assuming you have a byte[] bytes
String string = new String(bytes);

然后将其写回:

byte[] bytes = string.getBytes();

答案 3 :(得分:1)

请记住,调用base 64是因为它的基数为64(64个可能的值)。这意味着每个字符是2 ^ 6或6位。 Redis支持二进制安全字符串,因此甚至可以使用非打印字符。没有理由将自己限制在64个漂亮的打印,网页安全字符(为什么人们使用B64)。

另一个问题是ASCII是0-127,但是字节是-128 to 127,所以我们不能直接映射,我们失去了一半的范围(2 ^ 8 vs 2 ^ 7)。如果我们使用UTF-8,我们得到所有这些位,所以2 ^ 8或基数256.结果是我们可以将一个字节填充到1.25个B64字符或单个UTF-8字符中。因此,UTF-8编码将使用~75%的空间作为B64编码数据。由于B64使用了所有额外的填充=字符,因此我们会比这更好。

示例,编码19个字节:

B64 字符串: 28 字符

UTF8 字符串: 19 个字符(节省32%!)

// setup
byte[] bytes = new byte[]{-10, 1, 3, 85, 48, 100, 87, 99, 050, 74, 79, 71, 100, 85, 87, -120, 108, -128, 30};

// full UTF-8 range
String outFullRange = new String(bytes, "UTF-8");
System.out.println(outFullRange); // prints �U0dWc(JOGdUW�l�

// just Base64
String outB64 = Base64.encode(bytes);
System.out.println(outB64);// 9gEDVTBkV2MoSk9HZFVXiGyAHg==

请记住,由于Redis在内存中,并且内存很珍贵,因此一旦应用程序开始填充以节省一些空间,您可能希望将二进制数据切换为UTF-8编码。缺点是它不像B64那样可读。

答案 4 :(得分:0)

使用这两个函数进行转换和转换

Convert.ToBase64String(en)

Convert.FromBase64String(input)

它桥接字节和字符串之间的链接。并确保没有数据添加或丢失。 这是一个特殊的字符串。

https://en.wikipedia.org/wiki/Base64