您的位置首页百科问答

VS2013 MFC(Unicode) 字符串加密(英文+数字)

VS2013 MFC(Unicode) 字符串加密(英文+数字)

的有关信息介绍如下:

VS2013 MFC(Unicode) 字符串加密(英文+数字)

试过MD5、RSA、DES等常见的加密方式,加密结果经常出现空格或乱码,导致保存ini配置文件后无法正确读取,于是自己构思了一个加密方式(加密结果为英文和数字),带秘钥和随机秘钥。

优点:每次加密密文不同(最少也有16种变化),密文为0-9,a-f的字符。

缺点:加密后字符长度x4+4

加密思路:

1、理解Unicode、ASCII编码(度娘告诉你),Unicode编码每个字符占用4位16进制数表示(0xFFFF 即65535),也就是每个字符都是1个0-65535的数

2、对字符串的编码根据“秘钥”和“随机秘钥”进行加密运算(随机秘钥”是随机生成的4个(0-15)数,附加在密文开头,解码的时候要从密文先读取“随机秘钥”再配合“秘钥”进行解密)

比如:

原字符串“加密”的编码为0x52a0 0x5bc6(21920 23494)

秘钥"ab"的编码为0x0061 0x0062(97 98)

随机秘钥"1 10 3 4"(因为原字符只有2个字“加密”,所以随机秘钥只用到前面2个数"1 10",后面的"3 4"在这里没用)

加密过程是(21920+97-1)(23494+98-10)

得到22016(0x5600)23582(0x5C1E)

3、得到加密的数以后要对数的范围进行判断修正

如果得到的数大于65535就要对数减去65535,小于0则加上65535,以保证数在(0-65535)范围内

4、最后把"随机秘钥"转成16进制字符"1a34"加到密文开头组成加密文本

加密文本为:1a34 5600 5c1e

加密函数代码:

CString CFairy::Encode(CString szData, CString strKey)

{

//szData为待加密文本

//strKey为加密秘钥

int en;

for (int i = 0; i < 4; i++)

{

en[i] = randi(16);//生成随机密文(范围可自己调整0-15)

}

wchar_t *pData = szData.GetBuffer(0);//取生成的16进制字符串指针

int nData = szData.GetLength();//取生成的16进制字符串长度

wchar_t *pKey = strKey.GetBuffer(0);//秘钥指针

int nKeyLen = strKey.GetLength();//取秘钥长度

int tmpi = 0;

CString tmps, enstr;

for (int i = 0; i

{

tmpi = *pData + pKey[i%nKeyLen] - i*en[i/4];//按位加密运算

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

}

szData.ReleaseBuffer();

strKey.ReleaseBuffer();

CString ens;

for (int i = 0; i <4; i++)

{

tmps.Format(_T("%x"), en[i]);//随机秘钥放在返回字串前占用1个字符

ens += tmps;

}

return ens + enstr;

}

解密原理和加密刚好逆过程

代码:

CString CFairy::Decode(CString szData, CString strKey)

{

//szData为待解密文本

//strKey为解密秘钥(同加密秘钥)

int de;

for (int i = 0; i < 4; i++)

{

de[i] = sxtoi(szData.Left(1));//获得随机秘钥

szData.Delete(0, 1);//剩下的密文

}

int dn = szData.GetLength() / 4;

wchar_t *pKey = strKey.GetBuffer(0);

int nKeyLen = strKey.GetLength();

wchar_t *strc = new wchar_t[dn + 1];

wchar_t *enstr = strc;

CString tmps;

int tmpi = 0;

for (int i = 0; i < dn; i++)

{

tmps = szData.Left(4);//取4个字符(16进制字符)

szData.Delete(0, 4);//剩下的字符

*strc = (wchar_t) sxtoi(tmps);

tmpi = *strc - pKey[i%nKeyLen] + i*de[i / 4];//解密运算

tmpi = tmpi < 0 ? tmpi + 65535 : tmpi;//范围判断修正

*strc = tmpi;

strc++;

}

*strc = 0;

strKey.ReleaseBuffer();

tmps = enstr;

delete[]enstr; enstr = NULL;

return tmps;

}