base64到十六进制不一致结果

时间:2015-09-11 14:58:56

标签: java hex base64

昨天,我在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

1 个答案:

答案 0 :(得分:3)

base64 algorithm说:

  

当要编码的字节数不能被3整除时(也就是说,如果最后一个24位块只有一个或两个字节的输入),则执行以下操作:

     

添加值为零的额外字节,因此有三个字节,并执行到base64的转换。如果只有一个有效输入字节,则只选择前两个base64数字(12位),如果有两个有效输入字节,则选择前三个base64数字(18位)。可以添加'='字符以使最后一个块包含四个base64字符。

因此,由于您的上一个块(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。 / p>

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