base64编码

作用

在互联网上传输二进制数据。在互联网上传输非可打印字符时,可能会导致乱码、不能被网关有效处理等问题,而可打印字符不会有这些问题。故将二进制字符转为可打印字符就可以了。

原理

base64就是将3个8位的数据,转为4个6位的数据。转换后的字符都是可打印字符。一般设置为"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"。当然,你可以根据自己的需求,使用别的可打印字符。

处理位数不足

如果要编码的字节不是3的倍数,就会剩余2个字节或1个字节

1. 2个字节,16位,可以用3个6位来表示,这样编码后生成3个字符,最后两位用0填充

0 0 1 2 3 4 5 6 0 0 7 8 9 10 11 12 0 0 13 14 15 16 0 0

2. 1个字节,8位,可以用2个6位表示,编码后生成2个字符,最后四位用0填充

0 0 1 2 3 4 5 6 0 0 7 8 0 0 0 0

这样还有一个问题,生成的字符要么3个,要么2个,不是4的倍数。一般,生成的字符数都对齐为4的倍数。所以,不够的我们使用'='来填充

代码

下面是参考nginx实现的base64编码和解码


#include <stdio.h> #include <stdlib.h> #include <string.h> void base64_encode(u_char* dst, const u_char* src) { char basis[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int len = strlen((char*)src); while (len > 2) { *dst++ = basis[(src[0] >> 2) & 0x3f]; *dst++ = basis[((src[0] & 3) << 4) | (src[1] >> 4)]; *dst++ = basis[((src[1] & 0x0f) << 2) | (src[2] >> 6)]; *dst++ = basis[src[2] & 0x3f]; src += 3; len -= 3; } if (len == 1) { *dst++ = basis[src[0] >> 2]; *dst++ = basis[(src[0] & 0x3) << 4]; *dst++ = '='; *dst++ = '='; } if (len == 2) { *dst++ = basis[src[0] >> 2]; *dst++ = basis[((src[0] & 3) << 4) | (src[1] >> 4)]; *dst++ = basis[(src[1] & 0xf) << 2]; *dst++ = '='; } *dst = ''; } int base64_decode(u_char* dst, const u_char* src) { static u_char basis64[] = { 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77, 77, 0, 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, 77, 77, 77, 77, 77, 77, 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, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }; int srclen = strlen((char*)src); int len = 0; for (; len < srclen; len++) { if (src[len] == '=') { break; } if (basis64[src[len]] == 77) { return -1; } } if ((len >> 2) == 1) { return -1; } while (len > 3) { *dst++ = (u_char)((basis64[src[0]] << 2) | (basis64[src[1]] >> 4)); *dst++ = (u_char)((basis64[src[1]] << 4) | (basis64[src[2]] >> 2)); *dst++ = (u_char)((basis64[src[2]] << 6) | basis64[src[3]]); src += 4; len -= 4; } if (len > 1) { *dst++ = (u_char)((basis64[src[0]] << 2) | (basis64[src[1]] >> 4)); } if (len > 2) { *dst++ = (u_char)((basis64[src[1]] << 4) | (basis64[src[2]] >> 2)); } *dst = ''; } int main(int argc, char **argv) { u_char szencode[100] = {0}; u_char szdecode[100] = {0}; base64_encode(szencode, (u_char*)argv[1]); printf("%s ", szencode); base64_decode(szdecode, szencode); printf("%s ", szdecode); return 0; }


./a.out 'test测试english和and中文chinese'
dGVzdOa1i+ivlWVuZ2xpc2jlkoxhbmTkuK3mlodjaGluZXNl
test测试english和and中文chinese
原文地址:https://www.cnblogs.com/zuofaqi/p/9781251.html