📄 vernamdlg.cpp
字号:
// VernamDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Crypt.h"
#include "VernamDlg.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CVernamDlg dialog
CVernamDlg::CVernamDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVernamDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVernamDlg)
m_strBCipher = _T("");
m_strBKey = _T("");
m_strBPlainText = _T("");
m_strCipher = _T("");
m_strKey = _T("");
m_strPlainText = _T("");
m_strToPlainText = _T("");
//}}AFX_DATA_INIT
}
void CVernamDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVernamDlg)
DDX_Text(pDX, IDC_BCipher, m_strBCipher);
DDX_Text(pDX, IDC_BKey, m_strBKey);
DDX_Text(pDX, IDC_BPlainText, m_strBPlainText);
DDX_Text(pDX, IDC_Cipher, m_strCipher);
DDX_Text(pDX, IDC_Key, m_strKey);
DDX_Text(pDX, IDC_PlainText, m_strPlainText);
DDX_Text(pDX, IDC_ToPlainText, m_strToPlainText);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVernamDlg, CDialog)
//{{AFX_MSG_MAP(CVernamDlg)
ON_BN_CLICKED(IDC_Encrypt, OnVernamEncrypt)
ON_BN_CLICKED(IDC_Decrypt, OnVernamDecrypt)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVernamDlg message handlers
BOOL CVernamDlg::pick(char ch, int n)
{
//return(( ch & char(1)<<(8-n) )!=0);
return (ch & char(1)<<(8-n));
}
/*
Vernam体制:
Vernam密码在对明文加密前首先将明文编码为(0,1)字符串。
*/
void CVernamDlg::OnVernamEncrypt()
{
// TODO: Add your control notification handler code here
int i, j, k, milestone;
int pos;
int m_iPlainTextLen, m_iKeyLen;
char m_chPlainText[1000], m_chKey[1000], m_chCipher[1000];
for(i=0; i<1000; i++)
{
m_chPlainText[i] = '\0';
m_chKey[i] = '\0';
m_chCipher[i] = '\0';
}
UpdateData(true);
//首先或得明文和密钥,然后将字符串转换为二进制字符串
//然后按照加密算法进行运算,或得二进制密文流
//最后将二进制密文流转换成密文字符串。
m_iPlainTextLen = m_strPlainText.GetLength();
for(i=0; i<m_iPlainTextLen; i++)
m_chPlainText[i] = m_strPlainText.GetAt(i);
//--------------------------------------------------------------------
//显示明文的二进制表示
char* m_pBPlainText = new char[m_iPlainTextLen*8+m_iPlainTextLen];
int h = 0;
for(i=0; i<m_iPlainTextLen; i++)
{
for(j=1; j<=8; j++)
{
if(pick(m_chPlainText[i], j))
m_pBPlainText[h++] = '1';
else
m_pBPlainText[h++] = '0';
}
m_pBPlainText[h++] = ' ';
}
m_pBPlainText[h] = '\0';
m_strBPlainText.Format("%s", m_pBPlainText);
//--------------------------------------------------------------------
//-------------------------------------------------------------------
//显示密钥的二进制表示
m_iKeyLen = m_strKey.GetLength();
for(i=0; i<m_iKeyLen; i++)
m_chKey[i] = m_strKey.GetAt(i);
char* m_pBKey = new char[m_iKeyLen*8+m_iKeyLen];
h = 0;
for(i=0; i<m_iKeyLen; i++)
{
for(j=1; j<=8; j++)
{
if(pick(m_chKey[i], j))
m_pBKey[h++] = '1';
else
m_pBKey[h++] = '0';
}
m_pBKey[h++] = ' ';
}
m_pBKey[h++] = '\0';
m_strBKey.Format("%s", m_pBKey);
//--------------------------------------------------------------------
//建立密文空间,用来存放二进制密文
char* m_pBCipher = new char[m_iPlainTextLen*8+m_iPlainTextLen];
//char* m_pBCipher = new char[m_iPlainTextLen*8];
pos = 0;
//如果明文没有密钥长
if(m_iPlainTextLen <= m_iKeyLen)
{
for(i=0; i<m_iPlainTextLen; i++)
{
for(j=1; j<=8; j++)
{
if(pick(m_chPlainText[i],j) ^ pick(m_chKey[i],j))
m_pBCipher[pos++] = '1';
else
m_pBCipher[pos++] = '0';
}
m_pBCipher[pos++] = ' ';
}
}
//明文长度大于密钥长度
else
{
int quotient = m_iPlainTextLen / m_iKeyLen;
int compliment = m_iPlainTextLen % m_iKeyLen;
for(i=0; i<quotient; i++)
{
for(j=0; j<m_iKeyLen; j++)
{
for(k=1; k<=8; k++)
{
if(pick(m_chPlainText[i*m_iKeyLen+j],k) ^ pick(m_chKey[j], k))
m_pBCipher[pos++] = '1';
else
m_pBCipher[pos++] = '0';
}
m_pBCipher[pos++] = ' ';
}
}
milestone = quotient * m_iKeyLen;
for(i=0; i<compliment; i++)
{
for(j=1; j<=8; j++)
{
if(pick(m_chPlainText[milestone+i], j) ^ pick(m_chKey[i], j))
m_pBCipher[pos++] = '1';
else
m_pBCipher[pos++] = '0';
}
m_pBCipher[pos++] = ' ';
}
}
m_pBKey[pos++] = '\0';
m_strBCipher.Format("%s", m_pBCipher);
//将二进制密文转换为ASCII字符串
char* m_pCipher = new char[m_iPlainTextLen];
//AfxMessageBox(m_pBCipher);
if(BinToString(m_pBCipher, m_pCipher))
{
m_pCipher[m_iPlainTextLen] = '\0';
m_strCipher.Format("%s", m_pCipher);
//AfxMessageBox(m_pCipher);
}
UpdateData(false);
}
//将二进制字符串数组转换为字符串
bool CVernamDlg::BinToString(char *scStr, char *dsStr)
{
char ch = '\0';
if(scStr == NULL || strlen(scStr)==0)
return false;
while(strlen(scStr) >= 8)
{
if(!BinToChar(scStr, ch))
return false;
*dsStr = *dsStr + ch;
scStr += 8;
}
return true;
}
//将八位二进制数据转换为字符
bool CVernamDlg::BinToChar(char scStr[], char dsCh)
{
int i;
char ch = '\0';
if(scStr == NULL)
return false;
for(i=0; i<8; i++)
{
if(scStr[i] != '0' && scStr[i] != '1')
return false;
ch = scStr[i] - 48;
ch = ch << (8-i-1);
dsCh |= ch;
}
return true;
}
/*
通过明文的二进制表示恢复明文
*/
void CVernamDlg::OnVernamDecrypt()
{
// TODO: Add your control notification handler code here
int i;
int m_iBPlainTextLen, pos;
char m_Bch;
char m_chArr[8];
char m_chBPlainText[1000], m_chPlainText[1000];
for(i=0; i<1000; i++)
{
m_chBPlainText[i] = '\0';
m_chPlainText[i] = '\0';
}
UpdateData(true);
m_iBPlainTextLen = m_strBPlainText.GetLength();
for(i=0; i<m_iBPlainTextLen; i++)
{
m_Bch = m_strBPlainText.GetAt(i);
m_chBPlainText[i] = m_Bch;
}
//将二进制明文转换为字符串
pos = m_iBPlainTextLen;
int position = 0;
int num = 0;
while(pos > 0)
{
for(i=position; i<position+8; i++)
m_chArr[i-position] = m_chBPlainText[i];
for(i=0; i<8; i++)
{
if(m_chArr[i] == '1')
m_chPlainText[num] += (int)pow(2, 7-i);
}
num ++;
position += 9;
pos -= 9;
}
m_strToPlainText.Format("%s", m_chPlainText);
UpdateData(false);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -