⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 caesardedlg.cpp

📁 1、对于凯撒密文
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// CaesarDeDlg.cpp : implementation file
//

#include "stdafx.h"
#include "030300816.h"
#include "CaesarDeDlg.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

HWND m_hWnd;
CString m_plain;
char m_buffer[100000];
char m_buffout[100000];
int tetrfreq[26][26][26][26] , m_bpt;
/////////////////////////////////////////////////////////////////////////////
// CCaesarDeDlg dialog


CCaesarDeDlg::CCaesarDeDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCaesarDeDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCaesarDeDlg)
	m_cipherString = _T("");
	m_plainString = _T("");
	m_radio = 1;
	m_iMethod = 1;
	//}}AFX_DATA_INIT
}


void CCaesarDeDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCaesarDeDlg)
	DDX_Control(pDX, IDC_PLAIN, m_plainCtrl);
	DDX_Text(pDX, IDC_CIPHER, m_cipherString);
	DDX_Text(pDX, IDC_PLAIN, m_plainString);
	DDX_Radio(pDX, IDC_RADIO_P, m_radio);
	DDX_Text(pDX, IDC_TIME, m_time);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CCaesarDeDlg, CDialog)
	//{{AFX_MSG_MAP(CCaesarDeDlg)
	ON_BN_CLICKED(IDC_DECIPHER, OnDecipher)
	ON_BN_CLICKED(IDC_MODIFY_LEFT, OnModifyLeft)
	ON_BN_CLICKED(IDC_MODIFY_RIGHT, OnModifyRight)
	ON_BN_CLICKED(IDC_RADIO_P, OnRadioP)
	ON_BN_CLICKED(IDC_RADIO_H, OnRadioH)
	ON_WM_CTLCOLOR()
	ON_BN_CLICKED(IDC_RADIO_M, OnRadioM)
	ON_BN_CLICKED(IDC_RADIO_K, OnRadioK)
	ON_BN_CLICKED(IDC_RADIO_N, OnRadioN)
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCaesarDeDlg message handlers

DWORD WINAPI CTetr( LPVOID lpParam ) 
{
	FILE *tet;
//	char s[20];
	int d;
	tet = fopen( "tetra.txt" , "rt" );//读tetra.txt
	for ( int i = 0 ; i < 26 ; i ++ )
		for ( int j = 0 ; j < 26 ; j ++ )
			for ( int k = 0 ; k < 26 ; k ++ )
				for ( int l = 0 ; l < 26 ; l ++ )
				{
					fscanf ( tet , "%d" , &d );
					tetrfreq[i][j][k][l] = d;
				}
/*	while(1)
	{ 
		if( fscanf( tet , "%s" , s ) != 1 )//读前4个字符
			break;
		fscanf( tet , "%d" , &d );//读频率
		tetfreq[s[0]-'a'][s[1]-'a'][s[2]-'a'][s[3]-'a'] = d;//存各自频率
	}*/
	fclose( tet );//read tetra over
	return 0;
}

void CCaesarDeDlg::OnDecipher() 
{
	// TODO: Add your control notification handler code here
	start=clock();
	CString str;
	SetDlgItemText(IDC_PLAIN,"");
	if ( 0 == m_iMethod )
	{
		DecipherP();//盲目搜索式
		GetDlgItemText(IDC_PLAIN,str);
		Getsuggestion(str);
	}
	else if ( 1 == m_iMethod )//频率改进式
	{
		DecipherM();
		GetDlgItemText(IDC_PLAIN,str);
		Getsuggestion(str);
	}
	else if ( 2 == m_iMethod )//无敌概率式
	{
		DecipherH();
		GetDlgItemText(IDC_PLAIN,str);
		Getsuggestion(str);
	}
	else if ( 3 == m_iMethod )//超级综合式
	{
		if ( !DecipherH() )
			DecipherM();
		GetDlgItemText(IDC_PLAIN,str);
		Getsuggestion(str);
	}
	else//无间绝杀式
	{
		DecipherN();
		SetDlgItemText(IDC_SUGGESTION,"此法由于采用中间无空格或标点的方式,故不进行拼写检查");
	}

}

void CCaesarDeDlg::OnModifyLeft() 
{
	// TODO: Add your control notification handler code here
	CString temp = _T("");
	GetDlgItemText(IDC_SUB,temp);
	m_shift = temp.GetAt(0) - 'A';
	m_shift = ( m_shift + 1 ) % 26;
	char strr[100000];
	GetDlgItemText(IDC_CIPHER,strr,100000);
	CString str = strr;
	int length = str.GetLength();
	LPTSTR p = str.GetBuffer(length);	//将CString变为字符数组,便于操作
	for ( int j = 0 ; j < length ; j ++ )
	{
		if ( p[j] >= 'A' && p[j] <= 'Z' )	//密文字母 -> 密文字母 + cont
			p[j] = ( p[j] - 'A' + (26-m_shift%26) ) % 26 + 'A';
		else if ( p[j] >= 'a' && p[j] <= 'z' )
			p[j] = ( p[j] - 'a' + (26-m_shift%26) ) % 26 + 'a';
		else
			continue;
	}
	str.ReleaseBuffer();
	GetDlgItem(IDC_PLAIN)->SetWindowText(str);
	ShowSub ( m_shift );
}

