让“awids”为base 64中的12个字符长度id(A-Z a-z 0-9“ – ”“@”).这是输入.
我的最终目标是在这些awid和UUID之间创建一个双射映射,使用一些填充,将awid作为初始输入.
在尝试使用java.util.Base64时,我没有在解码和再次编码后得到初始值.我做的愚蠢错误是什么? 🙂
使用下面提供的可重现的示例,输出是错误的,因为在decode() – encode()之后没有返回输入字符串并且未保留双射(Q39s / L和Q39s / A映射到相同的值).
------------------------------------------> Q39s/L (6 [51 33 39 73 2f 4c]) 4 [43 7f 6c fc] -> 6 [51 33 39 73 2f 41] -> Q39s/A (6 [51 33 39 73 2f 41]) 4 [43 7f 6c fc] -> 6 [51 33 39 73 2f 41] -> Q39s/A (6 [51 33 39 73 2f 41])
这是一个可重复的例子:
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.StringJoiner;
public class StackOverflowQuestion {
public static void main(String[] args) {
String halfAwid = "Q39s/L";
byte[] sigBits = Base64.getDecoder().decode(halfAwid.getBytes(StandardCharsets.UTF_8));
byte[] actualSigBits = Base64.getEncoder().withoutPadding().encode(sigBits);
String actualHalfAwid = new String(actualSigBits, StandardCharsets.UTF_8);
byte[] sigBits2 = Base64.getDecoder().decode(halfAwid.getBytes(StandardCharsets.UTF_8));
byte[] actualSigBits2 = Base64.getEncoder().withoutPadding().encode(sigBits2);
String actualHalfAwid2 = new String(actualSigBits2, StandardCharsets.UTF_8);
System.out.println("----------------------------------------------> "
+ halfAwid + " (" + toHexString(halfAwid) + ") "
+ "\n"
+ " "
+ toHexString(sigBits) + " -> "
+ toHexString(actualSigBits) + " -> "
+ actualHalfAwid + " (" + toHexString(actualHalfAwid) + ") "
+ "\n"
+ " "
+ toHexString(sigBits2) + " -> "
+ toHexString(actualSigBits2) + " -> "
+ actualHalfAwid2 + " (" + toHexString(actualHalfAwid2) + ")"
+ "");
}
private static String toHexString(byte[] bytes) {
StringJoiner joiner = new StringJoiner(" ", "" + bytes.length + " [", "]");
for (byte b : bytes) {
joiner.add(String.format("%02x", b));
}
return joiner.toString();
}
private static String toHexString(String text) {
return toHexString(text.getBytes());
}
}
不要犹豫,指出我在代码中做的任何其他错误,即使它们与问题没有直接关系.谢谢.
最佳答案 如果将编码数据视为整个字节(或ASCII字符)的序列,则Base64编码不是所有输入大小的双射映射. Base64是8位到6位单位的编码单位(每个单位产生64种可能的组合),所以当你编码4个字节时,换句话说4×8 = 32位,你将获得32/6 =5⅓单位输出,这意味着输出的第六个单元不会使用所有位.
换句话说,当您将由64个定义字符中的6个组成的任意字符串视为Base64编码时,您将把64⁶组合的字符串投影到具有256⁴组合的6个字节的“源”序列,这意味着数据丢失.
如果您选择可投影到整数个单位的输入大小,则可以使用Base64编码作为双射映射.显然,六个源字节可以编码为八个Base64编码的字节.但它不适用于六个编码字节.有趣的是,它将适用于您实际需要的大小,因为九个源字节将被编码为正好十二个编码字节:9×8 = 72,72 / 6 = 12.