//EncodeDecode.cpp
#include <stdio.h>
#include "stdafx.h"
#include "EncodeDecode.h"
#include "zfzh.h"
#include "time.h"
CCode::CCode()
{
}
CCode::~CCode()
{
}
CString CCode::Encode(CString szData, CString strKey)
{
//szData为待加密文本
//strKey为加密秘钥
int en[4];
srand((int)time(0));//使得每次生成的密文不相同
for (int i = 0; i < 4; i++)
{
en[i] = 1 + (int)(10.0*rand() / (RAND_MAX + 1.0));//生成随机密文(范围可自己调整0-15)
}
std::string pass;
pass=toNarrowString(szData.GetString(), pass);
DWORD num = MultiByteToWideChar(CP_ACP, 0, pass.c_str(), -1, NULL, 0);
int nData = szData.GetLength();//取生成的16进制字符串长度
WCHAR *pData; //定义一个UNICODE的指针
pData = (WCHAR*)calloc(num, sizeof(WCHAR));//动态的申请空间存字
if (pData == NULL) //判断申请到空间没有
{
//free(pData);
return NULL;
}
memset(pData, 0, num * sizeof(WCHAR)); //初始化动作
MultiByteToWideChar(CP_ACP, 0, pass.c_str(), -1, pData, num);
WCHAR *pData_R = pData;
std::string key;
key= toNarrowString(strKey.GetString(), key);
DWORD num2 = MultiByteToWideChar(CP_ACP, 0, key.c_str(), -1, NULL, 0);
WCHAR *pKey;
pKey = (WCHAR*)calloc(num2, sizeof(WCHAR));
if (pKey == NULL) //判断申请到空间没有
{
free(pData);
return NULL;
}
memset(pKey, 0, num2 * sizeof(WCHAR)); //初始化动作
MultiByteToWideChar(CP_ACP, 0, key.c_str(), -1, pKey, num2);
int nKeyLen = strKey.GetLength();//取生成的16进制字符串长度
int tmpi = 0;
CString tmps, enstr;
for (int i = 0; i <nData; i++)
{
tmpi = *pData + pKey[i%nKeyLen] + i*en[i % 4];//按位加密运算
int strtmp;
strtmp = *pData;
tmpi = tmpi>65535 ? tmpi - 65535 : tmpi;//范围修正
tmps.Format(_T("%x"), tmpi);
//格式输出
if (tmpi >= 4096)
{
enstr += tmps;
}
else if (tmpi >= 256)
{
enstr += _T("0") + tmps;
}
else if (tmpi >= 16)
{
enstr += _T("00") + tmps;
}
else
{
enstr += _T("000") + tmps;
}
pData++;
}
*pData = 0;
CString ens;
for (int i = 0; i <4; i++)
{
tmps.Format(_T("%x"), en[i]);//随机秘钥放在返回字串前占用1个字符
ens += tmps;
}
free(pData_R);
free(pKey);
return ens + enstr;
}
CString CCode::Decode(CString szData, CString strKey)
{
//szData为待解密文本
//strKey为解密秘钥(同加密秘钥)
int de[4];
for (int i = 0; i < 4; i++)
{
CString szTemp;
szTemp = szData.Left(1);
CString temp;
de[i] = _tcstoul(szTemp, 0, 16); //获得随机秘钥
szData.Delete(0, 1);//剩下的密文
}
int dn = szData.GetLength() / 4;
std::string key;
key = toNarrowString(strKey.GetString(), key);
DWORD num3 = MultiByteToWideChar(CP_ACP, 0, key.c_str(), -1, NULL, 0);
WCHAR *pKey;
pKey = (WCHAR*)calloc(num3, sizeof(WCHAR));
if (pKey == NULL)
{
//free(pKey);
return NULL;
}
memset(pKey, 0, num3 * sizeof(WCHAR)); //初始化动作
MultiByteToWideChar(CP_ACP, 0, key.c_str(), -1, pKey, num3);
int nKeyLen = key.length();
WCHAR *strc;
strc = (WCHAR*)calloc(dn + 1, sizeof(WCHAR));
if (strc == NULL)
{
free(pKey);
return NULL;
}
memset(strc, 0, (dn + 1) * sizeof(WCHAR)); //初始化动作
//MultiByteToWideChar(CP_ACP,0, (LPCTSTR)strKey, -1, pKey, num3);
WCHAR *enstr = strc;
CString tmps;
unsigned int tmpi = 0;
for (int i = 0; i < dn; i++)
{
tmps = szData.Left(4);//取4个字符(16进制字符)
szData.Delete(0, 4);//剩下的字符
*strc = (WCHAR)_tcstoul(tmps, 0, 16);
tmpi = *strc - pKey[i%nKeyLen] - i*de[i % 4];//解密运算
tmpi < 0 ? tmpi + 65535 : tmpi;
*strc = tmpi;
strc++;
}
*strc = 0;
tmps = enstr;
free(pKey);
free(enstr);
return tmps;
}
//解密和加密运算中,求数组内的值只能用%,不能用/号,否则越界,造成内存问题。
//对指针申请了内存空间,要记得归还。如果对指针进行了操作,记得先将这个指针初始化另一个指针,最后将另一个指针释放掉
//zfzh.cpp
#include "stdafx.h"
#include <string>
#include <assert.h>
//#include <Windows.h>
std::string toNarrowString(const wchar_t* pStr, std::string &buf, int len)
{
// figure out how many narrow characters we are going to get
assert(pStr);
assert(len >= 0 || len == -1);
int nChars = WideCharToMultiByte(CP_ACP, 0,
pStr, len, NULL, 0, NULL, NULL);
if (len == -1)
--nChars;
if (nChars == 0)
return "";
// convert the wide string to a narrow string
// nb: slightly naughty to write directly into the string like this
//std::string buf;
buf.resize(nChars);
WideCharToMultiByte(CP_ACP, 0, pStr, len, const_cast<char*>(buf.c_str()), nChars, NULL, NULL);
return buf;
}
std::string toNarrowString(const std::wstring& strW, std::string buf)
{
const wchar_t* pStr = strW.c_str();
int len = (int)strW.length();
return toNarrowString(pStr, buf, len);
}
/*参考了网上一些方法:所谓的短字符, 就是用8bit来表示的字符, 典型的应用是ASCII码.而宽字符, 顾名思义, 就是用16bit表示的字符, 典型的有UNICODE.
常用的代码页有CP_ACP和CP_UTF8两个。
使用CP_ACP代码页就实现了ANSI与Unicode之间的转换。
使用CP_UTF8代码页就实现了UTF - 8与Unicode之间的转换。*/
//1. ASCII to Unicode(CP_ACP)
std::wstring ASCIIToUNICODE(char cArry[]) //传入参数为ANSI串,即用char数组或者string表示的串
{
int nLen = ::MultiByteToWideChar(CP_ACP, 0, cArry, -1, NULL, NULL); //将MultiByteToWideChar()的第四个形参设为-1,即可返回长度
wchar_t *pTemp = new wchar_t[nLen]; //new一个wchar_t空间,保存Unicode串
memset(pTemp, 0, nLen*sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, cArry, -1, (LPWSTR)pTemp, nLen);
std::wstring str = pTemp;
if (pTemp)
{
delete[] pTemp;
pTemp = NULL;
}
return str;
}
//2. Unicode to ASCII(CP_ACP)
std::string UNICODEToASCII(wchar_t cArry[]) //传入参数为Unicode串,用“wchar_t cArry[] = {L"这是个测试"};”表示
{
int nLen = ::WideCharToMultiByte(CP_ACP, 0, cArry, -1, NULL, 0, NULL, NULL);
char *pTemp = new char[nLen]; //new 一个char数组,保存ANSI串
memset(pTemp, 0, nLen);
::WideCharToMultiByte(CP_ACP, 0, cArry, -1, pTemp, nLen, NULL, NULL);
std::string str = pTemp;
if (pTemp)
{
delete[] pTemp;
pTemp = NULL;
}
return str;
}
std::string UnicodeToUTF8(const std::wstring& str)
{
// wide char to multi char
int iTextLen = ::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
char *pElementText = new char[iTextLen];
memset(pElementText, 0, iTextLen);
::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
std::string strText;
strText = pElementText;
if (pElementText)
{
delete[] pElementText;
pElementText = NULL;
}
return strText;
}
// UTF8 转宽字符
std::wstring DecodeUtf8(std::string in)
{
std::wstring s(in.length(), _T(' '));
size_t len = ::MultiByteToWideChar(CP_UTF8, 0, in.c_str(), in.length(), &s[0], s.length());
s.resize(len);
return s;
}
版权声明:本文为ywqb95原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。