void CCaesarDeDlg::OnModifyRight() 
{
	// TODO: Add your control notification handler code here
	CString temp = _T("");
	GetDlgItemText(IDC_SUB,temp);
	m_shift = temp.GetAt(0) - 'A';
	m_shift = ( m_shift - 1 + 26) % 26;
	char strr[100000];
	GetDlgItemText(IDC_CIPHER,strr,100000);
	CString str = strr;
	int length = str.GetLength();
	LPTSTR p = str.GetBuffer(length);	//将CString变为字符数组,便于操作
	for ( int j = 0 ; j < length ; j ++ )
	{
		if ( p[j] >= 'A' && p[j] <= 'Z' )	//密文字母 -> 密文字母 + cont
			p[j] = ( p[j] - 'A' + (26-m_shift%26) ) % 26 + 'A';
		else if ( p[j] >= 'a' && p[j] <= 'z' )
			p[j] = ( p[j] - 'a' + (26-m_shift%26) ) % 26 + 'a';
		else
			continue;
	}
	str.ReleaseBuffer();
	GetDlgItem(IDC_PLAIN)->SetWindowText(str);
	ShowSub ( m_shift );
}

void CCaesarDeDlg::OnRadioP() 
{
	// TODO: Add your control notification handler code here
	m_iMethod = 0;
	m_wndTaskbarNotifier->Show("盲目搜索式:从密文本身开始搜索,搜索26遍,找寻与词库中匹配单词最多的那组,显示在明文框中。");
}

void CCaesarDeDlg::OnRadioH() 
{
	// TODO: Add your control notification handler code here
	m_iMethod = 1;
	m_wndTaskbarNotifier->Show("频率改进式:在盲目搜索式的基础上加入了频率信息,从最多字母假设为e开始匹配,然后是t,i,a,o...使得尽量快的找到匹配数最多的“明文”,显示在明文框中。");
}

void CCaesarDeDlg::DecipherP()//盲目搜索式
{
		// TODO: Add your control notification handler code here
	UpdateData();
	int m_matched = 0;
	int m_matchedMost = 0;
	int m_finalChoice = 0;
	m_plainString = _T("");						//将明文置空
	int length = m_cipherString.GetLength();	//得到密文长度
//	int isCorrect = false;						//初始化“是否正确”标签
	CString original_cipher = m_cipherString;	//原始的密文,不变的
	CString str = m_cipherString;				//临时替换
	if ( str != _T("") )
	{
		for ( int i = 0 ; i < 26 ; i ++ )	//遇到isCorrect=true就跳出
		{
			str = original_cipher;				//初始化str变量
			LPTSTR p = str.GetBuffer(length);	//将CString变为字符数组,便于操作
			for ( int j = 0 ; j < length ; j ++ )
			{
				if ( p[j] >= 'A' && p[j] <= 'Z' )	//密文字母 -> 密文字母 + cont
					p[j] = ( p[j] - 'A' + (i%26) ) % 26 + 'A';
				else if ( p[j] >= 'a' && p[j] <= 'z' )
					p[j] = ( p[j] - 'a' + (i%26) ) % 26 + 'a';
				else
					continue;
			}
			m_matched = CountString(str);		//判断移位后的密文是否所有单词都能找到
			if ( m_matched >= m_matchedMost )
			{
				ShowTime();						//刷新时间
				m_matchedMost = m_matched;		//替换匹配最多的
				m_finalChoice = i;	
				GetDlgItem(IDC_PLAIN)->SetWindowText(str);
				UpdateWindow();
				str.ReleaseBuffer();
				ShowSub(26-i%26);					//显示对应关系,即密钥
			}
		}
/*		str = original_cipher;				//初始化str变量
		LPTSTR p = str.GetBuffer(length);	//将CString变为字符数组,便于操作
		for ( int j = 0 ; j < length ; j ++ )
		{
			if ( p[j] >= 'A' && p[j] <= 'Z' )	//密文字母 -> 密文字母 + cont
				p[j] = ( p[j] - 'A' + (m_finalChoice%26) ) % 26 + 'A';
			else if ( p[j] >= 'a' && p[j] <= 'z' )
				p[j] = ( p[j] - 'a' + (m_finalChoice%26) ) % 26 + 'a';
			else
				continue;
		}
		str.ReleaseBuffer();
		GetDlgItem(IDC_PLAIN)->SetWindowText(str);
		ShowSub(26-m_finalChoice%26);				//显示最后结果*/
	}
}

