这是我想要做的。我有一个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;
我做错了什么?有没有更好的解决方案?
答案 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)
它桥接字节和字符串之间的链接。并确保没有数据添加或丢失。 这是一个特殊的字符串。