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;
}