bool CCaesarDeDlg::DecipherH()//无敌概率式
{
	// TODO: Add your control notification handler code here
	UpdateData();
	char alphaFreq[27] = "etiaonsrhcldpyumfbgwvkxqzj";
//	SetTimer(1, 1000, NULL);
//	CTime begin = CTime::GetCurrentTime();
//	CTimeSpan time;
	m_plainString = _T("");						//将明文置空
	int length = m_cipherString.GetLength();	//得到密文长度
	bool isCorrect = false;						//初始化“是否正确”标签
	CString original_cipher = m_cipherString;	//原始的密文,不变的
	CString str = m_cipherString;				//临时替换
	int most = CountMost ( m_cipherString );	//算哪个字母最多
//	cont = 26 - most + 4;						//最多的字母初始为'e'
//	cont = 0;
	int diff = 26 - ( most - alphaFreq[cont] );	//初始化第一个最多的字母为'e'
	if ( str != _T("") )
	{
		for ( int i = 0 ; ( i < 26 && !isCorrect ); i ++ , cont ++)	//遇到isCorrect=true就跳出
		{
			diff = 26 - ( most - alphaFreq[i] );
			str = original_cipher;				//初始化str变量
			LPTSTR p = str.GetBuffer(length);	//将CString变为字符数组,便于操作
			for ( int j = 0 ; j < length ; j ++ )
			{
				if ( p[j] >= 'A' && p[j] <= 'Z' )	//密文字母 -> 密文字母 + cont
					p[j] = ( p[j] - 'A' + (diff%26) ) % 26 + 'A';
				else if ( p[j] >= 'a' && p[j] <= 'z' )
					p[j] = ( p[j] - 'a' + (diff%26) ) % 26 + 'a';
				else
					continue;
			}
			/*str.ReleaseBuffer();
			CWnd * wnd = GetDlgItem(IDC_PLAIN);
			wnd->SetDlgItemText(IDC_PLAIN,str);*/
			GetDlgItem(IDC_PLAIN)->SetWindowText(str);
			UpdateWindow();
			str.ReleaseBuffer();
			ShowSub(26-diff%26);					//显示对应关系,即密钥
			ShowTime();
		//	UpdateData(false);
		//	SetWindowText(IDC_PLAIN,str);
			isCorrect = CheckString(str);		//判断移位后的密文是否所有单词都能找到
		}
		if ( isCorrect )
		{
			ShowTime();
			GetDlgItem(IDC_PLAIN)->SetWindowText(str);	//显示中间过程
			ShowSub(26-diff%26+1);						//显示中间替换过程
		//	UpdateData(false);
		}
		else
		{
		//	m_plainString = "密文有误或词库不够全。。。";
		//	GetDlgItem(IDC_PLAIN)->SetWindowText("密文有误或词库不够全。。。");
		//	GetDlgItem(IDC_PLAIN)->SetWindowText(str);
			ShowTime();
			diff = 26 - ( most - alphaFreq[0] );
			str = original_cipher;				//初始化str变量
			LPTSTR p = str.GetBuffer(length);	//将CString变为字符数组,便于操作
			for ( int j = 0 ; j < length ; j ++ )
			{
				if ( p[j] >= 'A' && p[j] <= 'Z' )	//密文字母 -> 密文字母 + cont
					p[j] = ( p[j] - 'A' + (diff%26) ) % 26 + 'A';
				else if ( p[j] >= 'a' && p[j] <= 'z' )
					p[j] = ( p[j] - 'a' + (diff%26) ) % 26 + 'a';
				else
					continue;
			}
			str.ReleaseBuffer();
			GetDlgItem(IDC_PLAIN)->SetWindowText(str);
			ShowSub(26-diff%26);				//显示最后结果
		}
	}
/*	CTime end = CTime::GetCurrentTime();
	CTimeSpan total = end - begin;
	LONGLONG TT = total.GetTotalSeconds();
	CString pp;
	pp.Format("%d",TT);
	MessageBox(pp,NULL,MB_OK);*/
//	UpdateData(false);
	return isCorrect;
}

HBRUSH CCaesarDeDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)	//修改密钥颜色,变红
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
/*	// TODO: Change any attributes of the DC here
	if (pWnd->GetDlgCtrlID() == IDC_SUB 
		|| pWnd->GetDlgCtrlID() == IDC_MI)
	{
		// Set the text color to red
		pDC->SetTextColor(RGB(255, 0, 0));
		
		// Set the background mode for text to transparent 
		// so background will show thru.
		pDC->SetBkMode(TRANSPARENT);
	}
*/	// TODO: Return a different brush if the default is not Ideaired
	return hbr;
}

