写这篇文章缘由是很久以前,我用C#写了一个类似记事本的程序,如图:
想写一个私密的东西,比如日记等等。后来C#换成了C++CLI,C++MFC,现在是QT,那时候我用了两种加密程序,一种是DES,一种是自己写的。现在就有了三个版本的加密程序,一个是C#,一个是C++ CLI, 一个是 C++。由于DES每次都要库,所以干脆我用自己写的代码,在这里和大家分享一下,先把代码列出来,下面再来一步一步说明一下:
这里是一个加密程序的运行界面,C#的, TextEncrypt和TextEncrypt2生成的字符串都比DES长,
性能也差点,不过没关系了,能用就行,代码有点乱,最后会用C++说明一下。
c#版本
/// <summary>
/// 随便打乱字符串,防止一眼就能看清内容,加1取反
/// </summary>
/// <param name="aStr"></param>
/// <returns></returns>
public static string messCode(string aStr)
{
string tmp = "";
for (int i = 0; i < aStr.Length; ++i)
{
tmp += (char)(~((int)aStr[i] + 1));
}
return tmp;
}
/// <summary>
///还原打乱字符串
/// </summary>
/// <param name="aStr"></param>
/// <returns></returns>
public static string resumeCode(string aStr)
{
string tmp = "";
for (int i = 0; i < aStr.Length; ++i)
{
tmp += (char)(~((int)aStr[i]) - 1);
}
return tmp;
}
/// <summary>
/// 把字符串加密成密文
/// </summary>
/// <param name="aPassword"></param>
/// 创建时间: ????-??-?? 最后一次修改时间:2020-01-06(已丢弃)
/// <returns></returns>
public static string Rubbish_passwordEncrypt(string aPassword)
{
string mc = messCode(aPassword);
string tmp = "";
for (int i = 0; i < mc.Length; ++i)
{
tmp += ((int)mc[i] + i * 100).ToString();
if (i < mc.Length - 1)
tmp += ',';
}
return tmp;
}
/// <summary>
/// 把字符串译成明文
/// </summary>
/// <param name="aPassword"></param>
/// 创建时间: ????-??-?? 最后一次修改时间:2020-01-06(已丢弃)
/// <returns></returns>
public static string Rubbish_passwordRevert(string aPassword)
{
string[] sList = aPassword.Split(',');
string tmp = "";
for (int i = 0; i < sList.Length; ++i)
{
tmp += (char)(System.Convert.ToInt32(sList[i]) - (i * 100));
}
return resumeCode(tmp);
}
/// <summary>
/// 把正整数的个数,十位、百位等等都用英文表示:例:256 => cFg 123 => bCd
/// </summary>
/// <param name="iNumber">正整数</param>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-06
/// <returns>英文表示的数字</returns>
public static string NumberShowToEnglishAlphabet(int iNumber)
{
//a~z 97-122 A~Z 65-90 0~9 48-57
if (iNumber < 0)
return "";
string sResul = "";
string sNumber = iNumber.ToString();
for (int i = 0; i < sNumber.Length; ++i)
{
if (i % 2 == 0)
sResul += System.Convert.ToChar((int)sNumber[i] + 97 - 48); //小写字母
else
sResul += System.Convert.ToChar((int)sNumber[i] + 65 - 48); //大写字母
}
return sResul;
}
/// <summary>
/// 把英文表示的非负数还原成真实的数字,不成功返回-1. 例: 123 => abc abc = > 123
/// </summary>
/// <param name="sEnglishAlphabet"></param>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-06
/// <returns></returns>
public static int EnglishAlphabetToNumber(string sEnglishAlphabet)
{
string sNumber = "";
for (int i = 0; i < sEnglishAlphabet.Length; ++i)
{
if (i % 2 == 0)
sNumber += ((int)sEnglishAlphabet[i] - 97).ToString();
else
sNumber += ((int)sEnglishAlphabet[i] - 65).ToString();
}
if (!lg.IsNumberString(sNumber))
return -1;
return System.Convert.ToInt32(sNumber);
}
//十进制数是组成以10为基础的数字系统,有0,1,2,3, 4, 5, 6, 7, 8, 9十个基本数字组成。十进制,英文名称为Decimal System
//来源于希腊文Decem,意为十。十进制计数是由印度教教徒在1500年前发明的,由阿拉伯人传承至11世纪。
//十六进制(hexadecimal)是计算机中数据的一种表示方法。它的规则是“逢十六进一”。
/// <summary>
/// 把十进制数转为62进制
/// </summary>
/// <param name="iValue">十进制整数值</param>
/// 创建时间: 2020-04-26 最后一次修改时间:2020-04-26
/// <returns>返回62进制字符串</returns>
public static string SN10ToSN62(int iValue)
{
if (iValue == 0) return "0";
int iTemp = (iValue > 0 ? iValue : - iValue);
string sResult = "";
while (iTemp != 0)
{
int n = iTemp % 62;
sResult += SN62[n];
iTemp = iTemp / 62;
}
sResult = sResult._reversal();
return iValue > 0 ? sResult : "-" + sResult;
}
/// <summary>
/// 把62进制字符串转为十进制整数
/// </summary>
/// <param name="sValue"></param>
/// 创建时间: 2020-04-25 最后一次修改时间:2020-04-25
/// <returns></returns>
public static int SN62ToSN10(string sValue)
{
if(sValue.Length == 0)
{
throw new Exception("错误的数字!");
}
string sTemp = (sValue[0] == '-' ? sValue.Substring(1, sValue.Length - 1) : sValue)._reversal();
int iResult = 0;
int iExp = 0;
foreach(char c in sTemp)
{
int n = SN62.IndexOf(c);
if(n == -1)
{
throw new Exception("错误的62进制数!");
}
iResult += n * LMath.Pow(62, iExp);
++iExp;
}
return sValue[0] == '-' ? - iResult : iResult;
}
/// <summary>
/// 是否62进制数
/// </summary>
/// <param name="sValue"></param>
/// 创建时间: 2020-04-27 最后一次修改时间:2020-04-27
/// <returns></returns>
public static bool IsSN62Number(string sValue)
{
if (sValue == "")
return false;
foreach(char c in sValue)
{
if (SN62.IndexOf(c) == -1)
return false;
}
return true;
}
/// <summary>
/// 把字符串按一定格式加密
/// </summary>
/// <param name="sText">明文字符串</param>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-27
/// <returns>返回加密的字符串</returns>
public static string TextEncrypt(string sText)
{
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
string sResult = "";
int iLength = sText.Length;
string sLength = NumberShowToEnglishAlphabet(iLength);
string sLengthCount = NumberShowToEnglishAlphabet(sLength.Length);
sResult += sLengthCount;
sResult += sLength;
foreach (char c in sText)
{
int iCharValue = (int)c;
string sTemp = NumberShowToEnglishAlphabet(iCharValue + iLength);
sResult += NumberShowToEnglishAlphabet(sTemp.Length);
sResult += sTemp;
}
int iCheckValue = 0;
foreach (char c in sResult)
{
iCheckValue += (int)c;
}
string sCheckValue = NumberShowToEnglishAlphabet(iCheckValue);
sResult += sCheckValue;
sResult += NumberShowToEnglishAlphabet(sCheckValue.Length);
return sResult;
}
/// <summary>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-19
/// 把密文解密成明文,如果解密不成功,则回原字符串
/// </summary>
/// <param name="sEncryptText"></param>
/// <returns>成功返回明文,失败返回原字符串</returns>
public static string TextDecrypt(string sEncryptText)
{
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
if (sEncryptText.Length < 6) //不能少于6位,空字符是:babJfd
return sEncryptText;
int iCountLength = EnglishAlphabetToNumber(sEncryptText[sEncryptText.Length - 1].ToString());
if (iCountLength > sEncryptText.Length - 1 || iCountLength < 0)
{
//lg.ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0");
return sEncryptText;
}
int iCheckValue = EnglishAlphabetToNumber(sEncryptText.Substring(sEncryptText.Length - 1 - iCountLength, iCountLength));
if (iCheckValue <= 0)
{
//lg.ShowInfo("iCheckValue <= 0");
return sEncryptText;
}
//检查校验码
string sEncryptData = sEncryptText.Substring(0, sEncryptText.Length - 1 - iCountLength);
int iCheckValue2 = 0;
foreach (char c in sEncryptData)
{
iCheckValue2 += (int)c;
}
if (iCheckValue2 != iCheckValue) //文件检验失败!
{
return sEncryptText;
}
//校验码已通过
int iLengthCount = EnglishAlphabetToNumber(sEncryptData[0].ToString());
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (iLengthCount > sEncryptData.Length - 1)
{
return sEncryptText;
}
int iTextLength = EnglishAlphabetToNumber(sEncryptData.Substring(1, iLengthCount)); //明文字符串长度
int iStart = 1 + iLengthCount;
string sText = "";
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData.Length - 1 - iLengthCount)
{
int iSubLength = EnglishAlphabetToNumber(sEncryptData.Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData.Length)
{
lg.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = EnglishAlphabetToNumber(sEncryptData.Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
lg.ShowError("iCharValue < 0");
return sEncryptText;
}
sText += System.Convert.ToChar(iCharValue);
iStart = iStart + 1 + iSubLength;
}
if (sText.Length != iTextLength)
{
lg.ShowError("sText.Length != iTextLength");
return sEncryptText; //长度检查
}
return sText;
}
/// <summary>
/// 根据密钥来加密
/// </summary>
/// <param name="sText">要加密的字符串</param>
/// <param name="sKey">密钥</param>
/// 创建时间: 2020-04-27 最后一次修改时间:2020-04-27
/// <returns>近回加密字符串</returns>
public static string TextEncrypt2(string sText, string sKey)
{
if (sKey.Trim().Length == 0 || sText.Length == 0)
return TextEncrypt2(sText);
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
int nCount = 0;
foreach (char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % sText.Length + 1;
string s1 = sText.Substring(0, nText1_Lenth);
string s2 = sText.Substring(nText1_Lenth, sText.Length - nText1_Lenth);
string sTextLength = lg.SN10ToSN62(sText.Length);
string sTextLengthCount = lg.SN10ToSN62(sTextLength.Length);
string sKeyLength = lg.SN10ToSN62(sKey.Length);
string sKeyLengthCount = lg.SN10ToSN62(sKeyLength.Length);
string s = sTextLengthCount + sTextLength + lg.messCode(s1) + sKeyLengthCount + sKeyLength + lg.messCode(sKey) + lg.messCode(s2);
return TextEncrypt2(s);
}
/// <summary>
/// 把字符串按一定格式加密
/// </summary>
/// <param name="sText">明文字符串</param>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-27
/// <returns>返回加密的字符串</returns>
public static string TextEncrypt2(string sText)
{
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
string sResult = "";
int iLength = sText.Length;
string sLength = SN10ToSN62(iLength);
string sLengthCount = SN10ToSN62(sLength.Length);
sResult += sLengthCount;
sResult += sLength;
foreach (char c in sText)
{
int iCharValue = (int)c;
string sTemp = SN10ToSN62(iCharValue + iLength);
sResult += SN10ToSN62(sTemp.Length);
sResult += sTemp;
}
int iCheckValue = 0;
foreach (char c in sResult)
{
iCheckValue += (int)c;
}
string sCheckValue = SN10ToSN62(iCheckValue);
sResult += sCheckValue;
sResult += SN10ToSN62(sCheckValue.Length);
return sResult;
}
/// <summary>
/// 把密文解密成明文,如果解密不成功,则回原字符串
/// </summary>
/// <param name="sEncryptText"></param>
/// <returns>成功返回明文,失败返回原字符串</returns>
/// 创建时间: 2020-04-27 最后一次修改时间:2020-05-15
public static string TextDecrypt2(string sEncryptText)
{
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位(永远1位)
// a
// 1 + 1 + 2 + (97+1)
if (sEncryptText.Length < 5) //不能少于5位,空字符是:101z2
return sEncryptText;
//加密字符值总和占用位
string sCountLength = sEncryptText[sEncryptText.Length - 1].ToString();
if(!lg.IsSN62Number(sCountLength))
{
return sEncryptText;
}
int iCountLength = SN62ToSN10(sCountLength);//加密字符值总和占用位
if (iCountLength > sEncryptText.Length - 1 || iCountLength < 0)
{
lg.ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0");
return sEncryptText;
}
string sCount = sEncryptText.Substring(sEncryptText.Length - 1 - iCountLength, iCountLength);
//----------------------------------------------------------------2020-05-15加入
// (1) 10进制 int类型的最大值是:2147483647 = 62进制 2lkCB1
// (2) 如果sCount不是62进制,则密文错误
if (sCount.Length > 6 || !lg.IsSN62Number(sCount))
{
return sEncryptText;
}
//------------------------------------------------------------------------------
int iCheckValue = SN62ToSN10(sCount);
if (iCheckValue <= 0)
{
lg.ShowInfo("iCheckValue <= 0");
return sEncryptText;
}
//检查校验码
string sEncryptData = sEncryptText.Substring(0, sEncryptText.Length - 1 - iCountLength);
int iCheckValue2 = 0;
foreach (char c in sEncryptData)
{
iCheckValue2 += (int)c;
}
if (iCheckValue2 != iCheckValue) //文件检验失败!
{
lg.ShowInfo("iCheckValue2 != iCheckValue");
return sEncryptText;
}
//校验码已通过
int iLengthCount = SN62ToSN10(sEncryptData[0].ToString());
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (iLengthCount > sEncryptData.Length - 1)
{
lg.ShowInfo("iLengthCount > sEncryptData.Length - 1");
return sEncryptText;
}
int iTextLength = SN62ToSN10(sEncryptData.Substring(1, iLengthCount)); //明文字符串长度
int iStart = 1 + iLengthCount;
string sText = "";
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData.Length - 1 - iLengthCount)
{
int iSubLength = SN62ToSN10(sEncryptData.Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData.Length)
{
lg.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = SN62ToSN10(sEncryptData.Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
lg.ShowError("iCharValue < 0");
return sEncryptText;
}
sText += System.Convert.ToChar(iCharValue);
iStart = iStart + 1 + iSubLength;
}
if (sText.Length != iTextLength)
{
lg.ShowError("sText.Length != iTextLength");
return sEncryptText; //长度检查
}
return sText;
}
/// <summary>
/// 根据密钥来解密字符串
/// </summary>
/// <param name="sEncryptText">加密的字符串</param>
/// <param name="sKey">密钥(用户密码为6~16字符,可使用字母(区分大小写)、数字与特殊符号 用户密码至少包含字母、数字、符号中的两种)</param>
/// 创建时间: 2020-04-27 最后一次修改时间:2020-04-27
/// <returns>成功返回解密码字符串,失败返回原字符</returns>
public static string TextDecrypt2(string sEncryptText, string sKey)
{
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
string sDecryptText = TextDecrypt2(sEncryptText);
if (sDecryptText.Length == 0) //空字符
return "";
if (sDecryptText == sEncryptText) //失败返回原字符
return sEncryptText;
int nTextLengthCount = lg.SN62ToSN10(sDecryptText[0].ToString());
//当传递的字符串是不带sKey的加密串时
if (sDecryptText.Length.ToString().Length < nTextLengthCount) //母字符串的长度的占位数小于子字符串的长度的占位数是错误的
{
return sEncryptText;
}
if (nTextLengthCount <= 0) //占位最少是1
{
return sEncryptText;
}
int nTextLength = lg.SN62ToSN10(sDecryptText.Substring(1, nTextLengthCount));
if (nTextLengthCount == -1 || nTextLength == -1) //失败
return sEncryptText;
int nCount = 0;
foreach (char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % nTextLength + 1;
int nStart = 1 + nTextLengthCount + nText1_Lenth;
int nKeyLengthCount = lg.SN62ToSN10(sDecryptText.Substring(nStart, 1));
//nKeyLengthCount <= 2 sKey.Length的长度大小是1~15,也就是 <= 2
if (nKeyLengthCount > 2) //密钥可能不对
{
return sEncryptText; //返回原字符
}
int nKeyLength = lg.SN62ToSN10(sDecryptText.Substring(nStart + 1, nKeyLengthCount));
if (nKeyLengthCount == -1 || nKeyLength == -1) //失败
return sEncryptText;
string sCheckKey = lg.resumeCode(sDecryptText.Substring(nStart + 1 + nKeyLengthCount, nKeyLength));
if (sCheckKey != sKey) //失败
{
//return sEncryptText;
return "密码不正确!";
}
string s1 = lg.resumeCode(sDecryptText.Substring(1 + nTextLengthCount, nText1_Lenth));
string s2 = lg.resumeCode(sDecryptText.Substring(nStart + 1 + nKeyLengthCount + nKeyLength, nTextLength - nText1_Lenth));
return s1 + s2;
}
/// <summary>
/// 根据密钥来解密字符串
/// </summary>
/// <param name="sEncryptText">加密的字符串</param>
/// <param name="sKey">密钥(用户密码为6~16字符,可使用字母(区分大小写)、数字与特殊符号 用户密码至少包含字母、数字、符号中的两种)</param>
/// 创建时间: 2020-04-18 最后一次修改时间:2020-04-25
/// <returns>成功返回解密码字符串,失败返回原字符</returns>
public static string TextDecrypt(string sEncryptText, string sKey)
{
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
string sDecryptText = TextDecrypt(sEncryptText);
if (sDecryptText.Length == 0) //空字符
return "";
if (sDecryptText == sEncryptText) //失败返回原字符
return sEncryptText;
int nTextLengthCount = lg.EnglishAlphabetToNumber(sDecryptText[0].ToString());
//当传递的字符串是不带sKey的加密串时
if (sDecryptText.Length.ToString().Length < nTextLengthCount) //母字符串的长度的占位数小于子字符串的长度的占位数是错误的
{
return sEncryptText;
}
if (nTextLengthCount <= 0) //占位最少是1
{
return sEncryptText;
}
int nTextLength = lg.EnglishAlphabetToNumber(sDecryptText.Substring(1, nTextLengthCount));
if (nTextLengthCount == -1 || nTextLength == -1) //失败
return sEncryptText;
int nCount = 0;
foreach (char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % nTextLength + 1;
int nStart = 1 + nTextLengthCount + nText1_Lenth;
int nKeyLengthCount = lg.EnglishAlphabetToNumber(sDecryptText.Substring(nStart, 1));
//nKeyLengthCount <= 2 sKey.Length的长度大小是1~15,也就是 <= 2
if (nKeyLengthCount > 2) //密钥可能不对
{
return sEncryptText; //返回原字符
}
int nKeyLength = lg.EnglishAlphabetToNumber(sDecryptText.Substring(nStart + 1, nKeyLengthCount));
if (nKeyLengthCount == -1 || nKeyLength == -1) //失败
return sEncryptText;
string sCheckKey = lg.resumeCode(sDecryptText.Substring(nStart + 1 + nKeyLengthCount, nKeyLength));
if (sCheckKey != sKey) //失败
return sEncryptText;
string s1 = lg.resumeCode(sDecryptText.Substring(1 + nTextLengthCount, nText1_Lenth));
string s2 = lg.resumeCode(sDecryptText.Substring(nStart + 1 + nKeyLengthCount + nKeyLength, nTextLength - nText1_Lenth));
return s1 + s2;
}
/// <summary>
/// 根据密钥来加密
/// </summary>
/// <param name="sText">要加密的字符串</param>
/// <param name="sKey">密钥</param>
/// 创建时间: 2020-04-18 最后一次修改时间:2020-04-18
/// <returns>近回加密字符串</returns>
public static string TextEncrypt(string sText, string sKey)
{
if (sKey.Trim().Length == 0 || sText.Length == 0)
return TextEncrypt(sText);
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
int nCount = 0;
foreach (char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % sText.Length + 1;
string s1 = sText.Substring(0, nText1_Lenth);
string s2 = sText.Substring(nText1_Lenth, sText.Length - nText1_Lenth);
string sTextLength = lg.NumberShowToEnglishAlphabet(sText.Length);
string sTextLengthCount = lg.NumberShowToEnglishAlphabet(sText.Length.ToString().Length);
string sKeyLength = lg.NumberShowToEnglishAlphabet(sKey.Length);
string sKeyLengthCount = lg.NumberShowToEnglishAlphabet(sKey.Length.ToString().Length);
string s = sTextLengthCount + sTextLength + lg.messCode(s1) + sKeyLengthCount + sKeyLength + lg.messCode(sKey) + lg.messCode(s2);
return TextEncrypt(s);
}
C++CLI
String^ global_clr_extend::s_messCode(String^ aStr)
{
/*
string tmp = "";
for (int i = 0; i < aStr.Length; ++i)
{
tmp += (char)(~((int)aStr[i] + 1));
}
return tmp;
//C++ cli 的 char 是 1 , C# 的 char 是 2
*/
StringBuilder^ sb = gcnew StringBuilder(aStr->Length);
for (int i = 0; i < aStr->Length; ++i)
{
sb->Append((_char)(~((int)aStr[i] + 1))); //这里转换一定要 _char,而不是 char, C++ cli 的 char 是 1 , C# 的 char 是 2
}
return sb->ToString();
}
String^ global_clr_extend::s_resumeCode(String^ aStr)
{
/*
string tmp = "";
for (int i = 0; i < aStr.Length; ++i)
{
tmp += (char)(~((int)aStr[i]) - 1);
}
return tmp;
//C++ cli 的 char 是 1 , C# 的 char 是 2
*/
StringBuilder^ sb = gcnew StringBuilder(aStr->Length);
for (int i = 0; i < aStr->Length; ++i)
{
sb->Append( (_char) (~((int)aStr[i]) - 1) ); //这里转换一定要 _char,而不是 char, C++ cli 的 char 是 1 , C# 的 char 是 2
}
return sb->ToString();
}
String^ global_clr_extend::s_Rubbish_passwordEncrypt(String^ aPassword)
{
String^ mc = s_messCode(aPassword);
StringBuilder^ sb = gcnew StringBuilder(mc->Length * 4);
for (int i = 0; i < mc->Length; ++i)
{
sb->Append(((int)mc[i] + i * 100).ToString());
if (i < mc->Length - 1)
sb->Append( ',');
}
return sb->ToString();
}
String^ global_clr_extend::s_Rubbish_passwordRevert(String^ aPassword)
{
array<String^>^ sList = aPassword->Split(',');
StringBuilder^ sb = gcnew StringBuilder(aPassword);
for (int i = 0; i < sList->Length; ++i)
{
sb->Append((char)(System::Convert::ToInt32(sList[i]) - (i * 100)));
}
return s_resumeCode(sb->ToString());
}
String^ global_clr_extend::s_NumberShowToEnglishAlphabet(int iNumber)
{
//a~z 97-122 A~Z 65-90 0~9 48-57
if (iNumber < 0)
return "";
StringBuilder^ sbResult = gcnew StringBuilder(10);
String^ sNumber = iNumber.ToString();
for (int i = 0; i < sNumber->Length; ++i)
{
if (i % 2 == 0)
sbResult->Append( System::Convert::ToChar((int)sNumber[i] + 97 - 48) ); //小写字母
else
sbResult->Append ( System::Convert::ToChar((int)sNumber[i] + 65 - 48)); //大写字母
}
return sbResult->ToString();
}
int global_clr_extend::s_EnglishAlphabetToNumber(String^ sEnglishAlphabet)
{
StringBuilder^ sbResult = gcnew StringBuilder(10);
for (int i = 0; i < sEnglishAlphabet->Length; ++i)
{
if (i % 2 == 0)
sbResult->Append(((int)sEnglishAlphabet[i] - 97).ToString());
else
sbResult->Append(((int)sEnglishAlphabet[i] - 65).ToString());
}
String^ sTemp = sbResult->ToString();
if (! s_IsNumberString(sTemp))
return -1;
return System::Convert::ToInt32(sTemp);
}
String^ global_clr_extend::s_SN10ToSN62(int iValue)
{
if (iValue == 0) return "0";
int iTemp = (iValue > 0 ? iValue : -iValue);
StringBuilder^ sbResult = gcnew StringBuilder(10);
while (iTemp != 0)
{
int n = iTemp % 62;
sbResult->Append(ga.SN62[n]);
iTemp = iTemp / 62;
}
String^ sResult = s_reversal(sbResult->ToString());
return iValue > 0 ? sResult : "-" + sResult;
}
int global_clr_extend::s_SN62ToSN10(String^ sValue)
{
/*
------------------------------------C#
if(sValue.Length == 0)
{
throw gcnew Exception("错误的数字!");
}
string sTemp = (sValue[0] == '-' ? sValue.Substring(1, sValue.Length - 1) : sValue)._reversal();
int iResult = 0;
int iExp = 0;
foreach(char c in sTemp)
{
int n = SN62.IndexOf(c);
if(n == -1)
{
throw gcnew Exception("错误的62进制数!");
}
iResult += n * LMath.Pow(62, iExp);
++iExp;
}
return sValue[0] == '-' ? - iResult : iResult;
*/
if (sValue->Length == 0)
{
throw gcnew Exception("错误的数字!");
}
String^ sTemp = s_reversal((sValue[0] == '-' ? sValue->Substring(1, sValue->Length - 1) : sValue));
int iResult = 0;
int iExp = 0;
for each(_char c in sTemp)
{
int n = _Math::strChr_t(ga.SN62, (char)c);
if (n == -1)
{
throw gcnew Exception("错误的62进制数!");
}
iResult += n * _Math::pow(62, iExp);
++iExp;
}
return sValue[0] == '-' ? -iResult : iResult;
}
bool global_clr_extend::s_IsSN62Number(String^ sValue)
{
if (sValue == "")
return false;
for each(_char c in sValue)
{
if (ga.SN62[c] == -1)
return false;
}
return true;
}
String^ global_clr_extend::s_TextEncrypt(String^ sText)
{
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
StringBuilder^ sbResult = gcnew StringBuilder(sText->Length * 2);
int iLength = sText->Length;
String^ sLength = s_NumberShowToEnglishAlphabet(iLength);
String^ sLengthCount = s_NumberShowToEnglishAlphabet(sLength->Length);
sbResult->Append(sLengthCount);
sbResult->Append(sLength);
for each(_char c in sText)
{
int iCharValue = (int)c;
String^ sTemp = s_NumberShowToEnglishAlphabet(iCharValue + iLength);
sbResult->Append(s_NumberShowToEnglishAlphabet(sTemp->Length));
sbResult->Append(sTemp);
}
int iCheckValue = 0;
for (int i = 0; i < sbResult->Length; ++i)
{
iCheckValue += (int)sbResult[i];
}
String^ sCheckValue = s_NumberShowToEnglishAlphabet(iCheckValue);
sbResult->Append(sCheckValue);
sbResult->Append(s_NumberShowToEnglishAlphabet(sCheckValue->Length));
return sbResult->ToString();
}
String^ global_clr_extend::s_TextDecrypt(String^ sEncryptText)
{
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
if (sEncryptText->Length < 6) //不能少于6位,空字符是:babJfd
return sEncryptText;
int iCountLength = s_EnglishAlphabetToNumber(sEncryptText[sEncryptText->Length - 1].ToString());
if (iCountLength > sEncryptText->Length - 1 || iCountLength < 0)
{
//gce::ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0");
return sEncryptText;
}
int iCheckValue = s_EnglishAlphabetToNumber(sEncryptText->Substring(sEncryptText->Length - 1 - iCountLength, iCountLength));
if (iCheckValue <= 0)
{
//gce::ShowInfo("iCheckValue <= 0");
return sEncryptText;
}
//检查校验码
String^ sEncryptData = sEncryptText->Substring(0, sEncryptText->Length - 1 - iCountLength);
int iCheckValue2 = 0;
for each(char c in sEncryptData)
{
iCheckValue2 += (int)c;
}
if (iCheckValue2 != iCheckValue) //文件检验失败!
{
return sEncryptText;
}
//校验码已通过
int iLengthCount = s_EnglishAlphabetToNumber(sEncryptData[0].ToString());
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (iLengthCount > sEncryptData->Length - 1)
{
return sEncryptText;
}
int iTextLength = s_EnglishAlphabetToNumber(sEncryptData->Substring(1, iLengthCount)); //明文字符串长度
int iStart = 1 + iLengthCount;
StringBuilder^ sText = gcnew StringBuilder(sEncryptText->Length);
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData->Length - 1 - iLengthCount)
{
int iSubLength = s_EnglishAlphabetToNumber(sEncryptData->Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData->Length)
{
d.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = s_EnglishAlphabetToNumber(sEncryptData->Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
d.ShowError("iCharValue < 0");
return sEncryptText;
}
sText->Append(System::Convert::ToChar(iCharValue));
iStart = iStart + 1 + iSubLength;
}
if (sText->Length != iTextLength)
{
d.ShowError("sText.Length != iTextLength");
return sEncryptText; //长度检查
}
return sText->ToString();
}
String^ global_clr_extend::s_TextEncrypt2(String^ sText, String^ sKey)
{
if (sKey->Trim()->Length == 0 || sText->Length == 0)
return s_TextEncrypt2(sText);
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
int nCount = 0;
for each(_char c in sKey)
{
nCount += (int)c;
}
int nText1_Length = nCount % sText->Length + 1;
String^ s1 = sText->Substring(0, nText1_Length);
String^ s2 = sText->Substring(nText1_Length, sText->Length - nText1_Length);
String^ sTextLength = s_SN10ToSN62(sText->Length);
String^ sTextLengthCount = s_SN10ToSN62(sTextLength->Length);
String^ sKeyLength = s_SN10ToSN62(sKey->Length);
String^ sKeyLengthCount = s_SN10ToSN62(sKeyLength->Length);
String^ s = sTextLengthCount + sTextLength + s_messCode(s1) + sKeyLengthCount + sKeyLength + s_messCode(sKey) + s_messCode(s2);
return s_TextEncrypt2(s);
}
String^ global_clr_extend::s_TextEncrypt2(String^ sText)
{
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
StringBuilder^ sbResult = gcnew StringBuilder(sText->Length * 2);
int iLength = sText->Length;
String^ sLength = s_SN10ToSN62(iLength);
String^ sLengthCount = s_SN10ToSN62(sLength->Length);
sbResult->Append(sLengthCount);
sbResult->Append(sLength);
for each(_char c in sText)
{
int iCharValue = (int)c;
String^ sTemp = s_SN10ToSN62(iCharValue + iLength);
sbResult->Append(s_SN10ToSN62(sTemp->Length));
sbResult->Append(sTemp);
}
int iCheckValue = 0;
for(int i = 0; i < sbResult->Length; ++i)
{
iCheckValue += (int)sbResult[i];
}
String^ sCheckValue = s_SN10ToSN62(iCheckValue);
sbResult->Append(sCheckValue);
sbResult->Append(s_SN10ToSN62(sCheckValue->Length));
return sbResult->ToString();
}
String^ global_clr_extend::s_TextDecrypt2(String^ sEncryptText)
{
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位(永远1位)
// a
// 1 + 1 + 2 + (97+1)
if (sEncryptText->Length < 5) //不能少于5位,空字符是:101z2
return sEncryptText;
//加密字符值总和占用位
String^ sCountLength = sEncryptText[sEncryptText->Length - 1].ToString();
if ( !s_IsSN62Number(sCountLength))
{
return sEncryptText;
}
int iCountLength = s_SN62ToSN10(sCountLength);//加密字符值总和占用位
if (iCountLength > sEncryptText->Length - 1 || iCountLength < 0)
{
d.ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0","String^ global_clr_extend::s_TextDecrypt2(String^ sEncryptText)");
return sEncryptText;
}
String^ sCount = sEncryptText->Substring(sEncryptText->Length - 1 - iCountLength, iCountLength);
//----------------------------------------------------------------2020-05-15加入
// (1) 10进制 int类型的最大值是:2147483647 = 62进制 2lkCB1
// (2) 如果sCount不是62进制,则密文错误
if (sCount->Length > 6 || ! s_IsSN62Number(sCount))
{
return sEncryptText;
}
//------------------------------------------------------------------------------
int iCheckValue = s_SN62ToSN10(sCount);
if (iCheckValue <= 0)
{
d.ShowInfo("iCheckValue <= 0");
return sEncryptText;
}
//检查校验码
String^ sEncryptData = sEncryptText->Substring(0, sEncryptText->Length - 1 - iCountLength);
int iCheckValue2 = 0;
for each(char c in sEncryptData)
{
iCheckValue2 += (int)c;
}
if (iCheckValue2 != iCheckValue) //文件检验失败!
{
d.ShowInfo("iCheckValue2 != iCheckValue");
return sEncryptText;
}
//校验码已通过
int iLengthCount = s_SN62ToSN10(sEncryptData[0].ToString());
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (iLengthCount > sEncryptData->Length - 1)
{
d.ShowInfo("iLengthCount > sEncryptData.Length - 1");
return sEncryptText;
}
int iTextLength = s_SN62ToSN10(sEncryptData->Substring(1, iLengthCount)); //明文字符串长度
int iStart = 1 + iLengthCount;
StringBuilder^ sText = gcnew StringBuilder(sEncryptText->Length);
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData->Length - 1 - iLengthCount)
{
int iSubLength = s_SN62ToSN10(sEncryptData->Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData->Length)
{
d.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = s_SN62ToSN10(sEncryptData->Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
d.ShowError("iCharValue < 0");
return sEncryptText;
}
sText->Append(System::Convert::ToChar(iCharValue));
iStart = iStart + 1 + iSubLength;
}
if (sText->Length != iTextLength)
{
d.ShowError("sText.Length != iTextLength");
return sEncryptText; //长度检查
}
return sText->ToString();
}
String^ global_clr_extend::s_TextDecrypt2(String^ sEncryptText, String^ sKey)
{
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
String^ sDecryptText = s_TextDecrypt2(sEncryptText);
if (sDecryptText->Length == 0) //空字符
return "";
if (sDecryptText == sEncryptText) //失败返回原字符
return sEncryptText;
int nTextLengthCount = s_SN62ToSN10(sDecryptText[0].ToString());
//当传递的字符串是不带sKey的加密串时
if (sDecryptText->Length.ToString()->Length < nTextLengthCount) //母字符串的长度的占位数小于子字符串的长度的占位数是错误的
{
d.ShowError("母字符串的长度的占位数小于子字符串的长度的占位数是错误的");
return sEncryptText;
}
if (nTextLengthCount <= 0) //占位最少是1
{
d.ShowError("占位最少是1");
return sEncryptText;
}
int nTextLength = s_SN62ToSN10(sDecryptText->Substring(1, nTextLengthCount));
if (nTextLengthCount == -1 || nTextLength == -1) //失败
{
d.ShowError("nTextLengthCount == -1 || nTextLength == -1");
return sEncryptText;
}
int nCount = 0;
for each(char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % nTextLength + 1;
int nStart = 1 + nTextLengthCount + nText1_Lenth;
int nKeyLengthCount = s_SN62ToSN10(sDecryptText->Substring(nStart, 1));
//nKeyLengthCount <= 2 sKey.Length的长度大小是1~15,也就是 <= 2
if (nKeyLengthCount > 2) //密钥可能不对
{
d.ShowError("密钥可能不对");
return sEncryptText; //返回原字符
}
int nKeyLength = s_SN62ToSN10(sDecryptText->Substring(nStart + 1, nKeyLengthCount));
if (nKeyLengthCount == -1 || nKeyLength == -1) //失败
return sEncryptText;
String^ sCheckKey = s_resumeCode(sDecryptText->Substring(nStart + 1 + nKeyLengthCount, nKeyLength));
if (sCheckKey != sKey) //失败
{
//return sEncryptText;
return "密码不正确!";
}
String^ s1 = s_resumeCode(sDecryptText->Substring(1 + nTextLengthCount, nText1_Lenth));
String^ s2 = s_resumeCode(sDecryptText->Substring(nStart + 1 + nKeyLengthCount + nKeyLength, nTextLength - nText1_Lenth));
return s1 + s2;
}
String^ global_clr_extend::s_TextDecrypt(String^ sEncryptText, String^ sKey)
{
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
String^ sDecryptText = s_TextDecrypt(sEncryptText);
if (sDecryptText->Length == 0) //空字符
return "";
if (sDecryptText == sEncryptText) //失败返回原字符
return sEncryptText;
int nTextLengthCount = s_EnglishAlphabetToNumber(sDecryptText[0].ToString());
//当传递的字符串是不带sKey的加密串时
if (sDecryptText->Length.ToString()->Length < nTextLengthCount) //母字符串的长度的占位数小于子字符串的长度的占位数是错误的
{
return sEncryptText;
}
if (nTextLengthCount <= 0) //占位最少是1
{
return sEncryptText;
}
int nTextLength = s_EnglishAlphabetToNumber(sDecryptText->Substring(1, nTextLengthCount));
if (nTextLengthCount == -1 || nTextLength == -1) //失败
return sEncryptText;
int nCount = 0;
for each(char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % nTextLength + 1;
int nStart = 1 + nTextLengthCount + nText1_Lenth;
int nKeyLengthCount = s_EnglishAlphabetToNumber(sDecryptText->Substring(nStart, 1));
//nKeyLengthCount <= 2 sKey.Length的长度大小是1~15,也就是 <= 2
if (nKeyLengthCount > 2) //密钥可能不对
{
return sEncryptText; //返回原字符
}
int nKeyLength = s_EnglishAlphabetToNumber(sDecryptText->Substring(nStart + 1, nKeyLengthCount));
if (nKeyLengthCount == -1 || nKeyLength == -1) //失败
return sEncryptText;
String^ sCheckKey = s_resumeCode(sDecryptText->Substring(nStart + 1 + nKeyLengthCount, nKeyLength));
if (sCheckKey != sKey) //失败
return sEncryptText;
String^ s1 = s_resumeCode(sDecryptText->Substring(1 + nTextLengthCount, nText1_Lenth));
String^ s2 = s_resumeCode(sDecryptText->Substring(nStart + 1 + nKeyLengthCount + nKeyLength, nTextLength - nText1_Lenth));
return s1 + s2;
}
String^ global_clr_extend::s_TextEncrypt(String^ sText, String^ sKey)
{
if (sKey->Trim()->Length == 0 || sText->Length == 0)
return s_TextEncrypt(sText);
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
int nCount = 0;
for each(char c in sKey)
{
nCount += (int)c;
}
int nText1_Lenth = nCount % sText->Length + 1;
String^ s1 = sText->Substring(0, nText1_Lenth);
String^ s2 = sText->Substring(nText1_Lenth, sText->Length - nText1_Lenth);
String^ sTextLength = s_NumberShowToEnglishAlphabet(sText->Length);
String^ sTextLengthCount = s_NumberShowToEnglishAlphabet(sText->Length.ToString()->Length);
String^ sKeyLength = s_NumberShowToEnglishAlphabet(sKey->Length);
String^ sKeyLengthCount = s_NumberShowToEnglishAlphabet(sKey->Length.ToString()->Length);
String^ s = sTextLengthCount + sTextLength + s_messCode(s1) + sKeyLengthCount + sKeyLength + s_messCode(sKey) + s_messCode(s2);
return s_TextEncrypt(s);
}
String^ global_clr_extend::s_DES_Encrypt(String^ encryptString, String^ encryptKey)
{
try
{
cli::array<unsigned char>^ rgbKey = System::Text::Encoding::UTF8->GetBytes(encryptKey->Substring(0, 8));
array<unsigned char>^ rgbIV = Keys;
array<unsigned char>^ inputByteArray = System::Text::Encoding::UTF8->GetBytes(encryptString);
System::Security::Cryptography::DESCryptoServiceProvider^ dCSP = gcnew System::Security::Cryptography::DESCryptoServiceProvider();
MemoryStream^ mStream = gcnew MemoryStream();
System::Security::Cryptography::CryptoStream^ cStream = gcnew System::Security::Cryptography::CryptoStream(mStream,
dCSP->CreateEncryptor(rgbKey, rgbIV), System::Security::Cryptography::CryptoStreamMode::Write);
cStream->Write(inputByteArray, 0, inputByteArray->Length);
cStream->FlushFinalBlock();
return Convert::ToBase64String(mStream->ToArray());
}
catch(Exception^ e)
{
return encryptString;
}
}
String^ global_clr_extend::s_DES_Decrypt(String^ decryptString, String^ decryptKey)
{
try
{
array<unsigned char>^ rgbKey = System::Text::Encoding::UTF8->GetBytes(decryptKey);
array<unsigned char>^ rgbIV = Keys;
array<unsigned char>^ inputByteArray = System::Convert::FromBase64String(decryptString);
System::Security::Cryptography::DESCryptoServiceProvider^ DCSP = gcnew System::Security::Cryptography::DESCryptoServiceProvider();
MemoryStream^ mStream = gcnew MemoryStream();
System::Security::Cryptography::CryptoStream^ cStream = gcnew System::Security::Cryptography::CryptoStream(mStream, DCSP->CreateDecryptor(rgbKey, rgbIV),
System::Security::Cryptography::CryptoStreamMode::Write);
cStream->Write(inputByteArray, 0, inputByteArray->Length);
cStream->FlushFinalBlock();
return System::Text::Encoding::UTF8->GetString(mStream->ToArray());
}
catch (Exception^ e)
{
//gce::ShowInfo(e.ToString());
return decryptString;
}
}
下面用C++说明一下重点函数功能。
(1)messCode 与 resumeCode
/// <summary>
/// 随便打乱字符串,防止一眼就能看清内容,加1取反
/// </summary>
/// <returns></returns>
inline _Str<T> messCode()const {
_Str<T> result;
result.setBuffer(_nLength);
T* ps = result._pData;
for (size_t n = 0; n < _nLength; ++n)
{
ps[n] = ((T)(~((int)_pData[n] + 1)));
}
result.resetLength(_nLength);
return result;
}
/// <summary>
/// 还原打乱字符串
/// </summary>
/// <returns></returns>
inline _Str<T> resumeCode()const {
_Str<T> result;
result.setBuffer(_nLength);
T* ps = result._pData;
for (size_t n = 0; n < _nLength; ++n)
{
ps[n] = (T)(~((int)_pData[n]) - 1);
}
result.resetLength(_nLength);
return result;
}
例子:
(2)num_showToEnglishAlphabet 与 num_englishAlphabetToNumber
/// <summary>
/// 把正整数的个数,十位、百位等等都用英文表示:例:256 => cFg 123 => bCd
/// </summary>
/// <param name="iNumber">正整数</param>
/// 创建时间: 2020-04-05 最后一次修改时间:2025-03-22
/// <returns>英文表示的数字</returns>
static _Str<T> num_showToEnglishAlphabet(const size_t& nNumber) {
_Str<T> snum = _Math::intToStr(nNumber);
_Str<T> result;
result.setBuffer(snum.length());
for (int i = 0; i < snum.length(); ++i)
{
int ch = (int)snum[i];
if (i % 2 == 0)
result.add( (T)( ch + 97 - 48) ); //小写字母
else
result.add( (T)( ch + 65 - 48) ); //大写字母
}
return result;
}
/// <summary>
/// 把英文表示的非负数还原成真实的数字,不成功返回-1. 例: 123 => abc abc = > 123
/// </summary>
/// <param name="sEnglishAlphabet"></param>
/// 创建时间: 2020-04-05 最后一次修改时间:2025-03-22
/// <returns></returns>
size_t num_englishAlphabetToNumber() const {
if (_nLength == 0) return -1;
_Str<T> result;
result.setBuffer(20);
for (int i = 0; i < _nLength; ++i)
{
if (i % 2 == 0)
result.append((T) ((int)_pData[i] - 97 + 48) );
else
result.append((T) ((int)_pData[i] - 65 + 48) );
}
if ( !result.isAllArabicDigitString() ) {
return -1;
}
return _Math::strToInt_t(result.c_str());
}
例子:
(3)num_sn10Tosn62 与 num_sn62Tosn10
/// <summary>
///62进制表示
/// System Of Numeration (进制)
/// 0123456789 10 6061
/// </summary>
/// 创建时间:2022-12-03 最后一次修改时间:2025-02-09
const char* SN62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/// <summary>
/// 把十进制数转为62进制
/// </summary>
/// <param name="iValue">十进制整数值</param>
/// <returns>返回62进制字符串</returns>
/// 创建时间: 2020-04-26 最后一次修改时间:2025-03-22 (已测试)
static _Str<T> num_sn10Tosn62(const __int64& iValue) {
_string sResult;
sResult.setBuffer(20);
if (iValue == 0) {
sResult.add((T)'0');
return sResult;
}
if (iValue < 0) {
sResult.add((T)'-');
}
int iTemp = (iValue > 0 ? iValue : -iValue);
while (iTemp != 0)
{
int n = iTemp % 62;
sResult.append((T)gs.SN62[n]);
iTemp = iTemp / 62;
}
if (iValue < 0) {
sResult.reversal(1);
}
else {
sResult.reversal();
}
return sResult;
}
/// <summary>
/// 把62进制字符串转为十进制整数
/// </summary>
/// <param name="sValue"></param>
/// 创建时间: 2020-04-25 最后一次修改时间:2025-03-22 已测试
/// <returns></returns>
__int64 num_sn62Tosn10()const {
if (_nLength == 0)
{
_cout << _t("错误的数字!\n");
return 0;
}
_Str<T> sTemp = (_pData[0] == '-' ? reversal_copy(1) : reversal_copy());
__int64 iResult = 0;
_byte nExp = 0;
for (int i = 0; i < sTemp.length(); ++i) {
int n = _Math::strChr_t(gs.SN62, (char)sTemp[i]);
if (n == -1){
_cout << *this << _t("是错误的62进制数!\n");
return 0;
}
iResult += n * _Math::pow_uint(62, nExp);
++nExp;
}
return _pData[0] == '-' ? -iResult : iResult;
}
运行例子:
(4)toEncrypt2 与 toDecrypt2 (C++版本)
例子1:
例子2:
下面是代码:
/// <summary>
/// 把字符串按一定格式加密
/// </summary>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-27
/// <returns>返回加密的字符串</returns>
inline _Str<T> toEncrypt()const {
/*
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
StringBuilder^ sbResult = gcnew StringBuilder(sText->Length * 2);
int iLength = sText->Length;
String^ sLength = s_NumberShowToEnglishAlphabet(iLength);
String^ sLengthCount = s_NumberShowToEnglishAlphabet(sLength->Length);
sbResult->Append(sLengthCount);
sbResult->Append(sLength);
for each(_char c in sText)
{
int iCharValue = (int)c;
String^ sTemp = s_NumberShowToEnglishAlphabet(iCharValue + iLength);
sbResult->Append(s_NumberShowToEnglishAlphabet(sTemp->Length));
sbResult->Append(sTemp);
}
int iCheckValue = 0;
for (int i = 0; i < sbResult->Length; ++i)
{
iCheckValue += (int)sbResult[i];
}
String^ sCheckValue = s_NumberShowToEnglishAlphabet(iCheckValue);
sbResult->Append(sCheckValue);
sbResult->Append(s_NumberShowToEnglishAlphabet(sCheckValue->Length));
return sbResult->ToString();
*/
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
_Str<T> result;
result.setBuffer(_nLength * 2);
size_t nLength = _nLength;
_Str<T> sLength = num_showToEnglishAlphabet(nLength);
_Str<T> sLengthCount = num_showToEnglishAlphabet(sLength.length());
result.add(sLengthCount);
result.add(sLength);
for(size_t n = 0; n < _nLength; ++n)
{
T c = _pData[n];
size_t nCharValue = (size_t)c;
_Str<T> sTemp = num_showToEnglishAlphabet(nCharValue + nLength);
result.add(num_showToEnglishAlphabet(sTemp.length()));
result.add(sTemp);
}
size_t nCheckValue = 0;
for (size_t n = 0; n < result.length(); ++n)
{
nCheckValue += (int)result[n];
}
_Str<T> sCheckValue = num_showToEnglishAlphabet(nCheckValue);
result.add(sCheckValue);
result.add(num_showToEnglishAlphabet(sCheckValue.length()));
return result;
}
/// <summary>
/// 把密文解密成明文,如果解密不成功,则回原字符串
/// </summary>
/// <returns>成功返回明文,失败返回原字符串</returns>
/// 创建时间: 2020-04-05 最后一次修改时间:2020-04-19
_Str<T> toDecrypt()const {
/*
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
if (sEncryptText->Length < 6) //不能少于6位,空字符是:babJfd
return sEncryptText;
int iCountLength = s_EnglishAlphabetToNumber(sEncryptText[sEncryptText->Length - 1].ToString());
if (iCountLength > sEncryptText->Length - 1 || iCountLength < 0)
{
//gce::ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0");
return sEncryptText;
}
int iCheckValue = s_EnglishAlphabetToNumber(sEncryptText->Substring(sEncryptText->Length - 1 - iCountLength, iCountLength));
if (iCheckValue <= 0)
{
//gce::ShowInfo("iCheckValue <= 0");
return sEncryptText;
}
//检查校验码
String^ sEncryptData = sEncryptText->Substring(0, sEncryptText->Length - 1 - iCountLength);
int iCheckValue2 = 0;
for each(char c in sEncryptData)
{
iCheckValue2 += (int)c;
}
if (iCheckValue2 != iCheckValue) //文件检验失败!
{
return sEncryptText;
}
//校验码已通过
int iLengthCount = s_EnglishAlphabetToNumber(sEncryptData[0].ToString());
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (iLengthCount > sEncryptData->Length - 1)
{
return sEncryptText;
}
int iTextLength = s_EnglishAlphabetToNumber(sEncryptData->Substring(1, iLengthCount)); //明文字符串长度
int iStart = 1 + iLengthCount;
StringBuilder^ sText = gcnew StringBuilder(sEncryptText->Length);
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData->Length - 1 - iLengthCount)
{
int iSubLength = s_EnglishAlphabetToNumber(sEncryptData->Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData->Length)
{
d.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = s_EnglishAlphabetToNumber(sEncryptData->Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
d.ShowError("iCharValue < 0");
return sEncryptText;
}
sText->Append(System::Convert::ToChar(iCharValue));
iStart = iStart + 1 + iSubLength;
}
if (sText->Length != iTextLength)
{
d.ShowError("sText.Length != iTextLength");
return sEncryptText; //长度检查
}
return sText->ToString();
*/
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
if (_nLength < 6) //不能少于6位,空字符是:babJfd
return *this;
size_t nCountLength = substr(_nLength - 1, 1).num_englishAlphabetToNumber();
if (nCountLength > _nLength - 1 || nCountLength < 0)
{
//gce::ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0");
return *this;;
}
size_t nCheckValue = substr(_nLength - 1 - nCountLength, nCountLength).num_englishAlphabetToNumber();
//检查校验码
_Str<T> sEncryptData = substr(0, _nLength - 1 - nCountLength);
size_t nCheckValue2 = 0;
for (size_t n = 0; n < sEncryptData.length(); ++n) {
nCheckValue2 += (size_t)sEncryptData[n];
}
if (nCheckValue2 != nCheckValue) //文件检验失败!
{
std::cout << "文件检验失败!\n";
return *this;;
}
//校验码已通过
size_t nLengthCount = sEncryptData.substr(0,1).num_englishAlphabetToNumber();
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (nLengthCount > sEncryptData.length() - 1)
{
std::cout << "错误:nLengthCount > sEncryptData.length() - 1\n";
return *this;;
}
size_t nTextLength = sEncryptData.substr(1, nLengthCount).num_englishAlphabetToNumber(); //明文字符串长度
size_t nStart = 1 + nLengthCount;
_Str<T> sText;
sText.setBuffer(_nLength);
/*
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData->Length - 1 - iLengthCount)
{
int iSubLength = s_EnglishAlphabetToNumber(sEncryptData->Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData->Length)
{
d.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = s_EnglishAlphabetToNumber(sEncryptData->Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
d.ShowError("iCharValue < 0");
return sEncryptText;
}
sText->Append(System::Convert::ToChar(iCharValue));
iStart = iStart + 1 + iSubLength;
}
*/
//一定要加等于,否则最后一个字符是加不进去的
while (nStart <= sEncryptData.length() - 1 - nLengthCount)
{
size_t nSubLength = sEncryptData.substr(nStart, 1).num_englishAlphabetToNumber();
if (nSubLength < 0 || nSubLength >= sEncryptData.length())
{
std::cout << "nSubLength < 0 || nSubLength >= sEncryptData.length()\n";
return *this;
}
size_t nCharValue = sEncryptData.substr(nStart + 1, nSubLength).num_englishAlphabetToNumber() - nTextLength;
sText.append( (T)nCharValue);
nStart = nStart + 1 + nSubLength;
}
if (sText.length() != nTextLength)
{
std::cout << "sText.length() != iTextLength\n";
return *this;; //长度检查
}
return sText;
}
/// <summary>
/// 根据密钥来加密
/// </summary>
/// <param name="sText">要加密的字符串</param>
/// <param name="sKey">密钥</param>
/// 创建时间: 2020-04-27 最后一次修改时间:2020-04-27
/// <returns>近回加密字符串</returns>
_Str<T> toEncrypt2(const _Str<T>& sKey = _Str<T>()) {
/*-----------------------------------------------------------C++CLI
if (sKey->Trim()->Length == 0 || sText->Length == 0)
return s_TextEncrypt2(sText);
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
int nCount = 0;
for each(_char c in sKey)
{
nCount += (int)c;
}
int nText1_Length = nCount % sText->Length + 1;
String^ s1 = sText->Substring(0, nText1_Length);
String^ s2 = sText->Substring(nText1_Length, sText->Length - nText1_Length);
String^ sTextLength = s_SN10ToSN62(sText->Length);
String^ sTextLengthCount = s_SN10ToSN62(sTextLength->Length);
String^ sKeyLength = s_SN10ToSN62(sKey->Length);
String^ sKeyLengthCount = s_SN10ToSN62(sKeyLength->Length);
String^ s = sTextLengthCount + sTextLength + s_messCode(s1) + sKeyLengthCount + sKeyLength + s_messCode(sKey) + s_messCode(s2);
return s_TextEncrypt2(s);
}
*/
if (sKey.trim().length() == 0 || _nLength == 0) {
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位
// a
// 1 + 1 + 2 + (97+1)
_Str<T> result;
result.setBuffer(_nLength * 2);
size_t nLength = _nLength;
_Str<T> sLength = num_sn10Tosn62(nLength);
_Str<T> sLengthCount = num_sn10Tosn62(sLength.length());
result.add(sLengthCount);
result.add(sLength);
for (size_t n = 0; n < _nLength; ++n)
{
size_t nCharValue = (size_t)_pData[n];
_Str<T> sTemp = num_sn10Tosn62(nCharValue + nLength);
result.add(num_sn10Tosn62(sTemp.length()));
result.add(sTemp);
}
size_t nCheckValue = 0;
for (size_t n = 0; n < result.length(); ++n)
{
nCheckValue += (size_t)result[n];
}
_Str<T> sCheckValue = num_sn10Tosn62(nCheckValue);
result.add(sCheckValue);
result.add(num_sn10Tosn62(sCheckValue.length()));
return result;
}else {
/*
int nCount = 0;
for each(_char c in sKey)
{
nCount += (int)c;
}
int nText1_Length = nCount % sText->Length + 1;
String^ s1 = sText->Substring(0, nText1_Length);
String^ s2 = sText->Substring(nText1_Length, sText->Length - nText1_Length);
String^ sTextLength = s_SN10ToSN62(sText->Length);
String^ sTextLengthCount = s_SN10ToSN62(sTextLength->Length);
String^ sKeyLength = s_SN10ToSN62(sKey->Length);
String^ sKeyLengthCount = s_SN10ToSN62(sKeyLength->Length);
String^ s = sTextLengthCount + sTextLength + s_messCode(s1) + sKeyLengthCount + sKeyLength + s_messCode(sKey) + s_messCode(s2);
return s_TextEncrypt2(s);
*/
size_t nCount = 0;
for(const T& c : sKey){
nCount += (size_t)c;
}
size_t nText1_Length = nCount % _nLength + 1;
_Str<T> s1 = substr(0, nText1_Length);
_Str<T> s2 = substr(nText1_Length, _nLength - nText1_Length);
_Str<T> sTextLength = num_sn10Tosn62(_nLength);
_Str<T> sTextLengthCount = num_sn10Tosn62(sTextLength.length());
_Str<T> sKeyLength = num_sn10Tosn62(sKey.length());
_Str<T> sKeyLengthCount = num_sn10Tosn62(sKeyLength.length());
_Str<T> s = sTextLengthCount + sTextLength + s1.messCode() + sKeyLengthCount + sKeyLength +
sKey.messCode() + s2.messCode();
return s.toEncrypt2();
}
}
_Str<T> toDecrypt2(const _Str<T>& sKey = _Str<T>()) {
if (sKey.trim().length() == 0 || _nLength == 0) {
/*---------------------------------------------------C++cli
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位(永远1位)
// a
// 1 + 1 + 2 + (97+1)
if (sEncryptText->Length < 5) //不能少于5位,空字符是:101z2
return sEncryptText;
//加密字符值总和占用位
String^ sCountLength = sEncryptText[sEncryptText->Length - 1].ToString();
if (!s_IsSN62Number(sCountLength))
{
return sEncryptText;
}
int iCountLength = s_SN62ToSN10(sCountLength);//加密字符值总和占用位
if (iCountLength > sEncryptText->Length - 1 || iCountLength < 0)
{
d.ShowInfo("iCountLength > sEncryptText.Length - 1 || iCountLength < 0", "String^ global_clr_extend::s_TextDecrypt2(String^ sEncryptText)");
return sEncryptText;
}
String^ sCount = sEncryptText->Substring(sEncryptText->Length - 1 - iCountLength, iCountLength);
//----------------------------------------------------------------2020-05-15加入
// (1) 10进制 int类型的最大值是:2147483647 = 62进制 2lkCB1
// (2) 如果sCount不是62进制,则密文错误
if (sCount->Length > 6 || !s_IsSN62Number(sCount))
{
return sEncryptText;
}
//------------------------------------------------------------------------------
int iCheckValue = s_SN62ToSN10(sCount);
if (iCheckValue <= 0)
{
d.ShowInfo("iCheckValue <= 0");
return sEncryptText;
}
//检查校验码
String^ sEncryptData = sEncryptText->Substring(0, sEncryptText->Length - 1 - iCountLength);
int iCheckValue2 = 0;
for each(char c in sEncryptData)
{
iCheckValue2 += (int)c;
}
if (iCheckValue2 != iCheckValue) //文件检验失败!
{
d.ShowInfo("iCheckValue2 != iCheckValue");
return sEncryptText;
}
//校验码已通过
int iLengthCount = s_SN62ToSN10(sEncryptData[0].ToString());
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (iLengthCount > sEncryptData->Length - 1)
{
d.ShowInfo("iLengthCount > sEncryptData.Length - 1");
return sEncryptText;
}
int iTextLength = s_SN62ToSN10(sEncryptData->Substring(1, iLengthCount)); //明文字符串长度
int iStart = 1 + iLengthCount;
StringBuilder^ sText = gcnew StringBuilder(sEncryptText->Length);
//一定要加等于,否则最后一个字符是加不进去的
while (iStart <= sEncryptData->Length - 1 - iLengthCount)
{
int iSubLength = s_SN62ToSN10(sEncryptData->Substring(iStart, 1));
if (iSubLength < 0 || iSubLength >= sEncryptData->Length)
{
d.ShowError("iSubLength < 0 || iSubLength >= sEncryptData.Length");
return sEncryptText;
}
int iCharValue = s_SN62ToSN10(sEncryptData->Substring(iStart + 1, iSubLength)) - iTextLength;
if (iCharValue < 0)
{
d.ShowError("iCharValue < 0");
return sEncryptText;
}
sText->Append(System::Convert::ToChar(iCharValue));
iStart = iStart + 1 + iSubLength;
}
if (sText->Length != iTextLength)
{
d.ShowError("sText.Length != iTextLength");
return sEncryptText; //长度检查
}
return sText->ToString();
*/
//int 类型的最大值是:2147483647
//a~z 97-122 A~Z 65-90 0~9 48-57
// 字符串长度数值占用的字符位 + (字符串长度) + 原字符值与字符串长度之和占用的字符位 + (字符值 + 字符串长度) + 加密字符值总和 + 加密字符值总和占用的字符位(永远1位)
// a
// 1 + 1 + 2 + (97+1)
if (_nLength < 5) {//不能少于5位,空字符是:101z2{
std::cout << "错误:加密文本不能少于5位,空字符是:101z2" << "\n";
return *this;
}
//加密字符值总和占用位
_Str<T> sCountLength = substr(_nLength - 1, 1);
if (!sCountLength.num_isSN62Number())
{
std::cout << "错误:" << sCountLength << "不是62进制数" << "\n";
return *this;
}
size_t nCountLength = sCountLength.num_sn62Tosn10();//加密字符值总和占用位
if (nCountLength > _nLength - 1 || nCountLength < 0)
{
std::cout << "错误:nCountLength > _nLength - 1 || nCountLength < 0\n";
return *this;
}
_Str<T> sCount = substr(_nLength - 1 - nCountLength, nCountLength);
/*
//----------------------------------------------------------------2020-05-15加入
// (1) 10进制 int类型的最大值是:2147483647 = 62进制 2lkCB1
// (2) 如果sCount不是62进制,则密文错误
if (sCount->Length > 6 || !s_IsSN62Number(sCount))
{
return sEncryptText;
}
//------------------------------------------------------------------------------
*/
size_t nCheckValue = sCount.num_sn62Tosn10();
//检查校验码
_Str<T> sEncryptData = substr(0, _nLength - 1 - nCountLength);
size_t nCheckValue2 = 0;
for(const T& c : sEncryptData)
{
nCheckValue2 += (size_t)c;
}
if (nCheckValue2 != nCheckValue) //文件检验失败!
{
std::cout <<"错误:iCheckValue2 != iCheckValue\n";
return *this;
}
//校验码已通过
size_t nLengthCount = sEncryptData.substr(0,1).num_sn62Tosn10();
// if (iLengthCount >= sEncryptData.Length - 1) 错误: 空字符会失败
if (nLengthCount > sEncryptData.length() - 1)
{
std::cout << "错误:iLengthCount > sEncryptData.Length - 1\n";
return *this;
}
size_t nTextLength = sEncryptData.substr(1, nLengthCount).num_sn62Tosn10(); //明文字符串长度
size_t nStart = 1 + nLengthCount;
_Str<T> sText;
sText.setBuffer(_nLength);
//一定要加等于,否则最后一个字符是加不进去的
while (nStart <= sEncryptData.length() - 1 - nLengthCount)
{
size_t nSubLength = sEncryptData.substr(nStart, 1).num_sn62Tosn10();
if (nSubLength < 0 || nSubLength >= sEncryptData.length())
{
std::cout << "错误:nSubLength < 0 || nSubLength >= sEncryptData.length()";
return *this;
}
size_t nCharValue = sEncryptData.substr(nStart + 1, nSubLength).num_sn62Tosn10() - nTextLength;
sText.add((T)(nCharValue));
nStart = nStart + 1 + nSubLength;
}
if (sText.length() != nTextLength)
{
std::cout << "错误:sText.length() != nTextLength";
return *this; //长度检查
}
return sText;
}
else {
//(sText.Length的字符占位个数 + sText.Length) + sText1 + (sKey.Length的字符占位个数 + sKey.Length + skey) + sText2;
//关建插入点位置 InsertPos + Length + sKey
// InsertPos = sKey所有字符相加的和 % sText.Length //10%7=3
_Str<T> sDecryptText = toDecrypt2();
if (sDecryptText.length() == 0) //空字符
return *this;
if (sDecryptText.length() == _nLength) //失败返回原字符
return *this;
_Str<T> sTextLengthCount = sDecryptText.substr(0, 1);
size_t nTextLengthCount = sDecryptText.substr(0,1).num_sn62Tosn10();
//当传递的字符串是不带sKey的加密串时
if (_Math::intToStr(sDecryptText.length()).length() < nTextLengthCount) //母字符串的长度的占位数小于子字符串的长度的占位数是错误的
{
std::cout << "错误:母字符串的长度的占位数小于子字符串的长度。\n";
return *this;
}
if (nTextLengthCount <= 0) //占位最少是1
{
std::cout << "错误:占位最少是1。\n";
return *this;
}
size_t nTextLength = sDecryptText.substr(1, nTextLengthCount).num_sn62Tosn10();
size_t nCount = 0;
for(const T& c : sKey)
{
nCount += (size_t)c;
}
size_t nText1_Lenth = nCount % nTextLength + 1;
size_t nStart = 1 + nTextLengthCount + nText1_Lenth;
size_t nKeyLengthCount = sDecryptText.std_substr(nStart,1).num_sn62Tosn10();
//nKeyLengthCount <= 2 sKey.Length的长度大小是1~15,也就是 <= 2
if (nKeyLengthCount > 2) //密钥可能不对
{
std::cout << "错误:加密密钥可能不对!";
return *this; //返回原字符
}
size_t nKeyLength = sDecryptText.substr(nStart + 1, nKeyLengthCount).num_sn62Tosn10();
_Str<T> sCheckKey = sDecryptText.substr(nStart + 1 + nKeyLengthCount, nKeyLength).resumeCode();
if (sCheckKey != sKey) //失败
{
std::cout << "错误:加密密钥不正确!\n";
return this->qt_fromWCharArray(L"加密密钥不正确!");
}
_Str<T> s1 = sDecryptText.substr(1 + nTextLengthCount, nText1_Lenth).resumeCode();
_Str<T> s2 = sDecryptText.substr(nStart + 1 + nKeyLengthCount + nKeyLength, nTextLength - nText1_Lenth).resumeCode();
return s1 + s2;
}
}
由于是好几年写的,这个加密程序有没有问题,我自己看得都头晕,把密钥写入计算机可能不对,因为分析你的源代码,可能把密钥搞出来,一定要根据用户提供的密钥来确认数据的位置,如果用户密钥不对,真实数据位置无法确定,真实数据确定后,也要根据密钥来翻译成明文,密钥不对,任何一步都走不出来,且绝对不要把密钥写入计算机才对,任何形式都不行,但我想,自己用应该没问题,下次改进一下就行。:)
这里把数据分成两部分:
某一部分的长度是根据密钥来动态生成的
解密时根据密钥再合并起来:
不是根据密钥存在电脑中的位置来确认的,也就是说,没提供正确的密钥,也确认不了
密钥存在计算机的那个存储位置,所以密文给你也没关系,有源代码也没什么用。