使用Java中的JCA(Java Cryptography Architecture)做加密、解密、签名、验签、消息摘要等操作时,由于它们的输出和输入大多是byte数组,对于数据的存储交换不是太友好。平常的使用习惯,一般是转换成十六进制或Base64编码进行存储和交换。
在网上搜索有关java中Base64和十六进制转码工具时,发现很多开发者自己写了转换工具。what ? 难道jdk中没有现成的吗?
不喜欢重复制造轮子,所以就想找一下jdk中提供的Base64 和 十六进制转码工具。好在运气不错,现把找到的工具记录如下,以备后用。
十六进制转换工具 (HexBinaryAdapter
,DatatypeConverter
,BigInteger
)
HexBinaryAdapter
HexBinaryAdapter
的 全类名为:javax.xml.bind.annotation.adapters.HexBinaryAdapter
。
HexHexBinaryAdapter
中提供了两个方法,marshal
,unmarshal
。
public String marshal(byte[] bytes);
把 byte 数据转换成十六进制的字符串表示。public byte[] unmarshal(String s);
字符串表示的十六进制数据转换成 byte 数组。
DatatypeConverter
DatatypeConverter
的全类名为:javax.xml.bind.DatatypeConverter
。
DatatypeConverter
并不单单是为十六进制而生的,看名字就知道它是为数据类型转换而生的。其实在 HexHexBinaryAdapter
中也是调用了这个工具进行的十六进制字符串与byte数组之间的转换。
DatatypeConverter
中的方法分为两类:printXXXX
和 parseXXYY
。其中printXXYY
是把YY
类型的数据转字符串表示的XX
类型数据,而parseXXYY
是把字符串表示的YY
类型数据转换为XX
类型数据。这里重点说四个方法:
public static String printHexBinary( byte[] val );
把byte数组转换成字符串表示的十六进制数据。public static String printBase64Binary( byte[] val );
把byte数组转换成Base64编码的字符串。public static byte[] parseHexBinary( String lexicalXSDHexBinary );
把字符串形式的十六进制数据转换成byte数组public static byte[] parseBase64Binary( String lexicalXSDBase64Binary );
把Base64编码的字符串转换成byte数组
BigInteger
BigInteger
的全类名为java.math.BigInteger
。
它有一个方法 public String toString(int radix)
可以把当前“大数”转换为任意进制(2-36)的字符串。并且BigInteger
有一个构造方法public BigInteger(int signum, byte[] magnitude)
可以把一个byte
数据组构造成一个“正整大数”。利用这些特性可以把一个byte
数据转换成十六进制字符串。
new BigInteger(1,bytes).toString(16);
当需要把十六进制字符串转换为byte
数组时,可以使用构造函数public BigInteger(String val, int radix)
实例化一个大数,然后调用public byte[] toByteArray()
方法。
// 这里需要注意,当最高位不为0时,得到byte数组最高位会多出一个byte
new BigInteger(str,16).toByteArray();
推荐使用这种方式把 bytes 数组转换为16进制。
Base64转换工具(java.util.Base64
,sun.misc.BASE64Decoder
,sun.misc.BASE64Encoder
,DatatypeConverter
)
其中 DatatypeConverter 已经介绍过。而BASE64Decoder 和 BASE64Encoder 是一对,Base64中也有两个Encoder和Decoder内部类。
-
Base64.getDecoder()
得到内部类Decoder的实例,支持的方法如下图所示,我们常用的应该是public byte[] decode(String src);
-
Base64.getEncoder()
得到内部类Encoder的实例,支持的方法如下图所示,我们常用的应该是public String encodeToString(byte[] src)
。
-
BASE64Encoder
中的可用方法如下图所示,我们常用的应该是public String encode(byte[] src);
-
BASE64Decoder
中的可用方法如下图所示,我们常用的应该是public byte[] decodeBuffer(String src) throws IOException;
总结
对于Base64的编码与解码,Base64的输入和输出不仅支持字符串,还可以是byte数组,输入/输出流等。可根据实际应用灵活选择。