繁体   English   中英

Java:十六进制编码的字节使用base64解码

[英]Java : Hex encoded bytes get decoded with base64

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())));   

每个十六进制字符串都是合法的Base64字符串。

十六进制编码为您提供了一个字符串,代表原始字符串的字节,由0-9和AF组成。 Base64编码为您提供了一个字符串,该字符串对原始字符串进行了编码,并且仅由可打印字符(当然包括0-9,AF)组成。

因此,由0-9,AF组成的每个字符串都可以代表一个十六进制字符串,但也可以表示Base64字符串(恰好只有0-9,AF)。

您将需要一种不同的方式来告诉用户所使用的编码。 一个示例是将编码类型的结构与字符串一起发送,或发送原始字符串的长度(因此,如果解码后得到的长度错误,则这不是正确的编码模式)。

有些字符串以base 64或base 16为基础,没有任何线索。

但是有一些线索:

  • 如果length()%2!= 0,则它必须是Base64。
  • 如果length()%3 == 1,则有6个虚假的位,不能为Base64。 因为它必须是Base16,所以甚至必须保持length()%2 == 0。
  • 所有字母都可能是大写或小写。
  • 缺少特殊的“数字” /+以及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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM