1. Base64使用A--Z,a--z,0--9,+,/ 这64个字符.
    2. 编码原理:将3个字节转换成4个字节( (3 X 8) = 24 = (4 X 6) )先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了.
    3. 解码原理:将4个字节转换成3个字节.先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位.这样就还原了.

Base64是一种非经常见的编码规范,其作用是将二进制序列转换为人类可读的ASCII字符序列,经常使用在需用通过文本协议(比方HTTP和SMTP)来传输二进制数据的情况下。Base64并非一种用于安全领域的加密解密算法(这类算法有DES等),虽然我们有时也听到使用Base64来加密解密的说法,但这里所说的加密与解密实际是指编码(encode)和解码(decode)的过程,其变换是非常easy的,只可以避免信息被直接识别。

Base64採用了一种非常easy的编码转换:对于待编码数据,以3个字节为单位,依次取6位数据并在前面补上两个0形成新的8位编码,因为3*8=4*6,这样3个字节的输入会变成4个字节的输出,长度上添加�了1/3。

上面的处理还不能保证得到的字符都是可见字符,为了达到此目的,Base64制定了一个编码表,进行统一的转换。码表的大小为2^6=64,这也是Base64名称的由来。

Base64编码表

Value Encoding  Value Encoding  Value Encoding  Value Encoding
           0 A            17 R            34 i            51 z
           1 B            18 S            35 j            52 0
           2 C            19 T            36 k            53 1
           3 D            20 U            37 l            54 2
           4 E            21 V            38 m           55 3
           5 F            22 W           39 n           56 4
           6 G            23 X            40 o            57 5
           7 H            24 Y             41 p            58 6
           8 I            25 Z             42 q            59 7
           9 J            26 a             43 r             60 8
          10 K            27 b            44 s            61 9
          11 L            28 c            45 t             62 +
          12 M            29 d           46 u            63 /
          13 N            30 e           47 v
          14 O            31 f            48 w         (pad) =
          15 P            32 g           49 x
          16 Q            33 h           50 y

Base64编解码算法都非常easy,网上有非常多源代码,这里就不介绍了。

另外另一点要注意的地方,前面提到编码是以3个字节为单位,当剩下的字符数量不足3个字节时,则应使用0进行填充,对应的,输出字符则使用'='占位,因此编码后输出的文本末尾可能会出现1至2个'='。

这是一种典型的编码转换的处理方法,相似的可能还有UTF16与UTF8之间的转换。 /**
* /file base64.h
*/
#ifndef XYSSL_BASE64_H
#define XYSSL_BASE64_H

#define XYSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x0010
#define XYSSL_ERR_BASE64_INVALID_CHARACTER -0x0012

#ifdef __cplusplus
extern "C" {
#endif

/**
* /brief Encode a buffer into base64 format
*
* /param dst destination buffer
* /param dlen size of the buffer
* /param src source buffer
* /param slen amount of data to be encoded
*
* /return 0 if successful, or XYSSL_ERR_BASE64_BUFFER_TOO_SMALL.
* *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* /note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_encode(const unsigned char *src, int slen,unsigned char *dst, int *dlen);

/**
* /brief Decode a base64-formatted buffer
*
* /param dst destination buffer
* /param dlen size of the buffer
* /param src source buffer
* /param slen amount of data to be decoded
*
* /return 0 if successful, XYSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
* XYSSL_ERR_BASE64_INVALID_DATA if the input data is not
* correct. *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* /note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_decode(const unsigned char *src, int slen,unsigned char *dst, int *dlen);

/**
* /brief Checkup routine
*
* /return 0 if successful, or 1 if the test failed
*/
int base64_self_test( int verbose );

#ifdef __cplusplus
}
#endif

class CBase64
{
public:
CBase64();
virtual ~CBase64();
static BOOL Encrypt(const unsigned char *pSrc,int iSlen,unsigned char *pDst,int *iDlen,CString &strErrorInfo);
static BOOL Decrypt(const unsigned char *pSrc,int iSlen,unsigned char *pDst,int *iDlen,CString &strErrorInfo);
private:

};

