MFC封装的base64编码解码函数

函数本就是网上下载的,经过我修改并测试通过以后,封装成C++代码了,并且使用了MFC的数据结构,懂C或C++的朋友可以拿过去稍作修改就可以用了。
提醒:作为C函数,在进行base64编码时一定要给够缓冲区,base64是将8比特数据封装到6比特里,所以缓冲区大小应该为原数据长度 x 4 / 3 + 3,同理,解码的时候则是原数据长度 x 3 / 4 +4,为什么+3、+4?这是因为整除会抛弃余数,余数最大值分别为:2、3,+3、4,多了1个字节,正好给结尾的字符0准备。

#include "StdAfx.h"
#include "base64.h"

// 进行1次base64编码,返回编码的源字符串字符个数,-1代表出错
static int base64_string( const unsigned char *src, size_t srclen, unsigned char *dest, size_t destlen, unsigned char *base64, int index )
{
    if ( NULL == src || NULL == dest || NULL == base64 || index < 0)
		return -1;
	if (srclen <= 0 || destlen < 5) {
		return -1; // // dest多留1个给结尾的0
	}
	
    unsigned char one;
    unsigned char two;
    unsigned char thr;
    unsigned char fou;
	
    if ( srclen >= 3) 
    {
        one = src[0] >> 2;
        two = ( ( src[0] & 0x03 ) << 4 ) | ( src[1] >> 4 );
        thr = ( ( src[1] & 0x0F ) << 2 ) | ( src[2] >> 6 );
        fou = src[2] & 0x3F;
		
        *( dest + index++ ) = base64[one];
        *( dest + index++ ) = base64[two];
        *( dest + index++ ) = base64[thr];
        *( dest + index   ) = base64[fou];
    }
    else if ( srclen == 2)
    {
        one = src[0] >> 2;
        two = ( ( src[0] & 0x03) << 4 ) | ( src[1] >> 4 );
        thr = ( src[1] & 0x0F ) << 2;
		
        *( dest + index++ ) = base64[one];
        *( dest + index++ ) = base64[two];
        *( dest + index++ ) = base64[thr];
        *( dest + index   ) = '=';
    }
    else if ( srclen == 1 )
    {
        one = src[0] >> 2;
        two = ( src[0] & 0x03 ) << 4;
		
        *( dest + index++ ) = base64[one];
        *( dest + index++ ) = base64[two];
        *( dest + index++ ) = '=';
        *( dest + index   ) = '=';
    }
	
    return srclen >= 3 ? 3 : srclen;
}

// base64编码,传入的dest空间必须>=src * 4 / 3 + 3才能保证安全
void base64_encode( const unsigned char *src, int srclen, unsigned char *dest, int destlen )
{
    if ( NULL == src || srclen == 0 || NULL == dest || destlen < srclen * 4 / 3 + 3)
		return;
	
    unsigned char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int index = 0;
    while ( srclen > 0 )
    {
        int step = base64_string( src, srclen, dest, destlen, base64, index );
		if (step == -1) {
			break;
		}
		
		destlen -= 4; // 每次用掉4字节
        index += 4; // 那么索引每次必然增加4

		srclen -= step; // 每次减少3字节或2或者1,2或1都是结尾剩余字符个数
        src   += step; // 那么每次增加3或者2或者1
    }
	
    *( dest + index ) = '\0';
}


// 以上是base64编码的函数
// 下面是base64解码的函数

void create_array( unsigned char *array )
{
    int index  = 0;
    for ( index  = 0; index < 123; index += 1 )
    {
        if ( index == 0x2B )
        {
            *( array + index ) = 0x3E;
        }
        else if ( index == 0x2F )
        {
            *( array + index ) = 0x3F;
        }
        else if ( index >= 0x30 && index <= 0x39 )
        {
            *( array + index ) = 0x34 + index - 0x30;
        }
        else if ( index == 0x3D )
        {
			/* 特殊字符'=',也可合并到else情况 */
            *( array + index ) = 0x00;
        }
        else if ( index >= 0x41 && index <= 0x5A )
        {
            *( array + index ) = index - 0x41;
        }
        else if ( index >= 0x61 && index <= 0x7A ) {
            *( array + index ) = 0x1A + index - 0x61;
		}
		else
		{
			*( array + index ) = 0x00;
		}
	}

	*( array + 123 ) = '\0';
}

