base64编码
作用
在互聯(lián)網(wǎng)上傳輸二進制數(shù)據(jù)。在互聯(lián)網(wǎng)上傳輸非可打印字符時,可能會導致亂碼、不能被網(wǎng)關有效處理等問題,而可打印字符不會有這些問題。故將二進制字符轉為可打印字符就可以了。
原理
base64就是將3個8位的數(shù)據(jù),轉為4個6位的數(shù)據(jù)。轉換后的字符都是可打印字符。一般設置為"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"。當然,你可以根據(jù)自己的需求,使用別的可打印字符。
處理位數(shù)不足
如果要編碼的字節(jié)不是3的倍數(shù),就會剩余2個字節(jié)或1個字節(jié)
1. 2個字節(jié),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個字節(jié),8位,可以用2個6位表示,編碼后生成2個字符,最后四位用0填充
| 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 7 | 8 | 0 | 0 | 0 | 0 |
這樣還有一個問題,生成的字符要么3個,要么2個,不是4的倍數(shù)。一般,生成的字符數(shù)都對齊為4的倍數(shù)。所以,不夠的我們使用'='來填充
代碼
下面是參考nginx實現(xiàn)的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
總結
- 上一篇: 如何将真彩色图转换为各种灰度图
- 下一篇: 华为FusionSphere概述——计算