#endif /* base64.h */

//source file: base64.cpp

/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2007 Christophe Devine
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License, version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "stdafx.h"
#include "base64.h"

static const unsigned char base64_enc_map[64] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'
};

static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 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, 127, 127, 127, 127, 127, 127, 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, 127, 127, 127, 127, 127
};

/*
* Encode a buffer into base64 format
*/
int base64_encode(const unsigned char *src, int slen,unsigned char *dst, int *dlen)
{
int i, n;
int C1, C2, C3;
unsigned char *p;

if( slen == 0 )
return( 0 );

n = (slen << 3) / 6;

switch( (slen << 3) - (n * 6) )
{
case 2: n += 3; break;
case 4: n += 2; break;
default: break;
}

if( *dlen < n + 1 )
{
*dlen = n + 1;
return( XYSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}

n = (slen / 3) * 3;

for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;

*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}

if( i < slen )
{
C1 = *src++;
C2 = ((i + 1) < slen) ? *src++ : 0;

*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];

if( (i + 1) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';

*p++ = '=';
}
*dlen =static_cast<int>(p - dst);
*p = 0;
return( 0 );
}

/*
* Decode a base64-formatted buffer
*/
int base64_decode(const unsigned char *src, int slen,unsigned char *dst, int *dlen)
{
int i, j, n;
unsigned long x;
unsigned char *p;

for( i = j = n = 0; i < slen; i++ )
{
if( ( slen - i ) >= 2 &&
*(src+i) == '/r' && *(src+i+1) == '/n' )
continue;

if(*(src+i) == '/n' )
continue;

if(*(src+i) == '=' && ++j > 2 )
return( XYSSL_ERR_BASE64_INVALID_CHARACTER );

if(*(src+i) > 127 || base64_dec_map[*(src+i)] == 127 )
return( XYSSL_ERR_BASE64_INVALID_CHARACTER );

if( base64_dec_map[*(src+i)] < 64 && j != 0 )
return( XYSSL_ERR_BASE64_INVALID_CHARACTER );

n++;
}

if( n == 0 )
return( 0 );

n = ((n * 6) + 7) >> 3;

if( *dlen < n )
{
*dlen = n;
return( XYSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}

for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '/r' || *src == '/n' )
continue;

j -= ( base64_dec_map[*src] == 64 );
x = (x << 6) | ( base64_dec_map[*src] & 0x3F );

if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}

*dlen =static_cast<int>(p - dst);

return( 0 );
}

BOOL CBase64::Encrypt(const unsigned char *pSrc,int iSlen,unsigned char *pDst,int *iDlen,CString &strErrorInfo)
{
strErrorInfo=_T("");
int iRet=base64_encode(pSrc,iSlen,pDst,iDlen);
if(iRet==XYSSL_ERR_BASE64_BUFFER_TOO_SMALL)
strErrorInfo=_T("分配的缓冲区太小!");
else if(iRet==XYSSL_ERR_BASE64_INVALID_CHARACTER)
strErrorInfo=_T("无效数据!");
return iRet==0;
}
BOOL CBase64::Decrypt(const unsigned char *pSrc,int iSlen,unsigned char *pDst,int *iDlen,CString &strErrorInfo)
{
strErrorInfo=_T("");
int iRet=base64_decode(pSrc,iSlen,pDst,iDlen);
if(iRet==XYSSL_ERR_BASE64_BUFFER_TOO_SMALL)
strErrorInfo=_T("分配的缓冲区太小!");
else if(iRet==XYSSL_ERR_BASE64_INVALID_CHARACTER)
strErrorInfo=_T("无效数据!");
return iRet==0;
}

