base64 到十六进制不一致的结果

base64 to hex inconsistent results

昨天,我在java写了一个单元测试。我正在测试的例程需要以十六进制来回转换 base64。

在我的测试中,我使用字符串 myEvent= 作为 base64。在十六进制中,它变为 9B212F7A7B,但是当我将十六进制转换回 base64 时,我得到 myEvens=

为什么会这样?我尝试了不同的库和工具,它总是给我这个结果。

import java.util.*;
import java.lang.*;

import javax.xml.bind.DatatypeConverter;

class Rextester
{  
    public static void main(String args[])
    {
        String data1 = "myEvent=";
        String hex1 = convertBase64StringToBase16(data1); // 9B212F7A7B
        String data2 = convertBase16StringtoBase64(hex1); // myEvens=
        String hex2 = convertBase64StringToBase16(data2); // 9B212F7A7B 
        System.out.println("data1=" + data1);
        System.out.println("data2=" + data2);
        System.out.println("hex1=" + hex1);
        System.out.println("hex2=" + hex2);
    }

    private static String convertBase16StringtoBase64(String base16) {
        return Base64.getUrlEncoder().encodeToString(DatatypeConverter.parseHexBinary(base16));
    }

    public static String convertBase64StringToBase16(String base64) {
        return DatatypeConverter.printHexBinary(Base64.getUrlDecoder().decode(base64));
    }
}

现场演示:http://rextester.com/JFDYO56442

base64 algorithm 说:

When the number of bytes to encode is not divisible by three (that is, if there are only one or two bytes of input for the last 24-bit block), then the following action is performed:

Add extra bytes with value zero so there are three bytes, and perform the conversion to base64. If there was only one significant input byte, only the first two base64 digits are picked (12 bits), and if there were two significant input bytes, the first three base64 digits are picked (18 bits). '=' characters might be added to make the last block contain four base64 characters.

因此,由于您的最后一个块 (ent=) 包含单个 =,这意味着原始字节数组以 2 个字节或 16 位的块结束。

  • 前 6 位是数字 30,导致字符 e
  • 接下来的 6 位是数字 39,导致字符 n
  • 由于填充,剩下 4 个有效位后跟两个 0 位,因此应该导致偶数。然而你的第三个字符是 t,代表数字 45。45 是奇数。所以这意味着 ent= 不是有效的 base64 块。正确的 base64 编码器永远不会将任何字节序列编码为 ent=.

数字 45 在二进制中是 101101。但是由于只有前 4 位是重要的,正确的编码器应该使用它们并用两个 0 位填充它们,导致 101100,即数字 44,导致字母 s

因此,回顾一下,如果您正在解码的 base64 值是正确的 base64 值,您将永远不会遇到这样的“错误”。