base64加密解密
什么是base64:base64是一种常见的用于传输8Bit字节码的编码方式,是一种基于64个可打印字符来表示二进制数据的方法。
base64所用的字符为A到Z、a到z、0到9、+号符和/号符,他的索引(下标)从0开始,具体如下转换对照所示:
索引 |
对应字符 |
索引 |
对应字符 |
索引 |
对应字符 |
索引 |
对应字符 |
0 |
A |
17 |
R |
34 |
i |
51 |
z |
1 |
B |
18 |
S |
35 |
j |
52 |
0 |
2 |
C |
19 |
T |
36 |
k |
53 |
1 |
3 |
D |
20 |
U |
37 |
l |
54 |
2 |
4 |
E |
21 |
V |
38 |
m |
55 |
3 |
5 |
F |
22 |
W |
39 |
n |
56 |
4 |
6 |
G |
23 |
X |
40 |
o |
57 |
5 |
7 |
H |
24 |
Y |
41 |
p |
58 |
6 |
8 |
I |
25 |
Z |
42 |
q |
59 |
7 |
9 |
J |
26 |
a |
43 |
r |
60 |
8 |
10 |
K |
27 |
b |
44 |
s |
61 |
9 |
11 |
L |
28 |
c |
45 |
t |
62 |
+ |
12 |
M |
29 |
d |
46 |
u |
63 |
/ |
13 |
N |
30 |
e |
47 |
v |
||
14 |
O |
31 |
f |
48 |
w |
||
15 |
P |
32 |
g |
49 |
x |
||
16 |
Q |
33 |
h |
50 |
y |
base64加密方法:
1、 首先将需要加密的明文的每个字符依次翻译为二进制的ASII码,取八位(不足八位前面填充0补充)
2 、然后将1中所有二进制组成一串长字符串,然后再将这个字符串以每六个为一组组成几个新的二进制数;如果最后一组二进制数不足六位,则在其后面加0凑成六位
3、最后将这些二进制依次转换为十进制,这些十进制对应base64转换表中的索引,根据这些索引获取对应的字符组成的字符串就是密文(密文的个数必须为4的倍数,可以将其分为每4个一组,最后一组不足4的话添加=号补充完整)
demo:
明文:AllenYu
1、首先将这个明文中的每个字符转换成二进制的ASII码(通过查询本文末尾处的ASII码对照表获取)
A -> 01000001
l -> 01101100
l -> 01101100
e -> 01100101
n -> 01101110
Y -> 01011001
u -> 01110101
2、 由1获得字符串:01000001011011000110110001100101011011100101100101110101
将这个字符串以每六个一组,组成新的二进制,然后再将这些二进制转换成十进制,最后以这些十进制为索引找到相应的字符
二进制: 010000 010110 110001 101100 011001 010110 111001 011001 011101 010000(最后一组补四个0)
十进制: 16 22 49 44 25 22 57 25 29 16
对应字符: Q W x s Z W 5 Z d Q
3、 由2得到编码:QWxs ZW5Z dQ 每4个一组,不足四个补=号 得到最终加密后的密文QWxsZW5ZdQ==
base64解密方法:
1、 首先将base64加密后需要进行解密的密文(如末尾的有=号,将=号删除)的每个字符通过base64转换表找到索引,然后将这些索引转换为六位的二进制数(不足六位前面补充,凑足六位)
2、 然后将1中所有二进制组成一个字符串,将这个字符串以每8个为一组,组成几个新的二进制数;如果最后一组不足8个,则这组全部删除(字符长度取模8得到余数,末尾去除这个余数相应的个数的字符)
3、 通过查找ASII码对照表,找到2中所有二进制所对应的字符,这些字符就是解密后的明文
demo:
密文:QWxsZW5ZdQ==
1、 将结尾的两个=去除,并通过字符去编码表找到对应下标并转换为二进制(六位的)
字符: Q W x s Z W 5 Z d Q
对应索引: 16 22 49 44 25 22 57 25 29 16
索引对应二进制: 010000 010110 110001 101100 011001 010110 111001 011001 011101 010000
2、由1得到字符串:010000010110110001101100011001010110111001011001011101010000
每八个一组,组成多个二进制(最后一组不足八个的话,最后一组删除)
01000001 01101100 01101100 01100101 01101110 01011001 01110101 0000
最后一组只有四个字符,删除
二进制: 01000001 01101100 01101100 01100101 01101110 01011001 01110101
ASII码十进制: 65 108 108 101 110 89 117
对应ASII码字符:A l l e n Y u
得到最终解密明文:AllenYu
附:Java实现base64加密解密代码
/**
* base64 字典,编码表
*/
public static java.util.List<Character> getDictionaries() {
java.util.List<Character> dictionaries = new ArrayList<>();
dictionaries.add('A');
dictionaries.add('B');
dictionaries.add('C');
dictionaries.add('D');
dictionaries.add('E');
dictionaries.add('F');
dictionaries.add('G');
dictionaries.add('H');
dictionaries.add('I');
dictionaries.add('J');
dictionaries.add('K');
dictionaries.add('L');
dictionaries.add('M');
dictionaries.add('N');
dictionaries.add('O');
dictionaries.add('P');
dictionaries.add('Q');
dictionaries.add('R');
dictionaries.add('S');
dictionaries.add('T');
dictionaries.add('U');
dictionaries.add('V');
dictionaries.add('W');
dictionaries.add('X');
dictionaries.add('Y');
dictionaries.add('Z');
dictionaries.add('a');
dictionaries.add('b');
dictionaries.add('c');
dictionaries.add('d');
dictionaries.add('e');
dictionaries.add('f');
dictionaries.add('g');
dictionaries.add('h');
dictionaries.add('i');
dictionaries.add('j');
dictionaries.add('k');
dictionaries.add('l');
dictionaries.add('m');
dictionaries.add('n');
dictionaries.add('o');
dictionaries.add('p');
dictionaries.add('q');
dictionaries.add('r');
dictionaries.add('s');
dictionaries.add('t');
dictionaries.add('u');
dictionaries.add('v');
dictionaries.add('w');
dictionaries.add('x');
dictionaries.add('y');
dictionaries.add('z');
dictionaries.add('0');
dictionaries.add('1');
dictionaries.add('2');
dictionaries.add('3');
dictionaries.add('4');
dictionaries.add('5');
dictionaries.add('6');
dictionaries.add('7');
dictionaries.add('8');
dictionaries.add('9');
dictionaries.add('+');
dictionaries.add('/');
return dictionaries;
}
/**
* base64加密
*
* @param code 明文
* @return
*/
public static String enCode(String code) {
java.util.List<Character> pem_array = getDictionaries();
char[] codes = code.toCharArray();
StringBuffer binaryCode = new StringBuffer();
for (char c : codes) {
int asii = (int) c;
String binary = Integer.toBinaryString(asii);
for (int i = binary.length(); i < 8; i++) {
binary = "0" + binary;
}
binaryCode.append(binary);
}
StringBuffer str = new StringBuffer();
int binaryMode = binaryCode.length() % 6;
if (binaryMode != 0) {
for (int i = binaryMode; i < 6; i++) {
binaryCode.append(0);
}
}
for (int i = 0, j = 0; j < binaryCode.length() / 6; j++) {
String binaryString = binaryCode.substring(i, i += 6);
int decimalism = Integer.parseInt(binaryString, 2);
str.append(pem_array.get(decimalism));
}
binaryMode = binaryCode.length() / 6 % 4;
if (binaryMode != 0) {
for (int i = binaryMode; i < 4; i++) {
str.append("=");
}
}
return str.toString();
}
/**
* base64 解密
*
* @param code 密文
* @return
*/
public static String deCode(String code) {
StringBuffer res = new StringBuffer();
List<Character> pem_array = getDictionaries();
while (code.lastIndexOf('=') == code.length() - 1) {
code = code.substring(0, code.length() - 1);
}
StringBuffer deStr = new StringBuffer();
for (int i = 0; i < code.length(); i++) {
int index = pem_array.indexOf(code.charAt(i));
String deCode = Integer.toBinaryString(index);
for (int j = deCode.length(); j < 6; j++) {
deCode = "0" + deCode;
}
deStr.append(deCode);
}
int binaryMode = deStr.length() % 8;
String deStrs = deStr.substring(0, deStr.length() - binaryMode);
for (int i = 0, j = 0; j < deStrs.length() / 8; j++) {
int decimalism = Integer.parseInt(deStrs.substring(i, i += 8), 2);
res.append((char) decimalism);
}
return res.toString();
}
附:ASCll码对照表(来源:http://ascii.911cha.com/)
ASCII控制字符
二进制 | 十进制 | 十六进制 | 缩写 | 可以显示的表示法 | 名称/意义 |
---|---|---|---|---|---|
0000 0000 | 0 | 00 | NUL | ␀ | 空字符(Null) |
0000 0001 | 1 | 01 | SOH | ␁ | 标题开始 |
0000 0010 | 2 | 02 | STX | ␂ | 本文开始 |
0000 0011 | 3 | 03 | ETX | ␃ | 本文结束 |
0000 0100 | 4 | 04 | EOT | ␄ | 传输结束 |
0000 0101 | 5 | 05 | ENQ | ␅ | 请求 |
0000 0110 | 6 | 06 | ACK | ␆ | 确认回应 |
0000 0111 | 7 | 07 | BEL | ␇ | 响铃 |
0000 1000 | 8 | 08 | BS | ␈ | 退格 |
0000 1001 | 9 | 09 | HT | ␉ | 水平定位符号 |
0000 1010 | 10 | 0A | LF | ␊ | 换行键 |
0000 1011 | 11 | 0B | VT | ␋ | 垂直定位符号 |
0000 1100 | 12 | 0C | FF | ␌ | 换页键 |
0000 1101 | 13 | 0D | CR | ␍ | 归位键 |
0000 1110 | 14 | 0E | SO | ␎ | 取消变换(Shift out) |
0000 1111 | 15 | 0F | SI | ␏ | 启用变换(Shift in) |
0001 0000 | 16 | 10 | DLE | ␐ | 跳出数据通讯 |
0001 0001 | 17 | 11 | DC1 | ␑ | 设备控制一(XON 启用软件速度控制) |
0001 0010 | 18 | 12 | DC2 | ␒ | 设备控制二 |
0001 0011 | 19 | 13 | DC3 | ␓ | 设备控制三(XOFF 停用软件速度控制) |
0001 0100 | 20 | 14 | DC4 | ␔ | 设备控制四 |
0001 0101 | 21 | 15 | NAK | ␕ | 确认失败回应 |
0001 0110 | 22 | 16 | SYN | ␖ | 同步用暂停 |
0001 0111 | 23 | 17 | ETB | ␗ | 区块传输结束 |
0001 1000 | 24 | 18 | CAN | ␘ | 取消 |
0001 1001 | 25 | 19 | EM | ␙ | 连接介质中断 |
0001 1010 | 26 | 1A | SUB | ␚ | 替换 |
0001 1011 | 27 | 1B | ESC | ␛ | 跳出 |
0001 1100 | 28 | 1C | FS | ␜ | 文件分割符 |
0001 1101 | 29 | 1D | GS | ␝ | 组群分隔符 |
0001 1110 | 30 | 1E | RS | ␞ | 记录分隔符 |
0001 1111 | 31 | 1F | US | ␟ | 单元分隔符 |
0111 1111 | 127 | 7F | DEL | ␡ | 删除 |
ASCII可显示字符
|
|
|