Files
envi-code/SourceCode/Code2026/AecRxBase/Base64.cpp
T

378 lines
9.5 KiB
C++
Raw Normal View History

2026-10-04 00:04:20 +08:00
#include "StdAfx.h"
2026-09-28 15:28:50 +08:00
#include "Base64.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif
namespace
{
char code[65] = {
'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','+','/','=' };
std::string encode(const char *pBuff, const ULONGLONG &len)
{
2026-10-04 00:04:20 +08:00
int textSize = len; //明文长度
int resultSize = (textSize + 2) / 3 * 4; //密文长度
char* pText = new char[textSize + 1]; //多开辟一个内存空间用于存储'\0'
char* pResult = new char[resultSize + 1]; //多开辟一个内存空间用于存储'\0'
2026-09-28 15:28:50 +08:00
::memset(pText, 0, sizeof(char) * (textSize + 1));
::memset(pResult, 0, sizeof(char) * (resultSize + 1));
::memcpy(pText, pBuff, sizeof(char) * (textSize + 1));
pText[textSize] = '\0';
pResult[resultSize] = '\0';
2026-10-04 00:04:20 +08:00
int textIndex = 0;//pText的下标
int resultIndex;//pResult的下标
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
//加密明文,但不包括密文的最后四个字符,因为明文长度可能不是 3 的整数倍,密文会以‘=’结尾
2026-09-28 15:28:50 +08:00
for (resultIndex = 0; resultIndex < resultSize - 4; resultIndex += 4, textIndex += 3)
{
char a, b, c;
a = pText[textIndex];
b = pText[textIndex + 1];
c = pText[textIndex + 2];
for (int i = 0; i < 4; i++)
{
int index;
switch (i)
{
case 0:index = (a >> 2 & 0x3F); break;
case 1:index = (a << 4 & 0x30) | (b >> 4 & 0x0F); break;
case 2:index = (b << 2 & 0x3C) | (c >> 6 & 0x03); break;
case 3:index = (c & 0x3F); break;
}
pResult[resultIndex + i] = code[index];
}
}
2026-10-04 00:04:20 +08:00
//判断明文剩余几个字符,并加密
if (textIndex == textSize - 1)//余一个字符,密文末尾有两个‘=’
2026-09-28 15:28:50 +08:00
{
char a, b;
a = pText[textIndex];
b = 0;
for (int j = 0; j < 4; j++)
{
int index;
switch (j)
{
case 0:index = (a >> 2 & 0x3F); break;
case 1:index = (a << 4 & 0x30) | (b >> 4 & 0x0F); break;
case 2:index = 64; break;
case 3:index = 64; break;
}
pResult[resultIndex + j] = code[index];
}
}
2026-10-04 00:04:20 +08:00
else if ((textIndex + 1) == textSize - 1)//余两个字符,密文末尾有一个‘=’
2026-09-28 15:28:50 +08:00
{
char a, b, c;
a = pText[textIndex];
b = pText[textIndex + 1];
c = 0;
for (int j = 0; j < 4; j++)
{
int index;
switch (j)
{
case 0:index = (a >> 2 & 0x3F); break;
case 1:index = (a << 4 & 0x30) | (b >> 4 & 0x0F); break;
case 2:index = (b << 2 & 0x3C) | (c >> 6 & 0x03); break;
case 3:index = 64; break;
}
pResult[resultIndex + j] = code[index];
}
}
2026-10-04 00:04:20 +08:00
else//是三的整数倍,密文末尾没有‘=’
2026-09-28 15:28:50 +08:00
{
char a, b, c;
a = pText[textIndex];
b = pText[textIndex + 1];
c = pText[textIndex + 2];
for (int j = 0; j < 4; j++)
{
int index;
switch (j)
{
case 0:index = (a >> 2 & 0x3F); break;
case 1:index = (a << 4 & 0x30) | (b >> 4 & 0x0F); break;
case 2:index = (b << 2 & 0x3C) | (c >> 6 & 0x03); break;
case 3:index = (c & 0x3F); break;
}
pResult[resultIndex + j] = code[index];
}
}
std::string strOut(pResult);
delete[] pText;
delete[] pResult;
pText = NULL;
pResult = NULL;
return strOut;
}
ULONGLONG decode(const std::string &ciphertext, char *&pResult)
{
int textSize = ciphertext.size();
2026-10-04 00:04:20 +08:00
if (textSize % 4 != 0)//Base64密文的长度应该是4的倍数
2026-09-28 15:28:50 +08:00
return 0;
2026-10-04 00:04:20 +08:00
int resultSize = textSize / 4 * 3;//明文的长度
2026-09-28 15:28:50 +08:00
char* pText = new char[textSize + 1];
pResult = new char[resultSize + 1];
ciphertext.copy(pText, textSize, 0);
pText[textSize] = '\0';
pResult[resultSize] = '\0';
2026-10-04 00:04:20 +08:00
int textIndex = 0;//pText的下标
int resultIndex;//pResult的下标
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
int index[4];//存储字符在code种的位置
//解密密文,但不解密最后四个字符,因为密文最后四位可能包括‘=’
2026-09-28 15:28:50 +08:00
for (resultIndex = 0; resultIndex < resultSize - 3; resultIndex += 3, textIndex += 4)
{
for (int m = 0; m < 4; m++)
{
if (pText[textIndex + m] >= 'A' && pText[textIndex + m] <= 'Z')
{
index[m] = pText[textIndex + m] - 65;
}
else if (pText[textIndex + m] >= 'a' && pText[textIndex + m] <= 'z')
{
index[m] = pText[textIndex + m] - 71;
}
else if (pText[textIndex + m] >= '0' && pText[textIndex + m] <= '9')
{
index[m] = pText[textIndex + m] + 4;
}
else if (pText[textIndex + m] == '+')
{
index[m] = 62;
}
else if (pText[textIndex + m] == '/')
{
index[m] = 63;
}
2026-10-04 00:04:20 +08:00
else //如果密文包括其他字符则不是正确的Base64编码
2026-09-28 15:28:50 +08:00
{
delete[] pText;
delete[] pResult;
pText = pResult = NULL;
return 0;
}
}
pResult[resultIndex] = (index[0] << 2 & 0XFC) | (index[1] >> 4 & 0x03);
pResult[resultIndex + 1] = (index[1] << 4 & 0xF0) | (index[2] >> 2 & 0x0F);
pResult[resultIndex + 2] = (index[2] << 6 & 0xC0) | index[3];
}
2026-10-04 00:04:20 +08:00
//处理密文的最后四位
2026-09-28 15:28:50 +08:00
for (int m = 0; m < 4; m++)
{
if (pText[textIndex + m] >= 'A' && pText[textIndex + m] <= 'Z')
{
index[m] = pText[textIndex + m] - 65;
}
else if (pText[textIndex + m] >= 'a' && pText[textIndex + m] <= 'z')
{
index[m] = pText[textIndex + m] - 71;
}
else if (pText[textIndex + m] >= '0' && pText[textIndex + m] <= '9')
{
index[m] = pText[textIndex + m] + 4;
}
else if (pText[textIndex + m] == '+')
{
index[m] = 62;
}
else if (pText[textIndex + m] == '/')
{
index[m] = 63;
}
else if (pText[textIndex + m] == '=')
{
index[m] = 64;
}
else
{
delete[] pText;
delete[] pResult;
pText = pResult = NULL;
return 0;
}
}
2026-10-04 00:04:20 +08:00
if (index[2] == 64)//密文末尾有两个 =
2026-09-28 15:28:50 +08:00
{
pResult[resultIndex] = (index[0] << 2 & 0XFC) | (index[1] >> 4 & 0x03);
pResult[resultIndex + 1] = '\0';
pResult[resultIndex + 2] = '\0';
}
2026-10-04 00:04:20 +08:00
else if (index[3] == 64)//密文末尾有一个 =
2026-09-28 15:28:50 +08:00
{
pResult[resultIndex] = (index[0] << 2 & 0XFC) | (index[1] >> 4 & 0x03);
pResult[resultIndex + 1] = (index[1] << 4 & 0xF0) | (index[2] >> 2 & 0x0F);
pResult[resultIndex + 2] = '\0';
}
2026-10-04 00:04:20 +08:00
else//密文末尾没有 =
2026-09-28 15:28:50 +08:00
{
pResult[resultIndex] = (index[0] << 2 & 0XFC) | (index[1] >> 4 & 0x03);
pResult[resultIndex + 1] = (index[1] << 4 & 0xF0) | (index[2] >> 2 & 0x0F);
pResult[resultIndex + 2] = (index[2] << 6 & 0xC0) | index[3];
}
delete[] pText;
pText = NULL;
return resultSize + 1;
}
}
std::string Base64::Encode(const char * pBuffer, const ULONGLONG & length)
{
return encode(pBuffer, length);
}
ULONGLONG Base64::Decode(const std::string & ciphertext, char *& pBuffer)
{
return decode(ciphertext, pBuffer);
}
std::string Base64::Encode(const std::string& plaintext)
{
int textSize=plaintext.size() * sizeof(char);
char* pText=new char[textSize];
::memcpy(pText, plaintext.data(), sizeof(char) * textSize);
std::string str = encode(pText, textSize);
delete[] pText;
pText = NULL;
return str;
}
std::string Base64::Decode(const std::string& ciphertext)
{
char *pBuff(NULL);
ULONGLONG len = decode(ciphertext, pBuff);
if (!pBuff) return "";
std::string str(pBuff);
delete[] pBuff;
return str;
}
std::string Base64::EncodeF2S(CFile * pFile)
{
pFile->SeekToBegin();
ULONGLONG len = pFile->GetLength();
char *psz = new char[len];
::memset(psz, 0, sizeof(char) * len);
pFile->Read(psz, len);
std::string str = encode(psz, len);
delete[] psz;
return str;
}
ULONGLONG Base64::DecodeS2F(const std::string& ciphertext, CFile * pFile)
{
char *pBuff(NULL);
ULONGLONG len = decode(ciphertext, pBuff);
if (!len || !pBuff) return 0L;
pFile->SetLength(0L);
pFile->SeekToBegin();
pFile->Write(pBuff, len);
delete[] pBuff;
pBuff = NULL;
return len;
}
std::wstring Base64::Encode(const std::wstring & plaintext)
{
2026-10-04 00:04:20 +08:00
// 先将 plaintext 转为 utf8
2026-09-28 15:28:50 +08:00
std::string plain = unicode2Ansii(plaintext.c_str(), CP_UTF8);
2026-10-04 00:04:20 +08:00
// 得到的 ss 为 ansii 编码,将其转为unicode
2026-09-28 15:28:50 +08:00
return ansii2Unicode(plain.c_str(), CP_ACP);
}
std::wstring Base64::EncodeF2W(CFile * pFile)
{
std::string cipher = EncodeF2S(pFile);
return ansii2Unicode(cipher.c_str(), CP_ACP);
}
std::wstring Base64::Decode(const std::wstring & ciphertext)
{
2026-10-04 00:04:20 +08:00
// 先将 ciphertext 转为 ansii
2026-09-28 15:28:50 +08:00
std::string cipher = unicode2Ansii(ciphertext.c_str(), CP_ACP);
std::string plain = Decode(cipher);
2026-10-04 00:04:20 +08:00
// 得到 plain 为utf8编码,将 plain 转为 unicode
2026-09-28 15:28:50 +08:00
return ansii2Unicode(plain.c_str(), CP_UTF8);
}
ULONGLONG Base64::DecodeW2F(const std::wstring & ciphertext, CFile * pFile)
{
2026-10-04 00:04:20 +08:00
// cipher 转为 ansii
2026-09-28 15:28:50 +08:00
std::string cipher = unicode2Ansii(ciphertext.c_str(), CP_ACP);
return DecodeS2F(cipher, pFile);
}
std::string Base64::unicode2Ansii(LPCTSTR psz, const DWORD & codePage)
{
if (!psz) return std::string("");
char *pBuffer;
int nLength;
int nLen;
nLen = (int)wcslen(psz);
nLength = ::WideCharToMultiByte(codePage, 0, psz, nLen, NULL, 0, 0, 0);
int rc = ::GetLastError();
pBuffer = new char[nLength + 1];
memset(pBuffer, 0, (nLength + 1) * sizeof(char));
::WideCharToMultiByte(codePage, 0, psz, nLen, pBuffer, nLength, 0, 0);
std::string str(pBuffer);
delete[] pBuffer;
return str;
}
std::wstring Base64::ansii2Unicode(LPCSTR psz, const DWORD & codePage)
{
if (!psz) return std::wstring(L"");
int nLength, nLen;
wchar_t *pBuffer;
nLen = (int)strlen(psz);
nLength = ::MultiByteToWideChar(codePage, 0, psz, nLen, NULL, 0);
pBuffer = new wchar_t[nLength + 1];
memset(pBuffer, 0, (nLength + 1) * sizeof(wchar_t));
::MultiByteToWideChar(codePage, 0, psz, nLen, (LPWSTR)pBuffer, nLength);
std::wstring wstr(pBuffer);
delete[] pBuffer;
return wstr;
}