HEX(Base16)使用Base64对编码的字节进行解码而不会引发异常?如何区分是否仅使用base16编码器编码?
org.apache.commons.codec.binary.Base64.decodeBase64(bytesencodedwithHex);
当上述方法的字节是十六进制编码的数据时,该方法不会引发任何异常,也不会帮助标识它是十六进制编码的。 甚至org.apache.commons.codec.binary.Base64.Base64.isBase64(bytesencodedwithHex)也会返回true。
示例下面的字符串“ Hello”已用Hex编码,当我使用Base64解码时,它会带来一些废话。在这种情况下,我如何让客户知道他们使用了错误的解码器? :
System.out.println(new
String(org.bouncycastle.util.encoders.Hex.encode("Hello".getBytes())));
System.out.println(new String(org.bouncycastle.util.encoders.Base64.decode("48656c6c6f".getBytes())));
答案 0 :(得分:1)
每个十六进制字符串都是合法的Base64字符串。
十六进制编码为您提供了一个字符串,代表原始字符串的字节,由0-9和A-F组成。 Base64编码为您提供了一个字符串,该字符串对原始字符串进行了编码,并且仅由可打印字符(当然包括0-9,A-F)组成。
因此,每个由0-9,A-F组成的字符串都可以代表一个十六进制字符串,但也可以代表Base64字符串(恰好只有0-9,A-F)。
您将需要一种不同的方式来告诉用户所使用的编码。一个示例是将编码类型的结构与字符串一起发送,或发送原始字符串的长度(因此,如果解码后得到的长度错误,则这不是正确的编码模式)。
答案 1 :(得分:1)
有些字符串的基数是64或16,没有任何线索。
但是有一些线索:
/
,+
和G-Zg-z
。所以:
boolean probablyHex(String s) {
if (s.endsWith("=")) { // Base64 padding char (optional).
return false;
}
s = s.replaceAll("[^-_+/A-Za-z0-9]", ""); // MIME safe Base64 variant too.
if (s.matches(".*[-_+/G-Zg-z].*")) {
return false;
}
int n = s.length();
if (n % 2 == 1) {
return false;
}
if (n % 3 == 1) { // Spurious char with 6 bits data.
return true;
}
// Very unlikely that it is Base64, but you might have a bias towards Base64:
if (!s.equals(s.toUpperCase(Locale.US)) && !s.equals(s.toLowerCase(Locale.US)) {
// Mixed cases in A-Fa-f:
// For small texts that is significantly incoherent, meaning Base64.
return n > 32;
}
return true;
}