base64加密解密

1.定义

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。

2.原理

转码过程例子:
3*8=4*6
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机是8位8位的存数 6不够,自动就补两个高位0了
所有有了 高位补0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z


  先以“迅雷下载”为例: 很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
其实迅雷的“专用地址”也是用Base64"加密"的,其过程如下:
一、在地址的前后分别添加AA和ZZ
二、对新的字符串进行Base64编码
另: Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,Flashget在地址前后加的“料”是[FLASHGET]

而QQ旋风的干脆不加料,直接就对地址进行Base64编码了

3.实例

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char      u_char;

#define C_B64_CHAR62    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

/**
 * @fn   static inline void _WRITE_B64( char *p, char a, char b, char c, char const *ct )
 * @brief 具体解密计算,三个字符一组进行计算
 *
 * @param[in] a:第一个加密字符
 * @param[in] b:第二个加密字符
 * @param[in] c:第三个加密字符
 * @param[in] ct:加密表
 * @param[out] p:加密后的输出参数
 *
 * @retval
 */
static inline void _WRITE_B64( char *p, char a, char b, char c, char const *ct )
{
    p[0] = ct[ (u_char)((a >> 2) & 0x3F) ];
    p[1] = ct[ (u_char)(((a << 4) & 0x30) | ((b >> 4) & 0x0F)) ];
    p[2] = ct[ (u_char)(((b << 2) & 0x3C) | ((c >> 6) & 0x03)) ];
    p[3] = ct[ (u_char)(c & 0x3F) ];
}

/**
 * @fn   void c_b64_encrypt( char *obj, char const *src, size_t len, char const *ct, char tc )
 * @brief 加密操作
 *
 * @param[in] src:加密数据源
 * @param[in] len:数据长度
 * @param[in] tc:密钥
 * @param[in] ct:加密表
 * @param[out] obj:加密后输出缓冲区
 *
 * @retval
 */
void c_b64_encrypt( char *obj, char const *src, size_t len, char const *ct, char tc )
{
    char const *ps;
    ps = src;

    while(len >= 3)
    {
        _WRITE_B64(obj, ps[0], ps[1], ps[2], ct);
        len -= 3;
        ps += 3;
        obj += 4;
    }

    switch(len)
    {
        case 1:
            _WRITE_B64(obj, ps[0], 0, 0, ct);
            obj += 2;
            *obj++ = tc;
            *obj++ = tc;
            break;

        case 2:
            _WRITE_B64(obj, ps[0], ps[1], 0, ct);
            obj += 3;
            *obj++ = tc;
            break;
    }
}

size_t  c_strlen( char const *p, size_t c )
{
    size_t i;
    for(i = 0; i != c; ++i)
    {
        if(!p[i])
        {
            break;
        }
    }
    return i;
}

/**
 * @fn   void c_b64_decrypt( char *obj, char const *src, size_t len, char const *dt, char tc )
 * @brief 解密操作
 *
 * @param[in] src:解密数据源
 * @param[in] len:数据长度
 * @param[in] tc:密钥
 * @param[in] dt:加密表
 * @param[out] obj:加密后输出缓冲区
 *
 * @retval
 */
void c_b64_decrypt( char *obj, char const *src, size_t len, char const *dt, char tc )
{
    char  a, b, c, d;
    char const *end;

	if(len == (size_t)(-1))
	{
        len = c_strlen(src, (size_t)-1);
	}

	end = src + len;

    while(src < end)
    {
        a = dt[(u_char)src[0]];
        b = dt[(u_char)src[1]];
        c = dt[(u_char)src[2]];
        d = dt[(u_char)src[3]];

        if(src[3] == tc)
        {
            if(src[2] == tc)
            {
                obj[0] = (((a << 2) & 0xFC) | ((b >> 4) & 0x03));
            }
            else
            {
                obj[0] = (((a << 2) & 0xFC) | ((b >> 4) & 0x03));
                obj[1] = (((b << 4) & 0xF0) | ((c >> 2) & 0x0F));
            }
        }
        else
        {
            obj[0] = (((a << 2) & 0xFC) | ((b >> 4) & 0x03));
            obj[1] = (((b << 4) & 0xF0) | ((c >> 2) & 0x0F));
            obj[2] = (((c << 6) & 0xC0) | (d & 0x3F));
        }

        src += 4;
        obj += 3;
    }
}

/**
 * @fn   void c_b64_decrypt_table( char *dt, char const *ct )
 * @brief 获取解密表
 *
 * @param[in] ct:加密表
 * @param[out] dt:解密表
 *
 * @retval
 */
void c_b64_decrypt_table( char *dt, char const *ct )
{
    int  i;

	memset(dt, 0, 256);
    for(i = 0; i != 64; ++i)
    {
        dt[ (u_char)ct[i] ] = (char)i;
    }
}


int main()
{
    char obj[256] = {0};
    char *src = "1abc中国……7,。、23456789";
    printf("src:%s\n",src);
    size_t len = strlen(src)+1;
    char tc = ':';
    c_b64_encrypt(obj, src, len, C_B64_CHAR62, tc);
    printf("obj:%s\n",obj);

    char dt[256] = {0};
    char dobj[256] = {0};
    len = strlen(obj)+1;
    c_b64_decrypt_table(dt,C_B64_CHAR62);
    c_b64_decrypt(dobj, obj,len,dt,tc);
    printf("dobj:%s\n",dobj);
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值