• 大小: 3KB
    文件类型: .zip
    金币: 2
    下载: 1 次
    发布日期: 2021-07-19
  • 语言: C/C++
  • 标签: Vigenère  

资源简介

在只知道密文的情况下,对密文分析。猜测密钥长度,然后进行验证,确定密钥长度后,破译出密钥,最后反解出原文。c语言代码,密文放在txt文件当中,破译的明文,也保存在txt文件当中,扩展性强

资源截图

代码片段和文件信息

#include
#include
#include
#include
#define top 100//设置输入上限 
int judge(char str[]);
void guess_keyt(char *secret);
void analysis(char *secretint lengthint m_len);
void translate(char *secretint lenint lengthint m_lenchar *alphabet);
void write_file(char yuan_wen[]);
int main()
{
FILE *fp;
char secret[1000];//保存初始密文
if((fp = fopen(“密文.txt““r“)) == NULL)//从文件当中读取初始,并保存在数组中
{
printf(“文件打开失败!“);
return -1;
}
fscanf(fp“%s“&secret);
fclose(fp);
guess_keyt(secret);
return 0;
}
//用来猜测密钥长度
void guess_keyt(char *secret)
{
int ijktotal = 0;
double max;
int m_len;//初步确认的密钥长度
int length;//初始密文长度
int num;//保存输入的密钥长度
char s_top[10];//输入的猜测的密钥长度,字符串格式,然后判断输入是否合法
char *secret1 = secret;
length = strlen(secret1);
printf(“请输入你认为的密钥最大长度(不超过%d):\n“top);
scanf(“%s“s_top);
num = judge(s_top);


int coincidence[top];//移动num位后,每次移动的重合次数
double average;//总共移动num次后,重合次数的平均数
double fangc[num];//总共移动num次后,每次移动的方差
//用凯撒猜测发,初步确认密钥长度 
//计算从移动1次,到移动你认为的最大次数的,重合次数 
for(i = 1;i <= num;i++)
{
coincidence[i-1] = 0;
for(j = 0k = i;j < length;j++k++)
{
if(k == length)
{
k = 0;
}
if(secret[k] == secret1[j])
{
coincidence[i-1]++;
}
}
}
printf(“移动%d的重合次数分别为:\n“num);
 
for(i = 0;i < num;i++)
{
total = total + coincidence[i];
printf(“%d “coincidence[i]);
}

//计算每一次的样本方差,用来找出最佳值 
average = total*1.0/num;
printf(“%d“total);
printf(“\n\n这%d次的平均数为:\n%.2f\n\n“numaverage);
printf(“样本方差分别为:\n“);

for(i = 0;i < num;i++)
{
fangc[i] = (coincidence[i] - average)*(coincidence[i] - average);
printf(“%.2f  “fangc[i]);
}

//方差最大值时对应的次数,最有可能就是密钥的长度,计算可能的密钥长度 
for(i = 0;i < num;i++)
{
if(max < fangc[i])
{
max = fangc[i];
m_len = i + 1;
}
}
printf(“\n\n我们可以明显的看出来,第%d个样本方差为%.2f远远大于其他数据\n即密钥长度可能为:%d\n\n接下来通过重合指数进行验证\n\n\n“m_lenmaxm_len);
analysis(secretlengthm_len);
// printf(“%d“num);
}
void analysis(char *secretint lengthint m_len)
{
int i = 0j = 0k = 0num = 0;
int len;//分组后每组的长度
float average = 0ave1 = 0ave2 = 0;
char group[m_len][len];//分组后的密文 
char alphabet[] = {“ABCDEFGHIJKLMNOPQRSTUVWXYZ“};
int frequency[m_len][26];//分组后每组每个字母的频数 
double ratio[m_len];//每组中任取两个字母相同的概率 
len = length / m_len;//按密钥长度对密文进行分组,计算每组的长度
if(length % m_len != 0)
{
len++;
}
for(i = 0;i < len;i++)//对密文分组
{
for(j = 0;j < m_len;j++)
{
group[j][i] = secret[k];
k++;
}
}

for(i = 0;i < m_len;i++)//对分组后的密文,计算每组当中每个字母出现的频数
{
for(j = 0;j < 26;j++)
{
frequency[i][j] = 0;
for(k = 0;k < len;k++)
{
if(group[i][k] == alphabet[j])
{
frequency[i][j]++;
}
}
}
}
for(i = 0;i < m_len;i++)//对每一组分别计算重合指数,即任取两个字母相同的概率
{
ratio[i] = 0;
num = 0;
for(j = 0;j < 26;j++)
{
if(frequency[i][j] >= 2)//出现次数小于2的字母,不存在取到两个相同的情况
{
num += frequency[i][j]*(frequency[i][j

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     文件         312  2017-02-25 15:49  密文.txt
     文件        7690  2017-03-10 22:21  维吉尼亚密码解析.cpp

评论

共有 条评论