【问题标题】:Java : Hex encoded bytes get decoded with base64Java:十六进制编码字节用base64解码
【发布时间】:2019-03-20 15:50:10
【问题描述】:

HEX(Base16) 编码字节用 Base64 解码而不抛出异常?如何区分是否只用base16编码器编码?

org.apache.commons.codec.binary.Base64.decodeBase64(bytesencodedwithHex);

当上述方法的字节是十六进制编码数据时,该方法不会抛出任何异常或帮助识别它是十六进制编码的。 甚至 org.apache.commons.codec.binary.Base64.Base64.isBase64(bytesencodedwithHex) 返回 true。

字符串“Hello”下面的示例使用十六进制编码,当我使用 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())));   

【问题讨论】:

  • 为什么要它抛出异常?十六进制值(例如 '10ab')是合法的 base64 字符串...你能举例说明你的输入吗?
  • 感谢@Shir 的回复。我在主要问题中添加了详细信息。

标签: java base64 hex encode


【解决方案1】:

有些字符串不是以 64 为基数,就是以 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;
}

【讨论】:

    【解决方案2】:

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

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

    所以每个由0-9,A-F组成的字符串可以表示一个十六进制字符串,也可以表示一个Base64字符串(恰好只有0-9,A-F)。

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

    【讨论】:

      猜你喜欢
      • 2013-06-10
      • 1970-01-01
      • 2020-08-28
      • 2014-03-10
      • 1970-01-01
      • 2016-04-21
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多