BOOL CCaesarDeDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	m_shift = 0;
	cont = 0;
//	pSkin->ApplySkin((long)m_hWnd);
	::m_hWnd = GetSafeHwnd();
	hTetraThread = CreateThread(
			NULL,
			0,
			CTetr,
			&tetrfreq,
			0,
			&dwTetraThreadId);
		if(hTetraThread==NULL)
			AfxMessageBox("创建线程失败!");
	// CG: The following block was added by the ToolTips component.	{		// Create the ToolTip control.		m_tooltip.Create(this);		m_tooltip.Activate(TRUE);		// TODO: Use one of the following forms to add controls:		// m_tooltip.AddTool(GetDlgItem(IDC_<name>), <string-table-id>);		// m_tooltip.AddTool(GetDlgItem(IDC_<name>), "<text>");
		m_tooltip.AddTool(GetDlgItem(IDC_RADIO_P), "盲目搜索咯,没啥好说的了。");
		m_tooltip.AddTool(GetDlgItem(IDC_RADIO_H), "如果确信密文中有些单词在词典里面没有的话用这个");
		m_tooltip.AddTool(GetDlgItem(IDC_RADIO_M), "如果确信密文中所有单词都在词典里面的话用这个");
		m_tooltip.AddTool(GetDlgItem(IDC_RADIO_K), "无法肯定密文中是否存在词典中没有的词用这个,但速度较慢");
		m_tooltip.AddTool(GetDlgItem(IDC_RADIO_N), "如果密文中单词间没有空格用这个,密文长度太短则失效");
		m_tooltip.AddTool(GetDlgItem(IDC_CIPHER), "请输入密文");
		m_tooltip.AddTool(GetDlgItem(IDC_PLAIN), "明文显示区域");
		m_tooltip.AddTool(GetDlgItem(IDC_MODIFY_LEFT), "手动调整");
		m_tooltip.AddTool(GetDlgItem(IDC_MODIFY_RIGHT), "手动调整");
		m_tooltip.AddTool(GetDlgItem(IDC_DECIPHER), "开始解码");	}
	m_hArrow = AfxGetApp()->LoadCursor(IDC_MYARROW);
	m_hHand = AfxGetApp()->LoadCursor(IDC_MYHAND);
	m_hBeam = AfxGetApp()->LoadCursor(IDC_MYBEAM);
	m_hPen = AfxGetApp()->LoadCursor(IDC_MYPEN);
	m_hMove = AfxGetApp()->LoadCursor(IDC_MYMOVE);
//	pSkin2->ApplySkin((long)m_hWnd);
//	m_wndTaskbarNotifier.Create(this);
//	m_wndTaskbarNotifier.SetSkin(IDB_BITMAP2,255,0,255);
//	m_wndTaskbarNotifier.SetTextFont("Arial Black",90,TN_TEXT_NORMAL,TN_TEXT_UNDERLINE | TN_TEXT_BOLD);
//	m_wndTaskbarNotifier.SetTextColor(RGB(255,255,255),RGB(255,255,255));
//	m_wndTaskbarNotifier.SetTextRect(CRect(10,20,m_wndTaskbarNotifier.m_nSkinWidth-10,m_wndTaskbarNotifier.m_nSkinHeight-20));
	m_wndTaskbarNotifier->Show("欢迎进入凯撒解码系统!\r\n可点击单选按钮获得相关信息!");
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

bool CCaesarDeDlg::CheckString(CString &str)
{
	CString strRes;
	//	ClearUnderline();
	//	m_rich.GetWindowText(str);
	int iStart = 0,iEnd =0, iLen=0, iStrLen;
	bool isCorrect = true;
	iStrLen = str.GetLength();
	while ( iEnd < iStrLen )
	{
		while ( iStart < iStrLen 
			&& !( ( str.GetAt(iStart) >= 'a' && str.GetAt(iStart) <= 'z' )
			|| ( str.GetAt(iStart) >= 'A' && str.GetAt(iStart) <= 'Z' ) ) )
			iStart ++;
		if (iStart == iStrLen)
			break;
		iEnd = iStart;
		while ( iEnd < iStrLen
			&& ( ( str.GetAt(iEnd) >= 'a' && str.GetAt(iEnd) <= 'z' )
			|| ( str.GetAt(iEnd) >= 'A' && str.GetAt(iEnd) <= 'Z' ) ) )
			iEnd ++;
		strRes = str.Mid(iStart,iEnd-iStart); //Extract the word
		if( m_pDictionary->IsWordListed(strRes) == eMatchNone 
			|| m_pDictionary->IsWordListed(strRes) == eMatchInternalError )	//check for spelling
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -