IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    nginx模块开发(44)—base64算法加解密

    cjhust发表于 2015-01-29 15:03:35
    love 0

    1、知识百科

    Base64 使用US-ASCII子集的64个字符,即大小写的26个英文字母、0~9以及+、/。

    编码总是基于3个字符,每个字符用8位二进制表示,因此一共24位,再分为4组,每组6位,表示一个Base64的值。如下:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/。

    Base64值为0就是A,为27的就是b,每3个字符产生4位的Base64字符,如果被加密的字符串每3个一组,还剩1或2个字符,使用特殊字符"="补齐Base64的4字。如编码只有2个字符“me”,m的ascii是109,e的是101,用二进制表示分别是01101101、01100101,连接起来就是0110110101100101,再按6位分为一组:011011、010110、010100(不足6位补0),分别ascii分别是27、22、20,即Base64值为bWU,Base64不足4字,用=补齐,因此bWU=就me的Base64值。

    Base64的主要功能是可以把二进制文件和文本文件进行相互转换,用于使仅能以文本方式进行传输和存储的系统能够处理二进制文件,比如在某些只能使用文本方式的Email系统和不能够上传附件的论坛和BBS等上面使用二进制文件。

    Base64加密内容是肯定的,但是加密的目的不是让用户发送非常安全的Email,这种加密方式主要就是“防君子不防小人”,即达到一眼望去完全看不出内容即可。

    image

    2、具体实现

    ngx_encode_base64

    void

    ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)

    {

    static u_char basis64[] =

    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    ngx_encode_base64_internal(dst, src, basis64, 1);

    }

    ngx_encode_base64_internal

    static void

    ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis,

    ngx_uint_t padding)

    {

    u_char *d, *s;

    size_t len;

    len = src->len;

    s = src->data;

    d = dst->data;

    //3个byte-------->4个byte

    while (len > 2) {

    *d++ = basis[(s[0] >> 2) & 0x3f]; // 0x3f=00111111,第1个字符的前6bit

    *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)]; //第1个字符的后2bit,和第2个字符的前4bit

    *d++ = basis[((s[1] & 0x0f) << 2) | (s[2] >> 6)]; //第2个字符的后4bit和第3个字符的前2bit

    *d++ = basis[s[2] & 0x3f]; //第3个字符的后6bit

    s += 3;

    len -= 3;

    }

    //’d’=01100100,比如helloworld=aGVs bG93 b3Js ZA==

    if (len) {

    *d++ = basis[(s[0] >> 2) & 0x3f]; //第1个字符的前6bit=11001=25=’Z’

    if (len == 1) { //len=1,共8bit

    *d++ = basis[(s[0] & 3) << 4]; //第1个字符的后2bit=0=’A’

    if (padding) {

    *d++ = '='; //=

    }

    } else { //len=2,共8*2=16bit

    *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];

    *d++ = basis[(s[1] & 0x0f) << 2];

    }

    if (padding) {

    *d++ = '='; //=

    }

    }

    dst->len = d - dst->data;

    }

    ngx_decode_base64

    ngx_int_t

    ngx_decode_base64(ngx_str_t *dst, ngx_str_t *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

    };

    return ngx_decode_base64_internal(dst, src, basis64);

    }

    ngx_decode_base64_internal

    static ngx_int_t

    ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis)

    {

    size_t len;

    u_char *d, *s;

    for (len = 0; len < src->len; len++) {

    if (src->data[len] == '=') {

    break;

    }

    if (basis[src->data[len]] == 77) {

    return NGX_ERROR;

    }

    }

    if (len % 4 == 1) {

    return NGX_ERROR;

    }

    s = src->data;

    d = dst->data;

    while (len > 3) {

    *d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);

    *d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);

    *d++ = (u_char) (basis[s[2]] << 6 | basis[s[3]]);

    s += 4;

    len -= 4;

    }

    if (len > 1) {

    *d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);

    }

    if (len > 2) {

    *d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);

    }

    dst->len = d - dst->data;

    return NGX_OK;

    }

    3、参考资料

    http://blog.163.com/gaoguangtao_love/blog/static/38483715201242984016259/



沪ICP备19023445号-2号
友情链接