base64

base64

  • base64算法学习

    原理

编码

base64将每3个字节扩充为4个字节,就是 把3个字节分为4份,然后每份前面用00填充。

10101010 10101010 10101010==>00101010 00101010 00101010 00101010

那么,得到的字节范围在0~63 ,根据规范给出的Base64索引表,将0~63 这64个数字转换成ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的一个。

若是原字节数不是3的倍数,那么空缺的地方用00补,少一个字节(源字符串)加一个=,少两个字节加两个.

10101112 10121314==>00101011 00121012 00131400+=

解码

解码是编码的反向过程,每次取出4个字节,然后将每个字节的字符转换成原始Base64索引表对应的索引数字。然后使用位操作将每字节前2位去掉,重新转换成3字节。需要注意的是最后对于结尾“=”的处理

代码实现

ENCODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
static char base64_index[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";   

char *base64_encode(const char *input, const size_t length, char *output)
{
*output = '\0';
if (input == NULL || length < 1) return output;

char *p = (char*)input;
char *p_dst = (char*)output;;
char *p_end = (char*)input + length;
int loop_count = 0;

// 0x30 -> 00110000
// 0x3C -> 00111100
// 0x3F -> 00111111
while (p_end - p >= 3) {
*p_dst++ = base64_index[( p[0] >> 2 )];
*p_dst++ = base64_index[( (p[0] << 4) & 0x30 ) | ( p[1] >> 4 )];
*p_dst++ = base64_index[( (p[1] << 2) & 0x3C ) | ( p[2] >> 6 )];
*p_dst++ = base64_index[p[2] & 0x3F];
p += 3;
}

if (p_end - p > 0) {
*p_dst++ = base64_index[(p[0] >> 2)];
if (p_end - p == 2) {
*p_dst++ = base64_index[( (p[0] << 4) & 0x30 ) | ( p[1] >> 4 )];
*p_dst++ = base64_index[(p[1] << 2) & 0x3C];
*p_dst++ = '=';
} else if (p_end - p == 1) {
*p_dst++ = base64_index[(p[0] << 4) & 0x30];
*p_dst++ = '=';
*p_dst++ = '=';
}
}

*p_dst = '\0';
return output;
}

DECODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 16 * 16  
static int base64_decode_map[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32 - 47
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48 - 63
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64 - 79
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80 - 95
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96 - 111
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112 - 127
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 - 143
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144 - 159
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160 - 175
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176 - 191
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192 - 207
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208 - 223
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224 - 239
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 240 - 255
};

char *base64_decode(const char* input, char *output)
{
output[0] = '\0';
if (input == NULL || output == NULL)
return output;

int input_len = strlen(input);
if (input_len < 4 || input_len % 4 != 0)
return output;

// 0xFC -> 11111100
// 0x03 -> 00000011
// 0xF0 -> 11110000
// 0x0F -> 00001111
// 0xC0 -> 11000000
char *p = (char*)input;
char *p_out = output;
char *p_end = (char*)input + input_len;
for (; p < p_end; p += 4) {
*p_out++ = ((base64_decode_map[p[0]] << 2) & 0xFC) | ((base64_decode_map[p[1]] >> 4) & 0x03);
*p_out++ = ((base64_decode_map[p[1]] << 4) & 0xF0) | ((base64_decode_map[p[2]] >> 2) & 0x0F);
*p_out++ = ((base64_decode_map[p[2]] << 6) & 0xC0) | (base64_decode_map[p[3]]);
}

if (*(input + input_len - 2) == '=') {
*(p_out - 2) = '\0';
} else if (*(input + input_len - 1) == '=') {
*(p_out - 1) = '\0';
}

return output;
}

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. base64
    1. 1.1. 原理
      1. 1.1.1. 编码
      2. 1.1.2. 解码
    2. 1.2. 代码实现
      1. 1.2.1. ENCODE
      2. 1.2.2. DECODE
载入天数...载入时分秒...