Apache Codec Base32 加密/解密

本文将介绍怎样利用 Apache Codec 的 Base32 类对 Base32 编码进行加密和解密操作。

Apache Codec 提供了 org.apache.commons.codec.binary.Base32 类实现 BASE32 加密和解密。

Base32 类提供 RFC4648 定义的 base32 编码和解码。可以使用各种构造函数以下列方式对该类进行参数化:

a、是否使用“base32hex”变量而不是默认的“base32”

b、行长:默认为76。在编码的数据中,不是8倍的行长度实际上仍然是8的倍数。

c、行分隔符:默认为 CRLF (“\r\n”)

这个类直接操作字节流,而不是字符流。

示例代码

(1)使用 Base32 默认构造方法创建 Base32 对象,然后进行加密解密操作。代码如下:

package com.huangx.codec.base32;

import org.apache.commons.codec.binary.Base32;

public class Base32Demo {

    public static void main(String[] args) {
        Base32 base32 = new Base32();

        // 加密
        byte[] bytes = base32.encode("hello world".getBytes());
        System.out.println(new String(bytes));

        // 解密
        System.out.println(new String(base32.decode(bytes)));
    }

}

运行上面程序,输出结果如下:

NBSWY3DPEB3W64TMMQ======
hello world

其中,“=”是填充符号,我们可以通过 pad 参数进行指定。如下:

package com.huangx.codec.base32;

import org.apache.commons.codec.binary.Base32;

public class Base32Demo1 {

    public static void main(String[] args) {
        Base32 base32 = new Base32((byte)'#');

        // 加密
        byte[] bytes = base32.encode("hello world".getBytes());
        System.out.println(new String(bytes));

        // 解密
        System.out.println(new String(base32.decode(bytes)));
    }

}

再次运行,输出结果如下:

NBSWY3DPEB3W64TMMQ######
hello world

(2)使用带有 useHex 参数的构造方法创建 Base32 对象,如果我们使用 useHex = true,则将使用十六进制字符表。先看 Base32 构造方法的部分代码:

if (useHex) {
    this.encodeTable = HEX_ENCODE_TABLE;
    this.decodeTable = HEX_DECODE_TABLE;
} else {
    this.encodeTable = ENCODE_TABLE;
    this.decodeTable = DECODE_TABLE;
}

上面代码根据 useHex 不同,选择不同的解码和编码字符表。其中:HEX_ENCODE_TABLE、HEX_DECODE_TABLE、ENCODE_TABLE 和 DECODE_TABLE 定义如下:

// 该数组是一个查找表,用于将5位正整数索引值转换为 “Base32十六进制字母表” 等效于RFC4648的表4
private static final byte[] HEX_ENCODE_TABLE = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
};
// 这个数组是一个查找表,它将从“Base32十六进制字母表”(如RFC 4648的表4中所指定的)提取的Unicode字符转换为对应的5位正整数。
// 不在Base32十六进制字母表但在数组范围内的字符将被转换为-1。
private static final byte[] HEX_DECODE_TABLE = {
     //  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20-2f
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, // 30-3f 2-7
        -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 40-4f A-O
        25, 26, 27, 28, 29, 30, 31,                                     // 50-56 P-V
                                    -1, -1, -1, -1, -1, -1, -1, -1, -1, // 57-5f Z-_
        -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 60-6f `-o
        25, 26, 27, 28, 29, 30, 31                                      // 70-76 p-v
};
// 这个数组是一个查找表,它将5位正整数索引值转换为RFC 4648的表3中指定的“Base32字母表”等量值。
private static final byte[] ENCODE_TABLE = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        '2', '3', '4', '5', '6', '7',
};
// 这个数组是一个查找表,它将从“Base32字母表”(如RFC 4648的表3中所指定的)提取的Unicode字符转换为对应的5位正整数。
// 不在Base32字母表但在数组范围内的字符将被转换为-1。
private static final byte[] DECODE_TABLE = {
     //  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20-2f
        -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, // 30-3f 2-7
        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, // 40-4f A-O
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,                     // 50-5a P-Z
                                                    -1, -1, -1, -1, -1, // 5b - 5f
        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, // 60 - 6f a-o
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,                     // 70 - 7a p-z/**/
};

因此,使用 useHex = true 和 useHex = false 加密出来的密文是不一样的。示例代码如下:

package com.huangx.codec;

import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;

public class Base32Demo2 {

    public static void main(String[] args) {
        String str = "hello world";
        Base32 base32;

        // 加密
        base32 = new Base32(false);
        byte[] bytes = base32.encode(str.getBytes());
        System.out.println(Hex.encodeHexString(bytes));

        // 加密
        base32 = new Base32(true);
        bytes = base32.encode(str.getBytes());
        System.out.println(Hex.encodeHexString(bytes));
    }

}

运行上面程序,将输出如下结果:

4e42535759334450454233573634544d4d513d3d3d3d3d3d
4431494d4f5233463431524d55534a4343473d3d3d3d3d3d

(3)使用指定 lineLength 的构造方法创建 Base32。其中,lineLength 用于指定每一行编码数据最多为给定长度 (四舍五入至最接近的倍数为8)。如果 lineLength<=0,则输出不会被划分为行(块)。解码时忽略。例如:

package com.huangx.codec;

import org.apache.commons.codec.binary.Base32;

public class Base32Demo3 {

    public static void main(String[] args) {
        Base32 base32 = new Base32(16);

        // 加密
        byte[] bytes = base32.encode("hi, welcome administrator".getBytes());
        System.out.println(new String(bytes));

        // 解密
        System.out.println(new String(base32.decode(bytes)));
    }

}

运行上面程序,输出结果如下:

NBUSYIDXMVWGG33N
MUQGCZDNNFXGS43U
OJQXI33S

hi, welcome administrator

可以看到,Base32 编码结果按照指定的 lineLength 进行换行显示(插入 CRLF 字符)。

(4)使用 lineSeparator 指定每一行编码的数据都将以这个字节序列结束。例如:使用“%%”符号作为行结束符

package com.huangx.codec.base32;

import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;

public class Base32Demo4 {

    public static void main(String[] args) {
        Base32 base32 = new Base32(16, "%%".getBytes());

        // 加密
        byte[] bytes = base32.encode("hi, welcome administrator".getBytes());
        System.out.println(new String(bytes));

        // 解密
        System.out.println(new String(base32.decode(bytes)));
    }

}

运行上面程序,输出结果如下:

NBUSYIDXMVWGG33N%%MUQGCZDNNFXGS43U%%OJQXI33S%%
hi, welcome administrator

如果你指定的 lineSeparator 包含 base32 字符时抛出 IllegalArgumentException 异常。

「资源下载」

不傲才以骄人,不以宠而作威。——诸葛亮
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号