簡體   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