Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。
一.原理
转码过程例子:
3*8 = 4*6
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机一个字节占8位,不够就自动补两个高位0了
所以有了高位补0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z
即zcEz就是s13的Base64编码
当然输入并不能保证每次都是 3 的倍数所以,当输入不是3的倍数时即采用补“=”的方法来解决。
当输入为2 个字符时,我们需要再末尾补齐一个=
当输入为1个字符时,补两个=
以此类推。。。
二.编码实现(C/C++)
Base64 编码表
索引
|
对应字符
|
索引
|
对应字符
|
索引
|
对应字符
|
索引
|
对应字符
|
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 encode and decode
//Authour:Michael Jiang
//Sun May 5 18:56:09 DST 2019
#include "cstdio"
#include "string"
#include "iostream"
using namespace std;
char bin_temp[4096];//存放二进制代码
int bin_len = 0;
int str_len = 0;
//Base64 编码表
char 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', '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', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
void to_bin(string str)
{
int char_index = 8;
for (string::iterator it = str.begin(); it != str.end(); it++)
{
char c = *it;
int offset = 0;
while (c)
{
if (c % 2 == 0)
bin_temp[char_index - offset] = 0;
else
bin_temp[char_index - offset] = 1;
c /= 2;
offset++;
}
bin_len = char_index;
char_index += 8;
}
str_len = str.length();
}
void to_bin(int str[])
{
int char_index = 6;
for (int i = 0; i < str_len; i++)
{
char c = str[i];
int offset = 0;
while (c)
{
if (c % 2 == 0)
bin_temp[char_index - offset] = 0;
else
bin_temp[char_index - offset] = 1;
c /= 2;
offset++;
}
bin_len = char_index;
char_index += 6;
}
}
//编码
string encode(string str)
{
int index = 6;
string out = "";//Base64 编码结果
to_bin(str);//将输入的字符串转成二进制存放再bin_temp[]中
for (int i = 1; i <= bin_len; i += 6)
{
int index = 5;
int c = 0;
for (int j = i; j <= i+5; j++)
{
c+=bin_temp[j] * pow(2, index--);
}
out += table[c];
}
//求出末尾 = 的个数
int s = str_len % 3;
if (s)
{
for (int i = 0; i < 3 - s; i++)
out += "=";
}
return out;
}
int find_code(char c)
{
for (int i = 0; i < 64; i++)
{
if (table[i] == c)
return i;
}
return -1;
}
//解码
string decode(string s)
{
int temp[2048];
char c;
int i = 0;
string str = "";
for (string::iterator it = s.begin(); it != s.end(); it++)
{
if (*it != '=')
{
str += *it;
}
}
for (string::iterator it = str.begin(); it != str.end(); it++)
{
c = find_code(*it);
temp[i++] = c;
}
str_len = i;
to_bin(temp);
string out = "";
for (int i = 1; i <= bin_len; i += 8)
{
int index = 7;
char c = 0;
for (int j = i; j <= i + 7; j++)
{
c += bin_temp[j] * pow(2, index--);
}
out += c;
}
return out;
}
int main()
{
string in = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
string out = encode(in);
cout <<"原始字符串:"<<in << endl;
cout <<"Base64编码:"<<out << endl;
cout << "Base64解码: "<<decode(out);
}
Github:https://github.com/MichaelJiang1997/base64
三.使用自带库(Python3)
Python直接导入base64包即可,使用起来还是比较方便的.
import base64
output = base64.b64encode(b"hello")
data = base64.b64decode(output)
print(output)
print(data)
四.Golang大法可否一战?当然!
// base64test
package main
import (
"encoding/base64"
"fmt"
)
func main() {
//encode
src := []byte(`hello`)
dst := base64.StdEncoding.EncodeToString(src)
fmt.Println(string(dst))
//decode
data, _ := base64.StdEncoding.DecodeString(string(dst))
fmt.Println(string(data))
}
配合官方手册使用:https://studygolang.com/pkgdoc
其他主流编程语言基本都有类似的官方库函数,只要参考手册进行调用即可,这里就不一一列举了。
插一句:话说我的LCD12864 五一带回去把针脚焊了一下,驱动库也找了一份,预计下周就可以进行测试了,蛤蛤!