① 关于棋盘密码(一种古典密码) 怎么解密,加密
棋盘密码的加密方法,其实方法十分简单,在密码学并不发达的古代,也够用了。棋盘密码的解题思路是这样
这种密码的原理是:通信双方各掌握一个m*n列的矩阵,比如A列第一行写上“我”,A列第2行写上“的”……以此类推,构成:
所以,“我的名字叫XXX”的密文即:A1A2A3A4B1B2。这样,一份密文就出来了。
使用这种密码表的加密也叫作 ADFGX 密码(密文中只有 A D F G X)
明文:HELLO 密文:DD XF AG AG DF
对于解密,对密文每两个字符一组,分别进行解密
由于密文仅包含5个字符,所以其密钥(也就是密码表)只有5!种可能
写脚本暴力攻击(brute-force)即可
棋盘密码的由来:
公元前2世纪前后希腊人提出了棋盘密码,在当时得到了广泛的运用。同时,它也是密码史上第一个密码。棋盘密码通过将26个字母设法变成十位数来达到加密的目的。棋盘密码的密钥是一个5×5的棋盘,将26个英文字母放置在里面。其中 i 和 j 共用一个密码。
② 古典密码安全算法有哪些
世界上最早的一种密码产生于公元前两世纪。是由一位希腊人提出的,人们称之为
棋盘密码,原因为该密码将26个字母放在5×5的方格里,i,j放在一个格子里,具体情
况如下表所示
1 2 3 4 5
1 a b c d e
2 f g h i,j k
3 l m n o p
4 q r s t u
5 v w x y z
这样,每个字母就对应了由两个数构成的字符αβ,α是该字母所在行的标号,β是列
标号。如c对应13,s对应43等。如果接收到密文为
43 15 13 45 42 15 32 15 43 43 11 22 15
则对应的明文即为secure message。
另一种具有代表性的密码是凯撒密码。它是将英文字母向前推移k位。如k=5,则密
文字母与明文与如下对应关系
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
F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
于是对应于明文secure message,可得密文为XJHZWJRJXXFLJ。此时,k就是密钥。为了
传送方便,可以将26个字母一一对应于从0到25的26个整数。如a对1,b对2,……,y对
25,z对0。这样凯撒加密变换实际就是一个同余式
c≡m+k mod 26
其中m是明文字母对应的数,c是与明文对应的密文的数。
随后,为了提高凯撒密码的安全性,人们对凯撒密码进行了改进。选取k,b作为两
个参数,其中要求k与26互素,明文与密文的对应规则为
c≡km+b mod 26
可以看出,k=1就是前面提到的凯撒密码。于是这种加密变换是凯撒野加密变换的
推广,并且其保密程度也比凯撒密码高。
以上介绍的密码体制都属于单表置换。意思是一个明文字母对应的密文字母是确定
的。根据这个特点,利用频率分析可以对这样的密码体制进行有效的攻击。方法是在大
量的书籍、报刊和文章中,统计各个字母出现的频率。例如,e出现的次数最多,其次
是t,a,o,I等等。破译者通过对密文中各字母出现频率的分析,结合自然语言的字母频
率特征,就可以将该密码体制破译。
鉴于单表置换密码体制具有这样的攻击弱点,人们自然就会想办法对其进行改进,
来弥补这个弱点,增加抗攻击能力。法国密码学家维吉尼亚于1586年提出一个种多表式
密码,即一个明文字母可以表示成多个密文字母。其原理是这样的:给出密钥
K=k[1]k[2]…k[n],若明文为M=m[1]m[2]…m[n],则对应的密文为C=c[1]c[2]…c[n]。
其中C[i]=(m[i]+k[i]) mod 26。例如,若明文M为data security,密钥k=best,将明
文分解为长为4的序列data security,对每4个字母,用k=best加密后得密文为
C=EELT TIUN SMLR
从中可以看出,当K为一个字母时,就是凯撒密码。而且容易看出,K越长,保密程
度就越高。显然这样的密码体制比单表置换密码体制具有更强的抗攻击能力,而且其加
密、解密均可用所谓的维吉尼亚方阵来进行,从而在操作上简单易行。该密码可用所谓
的维吉尼亚方阵来进行,从而在操作上简单易行。该密码曾被认为是三百年内破译不了
的密码,因而这种密码在今天仍被使用着。
古典密码的发展已有悠久的历史了。尽管这些密码大都比较简单,但它在今天仍有
其参考价值。
③ 怎么用python编辑棋盘密码
需要进行软件在软件里面调整一下具体的输入,然后完成棋盘表格代码的填写,就可以修改密码。
④ 一道棋盘算法问题!用(c++)
真巧,pku 1753就是这题。。
前几天ICPC训练的时候还写过,现在懒得再写了,要用到bfs,我帮你找到了这题的解题报告,你看看吧:
解题思路:
BFS 即宽搜
因为这题说要找出最小值,也就是求最优值问题,那么,很快就可以想到DP 或者
搜索,而这题很难想出阶段以及状态,所以,构造DP的解法是比较困难的,至于
到底可不可以用DP,我也没有继续深思过,所以,我就想到直接搜索,把所有走法
都模拟出来,然后,哪种走法最快能够实现全盘为白或黑,则答案就出来了!
搜索有BFS和DFS两种,而BFS有能够求出最优值的特点,故考虑用BFS!
方法:
如果把走第i步之前,盘子上所有棋子构成的状态记为S(i-1),并且,初始状态
记为S(0)。而且,可以发现每走一步时,在棋盘上都有4*4=16中选择!但,当
如果盘子上出现的状态在之前也出现过,那么,就可以不用再继续走了!(即剪枝)
我们从第一步开始。。。
把走完第一步后盘子的所有状态都保存起来,如果用
很多个二维数组来保存这些状态就浪费空间了,并且,在之后的要寻找当前状态是否
已经出现过,也会出现麻烦!想一想,因为棋子是黑白两面,可以等价为“0”和“1”
两种性质,那么如果用一个一维数组保存起来的话,例如:
bwwb
bbwb
bwwb
bwww 1001110110011000
那么很快又可以发现另一个特点,图只有2^16个状态。
然后,开一个数组sign[65535]标记已经访问过的状态,则问题就迎刃而解了!
我的程序:
Problem: 1753 User: jlthero
Memory: 504K Time: 32MS
Language: C++ Result: Accepted
Source Code
#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
using namespace std;
char piece[5][5];
int bina[16];
int sign[65536];
int ans;
int toint()
{
int value=0;
int i;
for(i=15;i>=0;i--)
{
value=value*2;
value+=bina[i];
}
return value;
}
void tochar(int n)
{
int i;
for(i=0;i<16;i++)
{
bina[i]=n%2;
n=n/2;
}
}
void slip(int i)
{
bina[i]=1-bina[i];
if(i%4!=0)
bina[i-1]=1-bina[i-1];
if(i%4!=3)
bina[i+1]=1-bina[i+1];
if(i-4>=0)
bina[i-4]=1-bina[i-4];
if(i+4<16)
bina[i+4]=1-bina[i+4];
}
int DFS()
{
vector<int>quene;
int i=0,j;
int value0,value1;
value0=toint();
if(value0==0||value0==65535)
return 0;
else if(sign[value0]==0)
{
quene.push_back(value0);
sign[value0]=1;
}
while(i<quene.size())
{
value0=quene[i];
tochar(value0);
for(j=0;j<16;j++)
{
slip(j);
value1=toint();
if(value1==0||value1==65535)
return sign[value0];
else if(sign[value1]==0)
{
quene.push_back(value1);
sign[value1]=sign[value0]+1;
}
slip(j);
}
i++;
}
return -1;
}
int main()
{
int i,j;
int t,ans;
while(scanf("%s %s %s %s",piece[0],piece[1],piece[2],piece[3])!=EOF)
{
for(i=0;i<4;i++)
{
t=i*4;
for(j=0;j<4;j++)
bina[t+j]=(piece[i][j]=='b'?1:0);
}
memset(sign,0,sizeof(sign));
ans=DFS();
if(ans==-1)
printf("Impossible\n");
else
printf("%d\n",ans);
}
return 0;
}
下面是王炽辉师兄的代码,代码长度要比我短很多^_^:
Problem: 1753 User: wangchi
Memory: 148K Time: 30MS
Language: C Result: Accepted
Source Code
#include<stdio.h>
#include<string.h>
#define MAX 1000000
int a[16], b[16], min;
char ch[4][5];
int legal()
{
int i, t, sum;
static int k = -1;
t = (a[0] + b[0] + b[1] + b[4]) % 2;
for(i = 1; i < 16; i++){
sum = a[i] + b[i];
if(i%4 != 0) sum += b[i-1];
if(i%4 != 3) sum += b[i+1];
if(i-4 >= 0) sum += b[i-4];
if(i+4 < 16) sum += b[i+4];
if(sum % 2 != t) return 0 ;
}
return 1;
}
void dfs(int i, int num)
{
if(i==16) {
if(min > num && legal()) min = num;
return;
}
b[i] = 0;
dfs(i+1, num);
b[i] = 1;
dfs(i+1, num+1);
}
int main()
{
int i, j, t;
while(scanf("%s%s%s%s", ch[0], ch[1], ch[2], ch[3]) != EOF){
for(i = 0; i < 4; i++){
t = i * 4;
for(j = 0; j < 4; j++)
a[t+j] = (ch[i][j]=='w')?0:1;
}
min = MAX;
dfs(0, 0);
if(min == MAX) printf("Impossible\n");
else printf("%d\n", min);
}
return 0;
}
⑤ 最火数字表白密码
在很多内敛的人当中,总是不好意思去表达自己的情意。其实,表达情意的方式有很多种,例如短信告白、情书告白,还有最近很火的表白密码。很多人都选择用表白密码去表达,这样可以增加神秘感和情趣。那么,有哪些表白密码呢?让我们一起来看看吧。
高级表白密码
1.字母表白数字密码:9121522521= I LOVE U
表白解密:从1开始到26,分别表示从A到Z,即:A(1)B(2) C(3) D(4) E(5) F(6) G(7) H(8) I(9) J(10) K(11) L(12) M(13) N(14) O(15) P(16) Q(17) R(18) S(19) T(20) U(21) V(22) W(23) X(24) Y(25) Z(26)。
9=I / 12=L / 15=O / 22=V / 5=E / 21=U
9121522521数字表白密码结果是 I LOVE U。所以,当你发送这样一串数字给你喜欢的人的时候,跟他(她)说这是一串特别特别有意义的数字,让他(她)解开。如果他(她)能解开,一定会感受到你的心意。解不开,也会增加他(她)对你的神秘感。挑起他(她)对你的兴趣。
2.大小写变化:ilOvEU
表白解密:这个很简单,换成我们常见的大小写即可。
3.空格重组:il ov eu
表白解密:这个表白密码也容易识别,两个空格移位即可。
4.单词倒序:i evol u
5.整句倒序:u evol i
6.凯撒移位:j mpwf v
7.反字母表(埃特巴什码/Atbash):r olev f
表白解密:把26个字母对折(词穷,暂且这样描述。)就会得到:
AB C D E F G H I J K L M
ZY X W V U T S R Q P O N所以,R对应的就是I,E对应的就是L,O对应的就是L,L对应的就是O,E对应的就是V,V对应的就是E,F对应的就是U
答案:I LOVE U 。或者我们可以用这个:R OLEV BLF,对应的也就是I LOVE YOU 了。
8.栅栏密码:ioelvu
表白解密:所谓栅栏密码,就是把要加密的明文分成N个一组,然后把每组的第1个字连起来,形成一段无规律的话。 不过栅栏密码本身有一个潜规则,就是组成栅栏的字母一般不会太多。(一般不超过30个,也就是一。两句话),我们的ioelvu 就是把love拆开,然后先逆向排列两个,再逆向插空排列。
9.维吉尼亚密码(密钥i love u):q wcqi o
10.维吉尼亚密码(密钥12345…):j nrzj a
11.仿射密码(Affine *3+5):d mvqr n
12.希尔密码(Hill 密钥矩阵{3,2;5,7}):ungjae
13.纳粹Enigma(密钥ABC):YAPOJ R
14.摩斯电码:·· ·-·· --- ···- · ··-
15.棋盘密码(波利比奥斯密码/Polybius):gd ag df ff xf gg
16.棋盘密码(数字):14 14 23 33 53 44
17.ADFGX密码(密钥love):gfg gdx dff afg
18.键盘密码1:71 31 43 91 92 81
19.键盘密码2:*1 (2 (1 $3 #1 &1
20.键盘移位:o ;pbr i
小结:表白密码很有意思,既可以表达自己的情意,又很有特殊意义,是近年来最火的表白方式。
⑥ 棋盘密码怎么区分ij
根据明文和密钥区分。
由于ij同时出现的概率较低,所以同格。ij可以根据明文和密钥来区分。
棋盘密码是利用波利比奥斯方阵进行加密的密码方式,产生于公元前两世纪的希腊,相传是世界上最早的一种密码。
⑦ C语言课程设计
以下程序已在win-tc和tc2.0下运行通过,已加详细注释(本人所写)。
/* 数据安全实用程序,加密解密简单程序 */
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
int flag;
char encrypt(char ch,int key)/*加密函数,把字符循环移位*/
{
if(ch>='a' && ch<='z') /* 如果是小写字母 */
{
ch=(ch-'a'+key%26)%26+'a'; /* 字母向后移key%26个位置,超过字母z则再从a开始向后移动 */
}
else if(ch>='A' && ch<='Z') /* 如果是大写字母 */
{
ch=(ch-'A'+key%26)%26+'A'; /* 字母向后移key%26个位置,超过字母Z则再从A开始向后移动 */
}
return ch;
}
char decrypt(char ch,int key)/*解密函数,把字符循环移位*/
{
if(ch>='a' && ch<='z') /* 如果是小写字母 */
{
ch=(ch-'a'+26-key%26)%26+'a'; /* 字母向后移26-key%26个位置,超过字母z则再从a开始向后移动 */
}
else if(ch>='A' && ch<='Z') /* 如果是大写字母 */
{
ch=(ch-'A'+26-key%26)%26+'A'; /* 字母向后移26-key%26个位置,超过字母Z则再从A开始向后移动 */
}
return ch;
}
void menu()/*菜单,1.加密,2.解密,3.显示文本文件内容*/
{
clrscr();
printf("\n=======================================================");
printf("\n1.Encrypt the text file"); /* 加密文件 */
printf("\n2.Decrypt the text file"); /* 解密文件 */
printf("\n3.Display text file contents");/* 显示加密或解密或未加密或解密的文件 */
printf("\n4.Quit\n");
printf("=========================================================\n");
printf("Please select a item:"); /* 选择一个菜单 */
}
void logo()/*显示程序信息*/
{
printf("\nwelcome to encrypt program \n ");
return;
}
void encrypt_decrypt_File(char* infile,int key, char* outfile) /* 加密或解密函数 */
{
FILE *in,*out;
char ch;
clrscr(); /* 清屏 */
if((in=fopen(infile,"r"))==NULL) /* 打开欲加密或解密的文件*/
{
printf("Can not open the infile!\n"); /* 如果打开文件失败或文件不存在打印打开失败信息 */
printf("Press any key to exit!\n");
getch(); /* 并等待任一按键然后退出程序 */
exit(0);
}
if((out=fopen(outfile,"w"))==NULL) /* 打开文件保存加密或解密后的内容*/
{
printf("Can not open the outfile!\n"); /* 如果打开文件失败或文件不存在打印打开失败信息 */
printf("Press any key to exit!\n"); /* 并等待任一按键然后退出程序 */
fclose(in); /* 关闭输入文件 */
getch(); /* 等待按键,按任一键退出程序 */
exit(0);
}
ch=fgetc(in); /*从文本文件中读入字符*/
while(ch!=EOF)/*加密或解密*/
{
/*如果是英文字符,则进行加密或解密,否则,不进行加密或解密处理*/
if((ch>='a' && ch<='z' ) || (ch>='A' && ch<='Z'))
{ if(flag==1)
fputc(encrypt(ch,key),out);
if(flag==2)
fputc(decrypt(ch,key),out);
}
else
fputc(ch,out);
ch=fgetc(in);
}
/*关闭输入及输出文件*/
fclose(in);
fclose(out);
}
void displayFile(char *infile) /*将文本文件的内容显示在屏幕上*/
{
FILE *fp;
char string[81];
if((fp=fopen(infile,"r"))==NULL) /* 以只读方式打开文本文件 */
{
printf("cann't open file");exit(0); /* 如果文件不存在或打开失败打印无法打开信息并退出程序 */
}
while(fgets(string,81,fp)!=NULL)
fputs(string,stdout); /*把所取字符串送到屏幕显示*/
fclose(fp); /* 关闭文件 */
}
int main()
{
int i,n;
char ch0,ch1;
char infile[40],outfile[40];
textbackground(LIGHTGRAY); /*设置背景颜色为浅灰色*/
textcolor(BLACK); /*设置文字颜色为黑色*/
clrscr();/*清除屏幕显示*/
logo(); /*显示程序信息*/
sleep(2); /* 延时2秒 */
menu(); /*显示屏幕菜单*/
ch0=getche();/*等待用户从键盘输入,并把输入显示在屏幕上*/
while(ch0!='4')
{
clrscr();
if(ch0=='1') /*选择加密功能*/
{
flag=1;
printf("\nPlease input the infile to be encrypted:"); /* 输入要加密的文件名 */
scanf("%s",infile); /* 该文件要和本程序放在同一个目录下 */
printf("Please input the encrypt key:");
scanf("%d",&n);/*输入加密密码*/
printf("Please input the outfile:"); /*输入存放加密内容的文件名*/
scanf("%s",outfile); /* 该文件可以自动创建 */
encrypt_decrypt_File(infile,n,outfile);
printf("\nEncrypt is over!\n");/* 加密成功 */
sleep(1); /* 延时1秒 */
}
else if(ch0=='2') /*选择解密功能*/
{
flag=2;
printf("\nPlease input the infile to be decrypted:"); /* 输入要解密的文件名 */
scanf("%s",infile); /* 该文件要和本程序放在同一个目录下 */
printf("Please input the decrypt key:");
scanf("%d",&n);/*输入解密密码,加密和解密密码应相同*/
printf("Please input the outfile:"); /*输入存放解密内容的文件名*/
scanf("%s",outfile); /* 该文件可以自动创建 */
encrypt_decrypt_File(infile,n,outfile);
printf("\nDecrypt is over!\n");
sleep(1); /* 延时1秒 */
}
else if(ch0=='3') /*选择显示文本文件功能*/
{
printf("\nPlease input the infile to be displayed:"); /* 输入要显示的文件名 */
scanf("%s",infile);
displayFile(infile);/* 显示文件 */
getch();
}
else
{ /*不合法输入*/
printf("\nplease input a valid number(1-4)\n");
sleep(1); /* 延时1秒 */
}
menu();/*显示程序菜单*/
ch0=getche(); /*等待用户下一次的功能选择*/
}
system("cls");/*清除屏幕*/
logo(); /*显示程序信息*/
printf("\nGood Bye!\n");
sleep(2);/* 延时2秒 */
system("pause"); /* 暂停,按任一键退出程序 */
return 0;
}
⑧ 加密解密工具 之 波利比奥斯方阵密码
波利比奥斯方阵密码(Polybius Square Cipher或称波利比奥斯棋盘)是棋盘密码的一种,是利用波利比奥斯方阵进行加密的密码方式,简单的来说就是把字母排列好,用坐标(行列)的形式表现出来。字母是密文,明文便是字母的坐标。
工具链接: http://www.atoolbox.net/Tool.php?Id=913
⑨ 棋盘密码
波利比奥斯方阵
公元前2世纪,一个叫Polybius的希腊人设计了一种将字母编码成符号对的方法。他使用了一个称为Polybius的校验表。Polybius校验表由一个5行5列的网格组成,网格中包含26个英文字母,其中I和J在同一格中。相应字母用数对表示。在古代,这种棋盘密码被广泛使用。Polybius校验表如下:
假设我们需要发送明文信息“Hello”,找到H对应2行3列,则加密为23,e加密为15,以此类推,得到密文:2315 31 31 34。
ADFGX密码
1918年,第一次世界大战将要结束时,法军截获了一份德军电报,电文中的所有单词都由A、D、F、G、X五个字母拼成,因此被称为ADFGX密码。ADFGX密码是1918年3月由德军上校FritzNebel发明的,是结合了波利比奥斯方阵和置换密码的双重加密方案。ADFGX密码之所以选择ADFGX一个字母,是因为它们译成摩斯密码时不容易混淆,可以降低传输错误的机率。ADFGX密码表如下:
这样加密的话Hello的密文就是:DD XF AG AGDF。
ADFGVX密码
ADFGX密码发送含有大量数字的信息会有问题。 在1918年6月,又加入一个字母V扩充,变成以6×6格共36个字符加密,这使得所有英文字母(不再将I和J视为同一个字)以及数字0到9都可混合使用。ADFGVX是被法国陆军中尉Georges Painvin所破解的。
⑩ 高级表白密码
表白也是考智商的活啊!下面这些高级表白密码赶紧学起来,要不真的都看不懂暗恋你的人到底是不是对你表白了。
一、高级表白密码