Win32 / C++ Base64 编解码

CBase64Utils.h

#pragma once
#include <string>
#include <vector>
#include <cstdint>
#include <tchar.h>

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

namespace CBase64Utils
{
	std::string Encode(const void* pData, size_t size);
	std::string Encode(const std::string& data);
	std::wstring Encode(const std::wstring& data);
	std::vector<uint8_t> Decode(const std::string& data);
	std::vector<uint8_t> Decode(const std::wstring& data);
	std::string DecodeToString(const std::string& data);
	std::string DecodeToString(const std::wstring& data);
}

CBase64Utils.cpp

#include "CBase64Utils.h"

namespace CBase64Utils
{
	uint8_t Base64CharTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	uint8_t Base64FindTable[256] = { 0 };
	const uint8_t BASE_INIT_CHAR_FILL = 0xFF;

	std::string Encode(const void* pData, size_t size)
	{
		std::string strResult;
		uint32_t Base64Data = 0;
		size_t nCount = 0;

		const uint8_t* pBytes = (uint8_t*)pData;
		for (size_t i = 0; i < size; i++)
		{
			Base64Data |= ((uint32_t)pBytes[i] << ((2 - nCount) * 8));
			if (2 == nCount)
			{
				strResult += Base64CharTable[(Base64Data >> 18) & 0x3F];
				strResult += Base64CharTable[(Base64Data >> 12) & 0x3F];
				strResult += Base64CharTable[(Base64Data >> 6) & 0x3F];
				strResult += Base64CharTable[(Base64Data >> 0) & 0x3F];
				Base64Data = 0;
				nCount = 0;
			}
			else
			{
				nCount++;
			}
		}

		if (1 == nCount)
		{
			strResult += Base64CharTable[(Base64Data >> 18) & 0x3F];
			strResult += Base64CharTable[(Base64Data >> 12) & 0x3F];
			strResult += "==";
		}
		else if (2 == nCount)
		{
			strResult += Base64CharTable[(Base64Data >> 18) & 0x3F];
			strResult += Base64CharTable[(Base64Data >> 12) & 0x3F];
			strResult += Base64CharTable[(Base64Data >> 6) & 0x3F];
			strResult += "=";
		}

		return strResult;
	}

	std::string Encode(const std::string& data)
	{
		return Encode((const void*)data.data(), data.size());
	}

	std::wstring Encode(const std::wstring& data)
	{
		std::wstring strResult;
		std::string strTemp;
		strTemp.reserve(data.size() * sizeof(wchar_t));
		for (const auto& ch : data)
		{
			if (ch < 0x100)
			{
				strTemp.push_back((char)ch);
			}
			else
			{
				strTemp.push_back((char)(ch & 0xFF));
				strTemp.push_back((char)((ch >> 8) & 0xFF));
			}
		}

		std::string strBuf = Encode(strTemp.data(), strTemp.size());
		strResult.reserve(strBuf.size());
		for (const auto& ch : strBuf)
		{
			strResult.push_back(ch);
		}

		return strResult;
	}

	std::vector<uint8_t> Decode(const std::string& data)
	{
		std::vector<uint8_t> vResult;
		size_t size = data.size();

		if (BASE_INIT_CHAR_FILL != Base64FindTable[0])
		{
			memset(Base64FindTable, BASE_INIT_CHAR_FILL, sizeof(Base64FindTable));
			for (size_t i = 0; i < 64; i++)
			{
				Base64FindTable[Base64CharTable[i]] = i;
			}
		}

		for (auto it = data.crbegin(); it != data.crend(); it++)
		{
			if ('=' == *it)
			{
				size--;
			}
			else
			{
				break;
			}
		}

		uint32_t Base64Data = 0;
		size_t nCount = 0;
		for (size_t i = 0; i < size; i++)
		{
			Base64Data |= ((uint32_t)Base64FindTable[data[i] & 0xFF] << ((3 - nCount) * 6));
			if (3 == nCount)
			{
				vResult.push_back((Base64Data >> 16) & 0xFF);
				vResult.push_back((Base64Data >> 8) & 0xFF);
				vResult.push_back((Base64Data >> 0) & 0xFF);
				Base64Data = 0;
				nCount = 0;
			}
			else
			{
				nCount++;
			}
		}

		if (2 == nCount)
		{
			vResult.push_back((Base64Data >> 16) & 0xFF);
		}
		else if (3 == nCount)
		{
			vResult.push_back((Base64Data >> 16) & 0xFF);
			vResult.push_back((Base64Data >> 8) & 0xFF);
		}

		return vResult;
	}

	std::vector<uint8_t> Decode(const std::wstring& data)
	{
		std::vector<uint8_t> vResult;
		size_t size = data.size();

		if (BASE_INIT_CHAR_FILL != Base64FindTable[0])
		{
			memset(Base64FindTable, BASE_INIT_CHAR_FILL, sizeof(Base64FindTable));
			for (size_t i = 0; i < 64; i++)
			{
				Base64FindTable[Base64CharTable[i]] = i;
			}
		}

		for (auto it = data.crbegin(); it != data.crend(); it++)
		{
			if (L'=' == *it)
			{
				size--;
			}
			else
			{
				break;
			}
		}

		uint32_t Base64Data = 0;
		size_t nCount = 0;
		for (size_t i = 0; i < size; i++)
		{
			Base64Data |= ((uint32_t)Base64FindTable[data[i] & 0xFF] << ((3 - nCount) * 6));
			if (3 == nCount)
			{
				vResult.push_back((Base64Data >> 16) & 0xFF);
				vResult.push_back((Base64Data >> 8) & 0xFF);
				vResult.push_back((Base64Data >> 0) & 0xFF);
				Base64Data = 0;
				nCount = 0;
			}
			else
			{
				nCount++;
			}
		}

		if (2 == nCount)
		{
			vResult.push_back((Base64Data >> 16) & 0xFF);
		}
		else if (3 == nCount)
		{
			vResult.push_back((Base64Data >> 16) & 0xFF);
			vResult.push_back((Base64Data >> 8) & 0xFF);
		}

		return vResult;
	}

	std::string DecodeToString(const std::string& data)
	{
		std::string strResult;
		std::vector<uint8_t> vResult = Decode(data);
		if (!vResult.empty())
		{
			strResult.resize(vResult.size());
			memcpy(&strResult[0], &vResult[0], vResult.size());
		}
		return strResult;
	}

	std::string DecodeToString(const std::wstring& data)
	{
		std::string strResult;
		std::vector<uint8_t> vResult = Decode(data);
		if (!vResult.empty())
		{
			strResult.resize(vResult.size());
			memcpy(&strResult[0], &vResult[0], vResult.size());
		}
		return strResult;
	}
}

main.cpp

#include <locale.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "Win32Utils/CBase64Utils.h"

int _tmain(int argc, LPCTSTR argv[])
{
    setlocale(LC_ALL, "");

    std::wstring strInput = L"FlameCyclone";
    std::wstring strEncode = CBase64Utils::Encode(strInput);
    std::string strDeccode = CBase64Utils::DecodeToString(strEncode);

    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值