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