int decode_string( const unsigned char *src, size_t srclen, unsigned char *dest, size_t destlen, unsigned char *array, int index )
{
	if ( NULL == src || NULL == dest || NULL == array || index < 0)
		return -1;
	if (srclen < 4 || destlen < 4) {
		return -1; // // dest多留1个给结尾的0
	}
	
    int step = 0;
	
    unsigned char one;
    unsigned char two;
    unsigned char thr;
    if ( src[3] == '=' && src[2] == '=' )
    {
        one = ( array[src[0]] << 2 ) | ( array[src[1]] >> 4 );
        *( dest + index ) = one;
		
        step = 1;
    }
    else if ( src[3] == '=' )
    {
        one = ( array[src[0]] << 2 ) | ( array[src[1]] >> 4 );
        two = ( ( array[src[1]] & 0x0F ) << 4 ) | ( array[src[2]] >> 2 );
		
        *( dest + index++ ) = one;
        *( dest + index   ) = two;
		
        step = 2;
    }
    else
    {
        one = ( array[src[0]] << 2 ) | ( array[src[1]] >> 4 );
        two = ( ( array[src[1]] & 0x0F ) << 4 ) | ( array[src[2]] >> 2 );
        thr = ( array[src[2]] << 6 ) | array[src[3]];
		
        *( dest + index++ ) = one;
        *( dest + index++ ) = two;
        *( dest + index   ) = thr;
		
        step = 3;
    }
	
    return step;
}

// base64解码,传入的dest空间=src空间 * 3 / 4 + 4即可满足要求
void base64_decode( const unsigned char *src, size_t srclen, unsigned char *dest, size_t destlen )
{
    if ( NULL == src || NULL == dest || srclen < 0 || destlen < srclen * 3 / 4 + 4)
		return;
	
    static unsigned char array[124] = {'\0'};
	if (array[0x2B] == '\0') { // 需要初始化
		create_array( array );
	}
	
    int index = 0;
    while ( srclen )
    {
        int step = decode_string( src, srclen, dest, destlen, array, index );
		if (step == -1) {
			break;
		}
		
		srclen -= 4; // 每次解码4个字节
		src    += 4; // 源字符串前进4字节

		destlen -= step; // 每次消耗step(可能是3字节,也可能是2字节或1字节)
        index   += step; // 目标字符串每次前进step字节
    }
	
    *( dest + index ) = '\0';
}

// 下面是导出给MFC用的
CString Base64Encode(const unsigned char *src, size_t srclen)
{
	CString dest;
	srclen = srclen > 0 ? srclen : strlen((const char*)src);
	size_t destlen = srclen * 4 / 3 + 3;
	base64_encode(src, srclen, (unsigned char*)dest.GetBuffer(destlen), destlen);
	dest.ReleaseBuffer();
	return dest;
}

CString Base64Decode(const unsigned char *src, size_t srclen)
{
	CString dest;
	srclen = srclen > 0 ? srclen : strlen((const char*)src);
	size_t destlen = srclen * 3 / 4 + 4;
	base64_decode(src, srclen, (unsigned char*)dest.GetBuffer(destlen), destlen);
	dest.ReleaseBuffer();
	return dest;
}



#ifndef __BASE64_20200920_H__
#define __BASE64_20200920_H__
__declspec(dllexport) CString Base64Encode(const unsigned char *src, size_t srclen = 0);
__declspec(dllexport) CString Base64Decode(const unsigned char *src, size_t srclen = 0);
#endif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Windows API 中的 CryptBinaryToStringW 和 CryptStringToBinaryW 函数来实现 Unicode 编解码。下面是一个使用 MFC 的示例代码: ```cpp #include <wincrypt.h> #include <atlenc.h> CString EncodeBase64(CStringW strUnicode) { DWORD dwSize = strUnicode.GetLength() * sizeof(WCHAR); DWORD dwBase64Size = 0; CryptBinaryToStringW((const BYTE*)strUnicode.GetString(), dwSize, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &dwBase64Size); LPWSTR lpBase64 = new WCHAR[dwBase64Size]; if (CryptBinaryToStringW((const BYTE*)strUnicode.GetString(), dwSize, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, lpBase64, &dwBase64Size)) { CString strBase64(lpBase64); delete[] lpBase64; return strBase64; } delete[] lpBase64; return L""; } CStringW DecodeBase64(CString strBase64) { DWORD dwSize = 0; CryptStringToBinaryW(strBase64.GetString(), strBase64.GetLength(), CRYPT_STRING_BASE64, nullptr, &dwSize, nullptr, nullptr); LPBYTE lpBinary = new BYTE[dwSize]; if (CryptStringToBinaryW(strBase64.GetString(), strBase64.GetLength(), CRYPT_STRING_BASE64, lpBinary, &dwSize, nullptr, nullptr)) { CStringW strUnicode; strUnicode.SetString((LPCWSTR)lpBinary, dwSize / sizeof(WCHAR)); delete[] lpBinary; return strUnicode; } delete[] lpBinary; return L""; } ``` 使用示例: ```cpp CStringW strUnicode = L"你好,世界!"; CString strBase64 = EncodeBase64(strUnicode); CStringW strDecoded = DecodeBase64(strBase64); AtlMessageBox(nullptr, strDecoded, L"解码后的字符串", MB_OK); ``` 其中 `AtlMessageBox` 是 MFC 中的一个消息框函数,用来显示解码后的字符串。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值