C/C++对字串简单进行可逆加密(1)

注意:本篇代码已经发现存在严重问题!给您带来麻烦真的不好意思。您可以看C/C++对字串简单进行可逆加密(2)

加密字串当然是为了安全,废话不多说,直接进入!

要想进行可逆加密,目前我只知道用或者,或对字符进行移位。

新建一个控制台工程。

简单用密钥对明文进行异或运算。异或运算不改变字串的长度。

#include <iostream.h>
#include <windows.h>
#include <tchar.h>

void EncodeString(LPTSTR lpszText, LPCTSTR lpszKey)
{
	int nTextLen = ::_tcslen(lpszText);
	int nKeyLen = ::_tcslen(lpszKey);
	int i = 0;
	int k = 0;
	for(; i < nTextLen; i++)
	{
		lpszText[i] = lpszText[i] ^ lpszKey[k];
		k++;
		if(k >= nKeyLen)
			k = 0;
	}
}

int main(int argc, char* argv[])
{
	char strText[] = "Hello world!";

	cout<<strText<<endl;
	cout<<"========================================"<<endl;
	EncodeString(strText, "Zimmerk");	// 加密
	cout<<strText<<endl;
	cout<<"========================================"<<endl;
	EncodeString(strText, "Zimmerk");	// 解密
	cout<<strText<<endl;
	return 0;
}

运行发现加密,解密都正常。
但测试中发现,随着明文的增加,会出现解密不完整的情况,比如加密“Hello world! I'm zimmerk. I'm a boy. What's your name?”,这是因为加密得到的密文中含有特殊字符,导致_tcslen函数提前中止,获取字串长度不正确。这种上情况的解决方法可以是自己计算字串结尾。但如果字串中间出现\0,那就用不了了。

还有一种方法就是自己添加字串的中止标记。

这样无法确定字串长度,只好自己在函数内申请内存(当然你也可以用string)

我们设定在密文末尾加密自定的终止标记“==\0”

所以有以下代码

int nTextLen = 0;
char *cPos = NULL;
char *pDest = NULL;
if(!lpszReturn)	// 加密
{
	nTextLen = ::_tcslen(lpszText);
	pDest = (LPTSTR)lpszText;
}
else	// 解密
{
	cPos = ::_tcsstr(lpszText, _T("==\0"));	// 查找自定的中止标记
	if(!cPos)	// 没有找到结束标记,也不是加密
		return;
	nTextLen = cPos - lpszText;
	pDest = new char[nTextLen + 3];	// ==\0
}

但测试发现,随着字串长度的增加,::_tcsstr同样会无法正确获取到我们自定的终止标记,那只好自己搜索了。

 

#include <iostream.h>
#include <windows.h>
#include <tchar.h>

void EncodeString(LPCTSTR lpszText, LPTSTR *lpszReturn, LPCTSTR lpszKey)
{
	int nTextLen = 0;
	char *cPos = NULL;
	char *pDest = NULL;
	if(!lpszReturn)	// 加密
	{
		nTextLen = ::_tcslen(lpszText);
		pDest = (LPTSTR)lpszText;
	}
	else	// 解密
	{
		// 查找自定的中止标记
		cPos = (LPTSTR)lpszText;
		while(true)	// 从这里可以看到,除非搜索到我们自定的中止标记,否则会一直搜索下去
		{
			if(*cPos == '=')
				if(cPos[1] == '=')
					if(cPos[2] == '\0')
						break;
			cPos++;
		}
		if(!cPos)	// 没有找到结束标记,也不是加密
			return;
		nTextLen = cPos - lpszText;
		pDest = new char[nTextLen + 3];	// ==\0
	}

	int nKeyLen = ::_tcslen(lpszKey);
	int i = 0;
	int k = 0;
	for(; i < nTextLen; i++)
	{
		pDest[i] = lpszText[i] ^ lpszKey[k];
		k++;
		if(k >= nKeyLen)
			k = 0;
	}

	if(!cPos)
		memcpy(pDest + nTextLen, _T("==\0"), 3 * sizeof(TCHAR));
	else
	{
		memset(pDest  + nTextLen, _T('\0'), sizeof(TCHAR));
		*lpszReturn = pDest;
	}
}

int main(int argc, char* argv[])
{
	char strText[] = "Hello world! I'm zimmerk. I'm a boy. What's your name?";
	char *lpszDest = NULL;
	cout<<strText<<endl;
	cout<<"========================================"<<endl;
	EncodeString(strText , NULL, "Zimmerk");	// 加密
	cout<<strText<<endl;
	cout<<"========================================"<<endl;
	EncodeString(strText, &lpszDest, "Zimmerk");	// 解密
	if(*lpszDest)
	{
		cout<<lpszDest<<endl;
		delete [] lpszDest;
	}
	else
		cout<<_T("(NULL)")<<endl;
	return 0;
}

在测试中发现,再长的字串也能正常解密。

但还发现一个问题,如果知道密钥的一部分,密文就能解出一部分来,这样试下去,密钥不难被试出来。如果才能增大试出密钥的难度能,现在已经晚了,等下一篇文章吧。呵呵.

以上代码在Windows 2003 Server + VC6.0下编译通过

代码下载地址:https://files.cnblogs.com/bllqbz/EncodeString1.zip

原文链接: https://www.cnblogs.com/zimmerk/archive/2011/08/28/2156547.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C/C++对字串简单进行可逆加密(1)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/31302

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午8:32
下一篇 2023年2月8日 上午8:33

相关推荐