Base64加密解密原理以及代码实现的更多相关文章

  1. Base64加密解密原理以及代码实现(VC++)

    Base64加密解密原理以及代码实现 转自:http://blog.csdn.net/jacky_dai/article/details/4698461 1. Base64使用A--Z,a--z,0- ...

  2. Base64加密转换原理与代码实现

    一.Base64实现转换原理 它是用64个可打印字符表示二进制所有数据方法.由于2的6次方等于64,所以可以用每6个位元(bit)为一个单元,对应某个可打印字符.我们知道三个字节(byte)有24个位 ...

  3. Java Base64加密、解密原理Java代码

    Java Base64加密.解密原理Java代码 转自:http://blog.csdn.net/songylwq/article/details/7578905 Base64是什么: Base64是 ...

  4. 【代码笔记】iOS-3DES+Base64加密解密

    一,工程目录. 二,代码. RootViewController.m #import "RootViewController.h" #import "NSString+T ...

  5. base64加密解密c++代码

    关于base64加密解密代码: 程序运行功能请自行查看main函数: #include <stdio.h> #include <string.h> #include <a ...

  6. password学3——Java BASE64加密解密

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之中的一个,大家能够查看RFC2045-RFC2049.上面有MIME的具体规范.Base64编码可用于在HTTP环境下传递较长的标识信息 ...

  7. php使用base64加密解密图片

    php使用base64加密解密图片的实例代码. 例子: <?php //文件名:base64.php $data="/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAB ...

  8. 使用jframe编写一个base64加密解密工具

    该工具可以使用exe4j来打包成exe工具(如何打包自己百度) 先上截图功能 运行main方法后,会弹出如下窗口 输入密文 然后点击解密,在点格式化 代码分享 package tools;import ...

  9. Base64加密解密工具类

    使用Apache commons codec类Base64进行加密解密 maven依赖 <dependency> <groupId>commons-codec</grou ...

随机推荐

  1. poj3974(manacher)

    传送门:Palindrome 题意:给定一个字符串,求最长回文子串. 分析:manach裸题,核心理解mx>i?p[i]=min(p[2*id-i],mx-i):1. #pragma comme ...

  2. cocos2dx-3.0(1)------win7 32位android环境搭建

    參照链接http://blog.csdn.net/wonengxing/article/details/23601359 ----我的生活,我的点点滴滴!! 一. Android工具安装 1. 安装J ...

  3. http://www.shengshiyouxi.com

    android从Linux系统启动有4个步骤:   (1) init进程启动   (2) Native服务启动   (3) System Server,Android服务启动   (4) Home启动 ...

  4. python语言学习1——初识python

    Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. 龟叔给Python的定位是“优雅”.“明确”.“简单”,所以Python ...

  5. jQuery UI 是建立在 jQuery JavaScript 库上的一组用户界面交互、特效、小部件及主题

    jQuery UI 是建立在 jQuery JavaScript 库上的一组用户界面交互.特效.小部件及主题.无论您是创建高度交互的 Web 应用程序还是仅仅向窗体控件添加一个日期选择器,jQuery ...

  6. PHP监測memcache服务端的执行状况

    . 代码例如以下,代码为memcache官方代码,引用在此.做一下简单的说明: 1.设置username和password define('ADMIN_USERNAME','admin'); // A ...

  7. ORA-12520错误解决一则

    问题描写叙述: 今天突然发现连接数据库时报错,用pl/sql dev连接数据时,有时能连接上,有时连接时报: ORA-12520: TNS: 监听程序无法找到须要的server类型的可用句柄 通过se ...

  8. [ACM] hdu 4418 Time travel (高斯消元求期望)

    Time travel Problem Description Agent K is one of the greatest agents in a secret organization calle ...

  9. 委托、Lambda和事件

    委托 委托相当于C语言当中的函数指针,不过委托是类型安全的类,它定义了返回类型和参数的类型. 声明委托 在C#中使用一个类,分为两个阶段.首先,需要定义这个类,告诉编译器这个类由什么字段和方法组成,然 ...

  10. gdb学习(一个)[再版]

    概要 gdb是GNU debugger的缩写,是编程调试工具. 功能 1.启动程序,能够依照用户自己定义的要求随心所欲的执行程序. 2.可让被调试的程序在用户所指定的断点处停住 (断点能够是条件表达式 ...