天天看點

關于單表代換密碼分析程式設計{C++}

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <fstream>
#include <iostream>
using namespace std;

char ciphertextB[1000],ciphertextC[1000];
char tongji[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

int plaintextA[27];//存放明文對應的數值
char plaintextB[27];//明文表
int plaintextC[27];
char u1,u2,v1,v2;	
int p=0;

char wmax1,wmax2;
void yanzheng(int t1,int t2);
void count(char s[]);
void findmax(int k[]);
void change(char x1,char x2,char y1,char y2);
int qiuniyuan(int r1,int r2);
void dx(char s1[]);
int main( )
{
	
	printf("insert the ciphertextA:\n");
	fstream infile;
	char ciphertextA[1000];
	infile.open("F:\\miwen.txt", fstream::in);
	infile >> ciphertextA;
	cout << ciphertextA << endl;
	
	dx(ciphertextA);
	puts(ciphertextA);
	count(ciphertextA);
	printf("\nplease insert the supposed key ");
	scanf("%c%c%c%c",&u1,&u2,&v1,&v2);
	change(u1,u2,v1,v2);
	system("pause");
	return 0;

}
void dx(char s1[])
{
	int i=0;
	for (i=0;s1[i]!='\0';i++)
	{
		if (s1[i]>='A'&&s1[i]<='Z')
			s1[i]=s1[i]+32;
	}
}
void count(char s[])//統計字母頻率
{	
	int tongji2[27]={0};//存放字母出現次數
	int i=0;
	int q=0;
	for (q=0;tongji[q]!='\0';q++)
	{
		for (i=0;s[i]!='\0';i++)
		{
			if (tongji[q]==s[i])
			{
				tongji2[q]=tongji2[q]+1;
			}
		}
	}
	for (q=0;q<=27;q++)
	{
		printf("%d",tongji2[q]);
	}
	findmax(tongji2);
	
}
void findmax(int k[])//尋找最大的兩個數
{
	int m=0;
	int max1=0;
	int max2=0;
	int maxz1=0;
	int maxz2=0;
	for (m=0;m<27;m++)
	{
		if (k[m]>=max1)
			{
				max1=k[m];
				maxz1=m;
				wmax1=tongji[m];
			}
	}
	printf("\nthe first num is %d",max1);
	printf("\nthe word is %c",wmax1);
	for (p=0;(p<27&&p!=maxz1);p++)
	{
		if (k[p]>=max2&&k[p]<=max1)
			{
				max2=k[p];
				maxz2=p;
				wmax2=tongji[p];
			}
	}
	printf("\nthe second num is %d",max2);
	printf("\nthe word is %c",wmax2);

}
	
void change(char x1,char x2,char y1,char y2)//輸入不同的對應字母尋找正确的a,b
{
	int a=0,b=0;
	int p1=0,p2=0,p3=0,p4=0;
	if (x1>='A'&&x1<='Z')
		x1=x1+32;
	if (x2>='A'&&x2<='Z')
		x2=x2+32;
	if (y1>='A'&&y1<='Z')
		y1=y1+32;
	if (y2>='A'&&y2<='Z')
		y2=y2+32;
	
	printf("x1=%d,x2=%d,y1=%d,y2=%d",x1,x2,y1,y2);
	p1=x1-97;
	p2=x2-97;
	p3=y1-97;
	p4=y2-97;
	printf("\np1=%d,p2=%d,p3=%d,p4=%d",p1,p2,p3,p4);
	int p11=0;
		int xishu[2][2]={p1,1,p2,1};
		int xishu2[2][2]={p3,0,p4,0};
		if (p1-p2<0)
		
			p11=qiuniyuan((p1-p2+26),26);
		else
			p11=qiuniyuan((p1-p2),26);
		
		printf("p11=%d",p11);
		int qq=p3-p4;
		a=(p11*qq)%26;
		b=(p3-p1*a)%26;
		printf("\na=%d,b=%d",a,b);
	yanzheng(a,b);
}

int qiuniyuan(int r1,int r2)//求一個數r1在模r2下的逆元,輸出為a1。
{
	int i=0,j,a,m,q,s1,s2,t1,t2,s,t,a1;
	
	a=r1;m=r2;
	s1=1;s2=0;
	t1=0;t2=1;
	do
	{   
		q=r1/r2;
		j=s2;
		s2=s1-q*s2;
		s1=j;
		j=t2;
		t2=t1-q*t2;
		t1=j;		
		j=r2;
		r2=r1-q*r2;
		r1=j;

	}while(r2!=0);
	s=s1;
	t=t1;
	a1=s%m;
	a1=a1%m;
	if(a1<0)
		a1=a1+m;
	printf("\n%d關于%d的逆元為%d\n",a,m,a1);
	
	return a1;
	
}

void yanzheng(int t1,int t2)//驗證映射關系
{
	int d=0;
	switch(t1)
	{
	case 1: d=1;break;
	case 3: d=9;break;
	case 5: d=21;break;
	case 7: d=15;break;
	case 9: d=3;break;
	case 11: d=19;break;
	case 15: d=7;break;
	case 17: d=19;break;
	case 19: d=11;break;
	case 21: d=5;break;
	case 23: d=17;break;
	case 25: d=25;break;
	}
	int k=0;
	int j=0;
	for(j=0;tongji[j]!='\0';j++)
	{
		plaintextC[j]=tongji[j]-97;
	}
	char dxciphertext[27];
	for (j=0;j<27;j++)
	{
		dxciphertext[j]=tongji[j]-32;
	}
	
	for (k=0;tongji[k]!='\0';k++)
	{
		if (plaintextC[k]-t2<0)
			plaintextA[k]=(d*(plaintextC[k]-t2+26))%26;
		else 
		plaintextA[k]=(d*(plaintextC[k]-t2))%26;

		plaintextB[k]=plaintextA[k]+65;
		printf("\n%c,%c\n",dxciphertext[k],plaintextB[k]);
	}
	
}
           

這個代碼為在隻知道單表代換密文的情況下根據密文中字母出現的頻率與人類統計出的英文字母使用頻率進行多次比對和假設進行明文的破譯。