-
base64不是加密,就是一种编码,将字符串的二进制按6个bit一组,每组的6个bit的形式转换一下。
-
每组6个bit对应的字符是 有特定的映射表决定。
映射表:
| 字符 | 序号 |
|---|---|
| A-Z | 序号0-25 |
| a-z | 序号26-51 |
| 0-9 | 序号52-61 |
| + | 序号62 |
| / | 序号63 |
-
都转成以上5种,目的是为了网络传输没有特殊字符。
-
标准base64 不适合url中直接传输; safe_base64的做法是把最后那俩字符 +和/ 替换成 -_ 即可。解析的时候反向替换之后再base64解码。
-
因为http传输,+号会被服务器解析成空格, 导致解析base64字符串失败。当然可以对传输的base64字符串进行url编码在传输, nginx会自动url解码。
-
c语言实现编码(3个byte拆分成4个byte):
-
3个字节一次循环正好拆为4个字符,如果循环剩余1个字符,需要补2个=,如果剩余2个字符,需要补1个=。每个=是6位,凑成8位的倍数,因为网络传输是按8位一组传输的,所以必须是总bit数必须是8的倍数。
#include#include #include char* base64_encode(const char *p, int length, char **output, int *dlen){ static const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int j = 0; int flag = 0; const char *str = p; int insize = length; char * dst = *output; int i = 0; while(i < insize){ unsigned char c1 = (unsigned char) *str++; i++; c1 = c1 & 0xff ; if(i == insize){ snprintf(*output, 5, "%c%c==",base[((c1 & 0xfc) >> 2)], base[((c1 & 0x03) << 4)]); *output +=4; break; } unsigned char c2 = (unsigned char) *str++; i++; if(i == insize){ snprintf(*output, 5, "%c%c%c=",base[((c1 & 0xfc) >> 2)], base[(((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4))], base[((c2 & 0x0f) << 2)]); *output +=4; break; } unsigned char c3 = (unsigned char) *str++; i++; snprintf(*output, 5, "%c%c%c%c",base[((c1 & 0xfc) >> 2)], base[(((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4))], base[(((c2 & 0x0f) << 2) | ((c3 & 0xc0) >>6))], base[(c3 & 0x3f)]); *output +=4; } **output = ' '; *dlen = strlen(dst); return dst; } int find_index(unsigned char c){ static const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int i = 0; int ret = 0; for(i=0; i< 64; i++){ if(base[i] == c){ ret = i; break; } } return ret; } char* base64_decode(const char *src, int len, char **output, int *dlen){ char *str = (char*)src; int i = 0; char *dst = *output; while(i < len){ int arr[4] = {0}; int k = 0; while(k<4){ char tmp = *str++; if(tmp != '='){ arr[k] = find_index(tmp); } k++; } i+=4; //printf("%d, %d,%d,%dn",arr[0],arr[1],arr[2],arr[3] ); unsigned char o1 = ((arr[0]<<2) | (arr[1] & 0x30) >>4); unsigned char o2 = (((arr[1] & 0x0f) << 4) | ((arr[2] & 0x3c) >>2)); unsigned char o3 = (((arr[2] & 0x03) << 6) | arr[3]); snprintf(*output, 4, "%c%c%c", o1,o2,o3); //printf("%c,%c,%cn", o1,o2,o3); *output+=3; } //printf("%s n", base64); *dlen = strlen(dst); return dst; } int main(int argc, char* argv[]){ if(argc != 3){ printf("提示: 输入加密选项-d或-e, 和待加密解密的参数"); exit(-1); } if(!strcmp(argv[1], "-e")){ int len = strlen(argv[2]); char *output = (char*)malloc(((len+2)/3)*4); char *encode_str = output; int dlen = 0; base64_encode(argv[2], len, &output, &dlen); printf("字符串:%sn", argv[2]); printf("base64编码: %sn", encode_str); free(encode_str); }else if(!strcmp(argv[1],"-d")){ //const char * encode_str = "aGVsbG93b3JsZA=="; // helloworld char *encode_str = argv[2]; int len = strlen(encode_str); char *output = (char *)malloc(((len+3) /4) *3); char *decode_str = output; int dlen = 0; base64_decode(encode_str, len, &output, &dlen); printf("base64解码: %sn", decode_str); free(decode_str); }else{ printf("命令选项错误: -[de]n"); } return 0; }
- lua ffi编译
cd /usr/local/openresty/lualib/base64 gcc -o base64.so -fpic -shared base64.c
- openresty 接口调用
local ffi = require "ffi"
local base64 = ffi.load("/usr/local/openresty/lualib/base64/base64.so")
ffi.cdef[[
int base64_encode(const char *p, int length, char **output, int *dlen);
int base64_decode(const char *src, int len, char **output, int *dlen);
]]
local c_char = ffi.typeof("char[?]")
local c_int = ffi.typeof("int[?]")
local function base64_encode(s)
local buf = ffi.new(c_char, ((#s+2) / 3 ) * 4)
local buf1= ffi.new("char *[1]", buf) -- 二级指针,如果不修改指针指向,用一级指针即可。
local dlen = ffi.new(c_int, 1) -- ffi.new("int[1]")
local encode_str = base64.base64_encode(s, #s, buf1, dlen)
return ffi.string(buf, dlen[0])
end
local function base64_decode(s)
local buf = ffi.new(c_char, ((#s+3) / 4 ) * 3)
local buf1= ffi.new("char *[1]", buf) -- 二级指针,如果不修改指针指向,用一级指针即可。
local dlen = ffi.new(c_int, 1) -- ffi.new("int[1]")
local encode_str = base64.base64_decode(s, #s, buf1, dlen)
return ffi.string(buf, dlen[0])
end
local encode = base64_encode("真的很用容易去调用一个外部 C 库函数,示例代码")
ngx.say(encode)
local decode = base64_decode(encode)
ngx.say(decode)
--[[
output:
55yf55qE5b6I55So5a655piT5Y676LCD55So5LiA5Liq5aSW6YOoIEMg5bqT5Ye95pWw77yM56S65L6L5Luj56CB
真的很用容易去调用一个外部 C 库函数,示例代码
]]--
暑期编程PK赛
得CSDN机械键盘等精美礼品!


