• 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
  • 相关阅读:
    【可能是】退役记
    cf3
    react使用antd的Autocomplate时,给onSearch运用lodash的防抖debounce不生效
    依赖项useEffect的执行顺序问题
    AppleDoc 介绍
    AppleDoc 安装步骤
    AppleDoc 使用介绍
    GetKernel32Moudle and GetProcAddress
    TLS回调函数无效
    新的博客地址
  • 原文地址:https://www.cnblogs.com/zuofaqi/p/9781251.html
Copyright © 2020-2023  润新知