1. C/C++
  2. Golang
  3. Python

Base64 编码实现

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 五一带回去把针脚焊了一下,驱动库也找了一份,预计下周就可以进行测试了,蛤蛤!