WeChall上的一题,把代码放在这里算作学习的一个过程。
什么是凯撒密码
它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。 ----百度百科
分析问题
也就是说,在知道密钥的情况下,用取余的方式即可将明文转换为密文;但在不知道密文的情况下,则无法直接对密文进行转换。
在文本长度较短的情况下,不适宜采用文本分析的方式来确定字符,因此直接采用暴力破解的形式,将密钥(偏移量)1-25全部试一遍,再用肉眼去观察哪一组是有明确词义句意的即可。
代码
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[] = "ESP BFTNV MCZHY QZI UFXAD ZGPC ESP WLKJ OZR ZQ NLPDLC LYO JZFC FYTBFP DZWFETZY TD TNSONDLMLOOL";
//对整个字符串循环,把1-25全部尝试一遍,i即为密钥
for(int i = 1; i < 26; i++)
{
//遍历字符串中的每个字符
for(int j = 0; j < strlen(str); j++)
{
if(str[j] == ' ') //如果j是空格,就将j原封不动地打印出来,因为我们需要划分单词
{
printf("%c", str[j]);
}
else //如果不是空格,就将当前字符向后移动i位,i为当前轮的密钥
{
printf("%c", (str[j] + i - 'A') % 26 + 'A'); //打印得到向后移动的密文
}
}
printf("\n\n");
}
return 0;
}
WeChall上每次密文都会变,所以在做的时候记得改变代码行中的密文。
运行结果
肉眼可以观察到第16组是有语义的,即密钥为16。