java实现Playfair密码
⼀种 Playfair 密码变种加密⽅法如下:⾸先选择⼀个密钥单词(称为 pair)(字母不重复,且都为⼩写字母),
然后与字母表中其他字母⼀起填⼊⾄⼀个 5x5 的⽅阵中,填⼊⽅法如下:
1.⾸先按⾏填⼊密钥串。
2.紧接其后,按字母序按⾏填⼊不在密钥串中的字母。
3.由于⽅阵中只有 25 个位置,最后剩下的那个字母则不需变换。
如果密钥为 youandme,则该⽅阵如下:
y o u a n
d m
e b c
f g h i j
k l p q r
s t v w x
在加密⼀对字母时,如 am,在⽅阵中到以这两个字母为顶点的矩形(红⾊字体):
y o u a n
d m
e b c
f g h i j
k l p q r
s t v w x
这对字母的加密字母为该矩形的另⼀对顶点,如本例中为 ob。
请设计程序,使⽤上述⽅法对输⼊串进⾏加密,并输出加密后的串。
另外有如下规定:
1、⼀对⼀对取字母,如果最后只剩下⼀个字母,则不变换,直接放⼊加密串中;
2、如果⼀对字母中的两个字母相同,则不变换,直接放⼊加密串中;
3、如果⼀对字母中有⼀个字母不在正⽅形中"如 z",则不变换,直接放⼊加密串中;
4、如果字母对出现在⽅阵中的同⼀⾏或同⼀列,如 df 或 hi,则只需简单对调这两个字母,即变换为 fd 或 ih;
5、如果在正⽅形中能够到以字母对为顶点的矩形,假如字母对为 am,则该矩形的另⼀对顶点字母中,
与 a 同⾏的字母应在前⾯,在上例中应是 ob;同样若待变换的字母对为 ta,则变换后的字母对应为 wo;
6、本程序中输⼊串均为⼩写字母,并不含标点、空格或其它字符。
解密⽅法与加密相同,即对加密后的字符串再加密,将得到原始串。
要求输⼊形式如下:
从控制台输⼊两⾏字符串,第⼀⾏为密钥单词(长度⼩于等于 25),第⼆⾏为待加密字符串(长度⼩于等于 50),两⾏字符串末尾都有⼀个回车换⾏符,并且两⾏字符串均为⼩写字母,不含其它字符。
在标准输出上输出加密后的字符串。
例如,若输⼊:
youandme
welcometohangzhou
则表⽰输⼊的密钥单词为 youandme,形成的正⽅形如上所⽰;待加密字符串为 welcometohangzhou。
51
在正⽅形中可以到以第⼀对字母 we 为顶点的矩形,对应另⼀对顶点字母为 vb,因此加密后为 vb,
同理可到与字母对 lc,et,oh,ho 对应的顶点字母对。⽽字母对 om 位于上述正⽅形中的同⼀列,
所以直接以颠倒这两个字母来加密,即为 mo,字母对 an 同理。字母对 gz 中的 z 不在上述正⽅形中,
因此原样放到加密串中。最后剩⼀个字母 u 也原样输出。
因此输出的结果为:
vbrmmomvugnagzguu
vbrmmomvugnagzguu
vbrmmomvugnagzguu
要求考⽣把所有类写在⼀个⽂件中。调试好后,存⼊与考⽣⽂件夹下对应题号的“解答.txt”中即可。
相关的⼯程⽂件不要拷⼊。请不要使⽤ package 语句。
另外,源程序中只能出现 JDK1.5 中允许的语法或调⽤。不能使⽤ 1.6 或更⾼版本。
package Question20_29;
import java.util.Scanner;
import java.util.Vector;
public class Question26 {
public static char initArray(char[][] array, String pair) {
Vector<Character>vector=new Vector<Character>();
for (char i = 'a'; i <='z'; i++) {
vector.add(i);
}
for (int i = 0; i < pair.length(); i++) {
array[i/5][i%5]=pair.charAt(i);
}
for (int i = 0,j=pair.length() ; i < vector.size()-1; i++,j++) {
array[j/5][j%5]=vector.elementAt(i);
}
return vector.elementAt(vector.size()-1);
}
public static String passwordAfterChange(char[][] array,String password,char unUsedch) { StringBuffer sb=new StringBuffer();
for (int i = 0; i < password.length(); i+=2) {
if(i+1<password.length()){
if(password.charAt(i)==unUsedch||password.charAt(i+1)==unUsedch){//如果⼀对字母中有⼀个字母不在正⽅形中"如 z",则不变换,直接放⼊加密串中
sb.append(password.charAt(i));
sb.append(password.charAt(i+1));
}else if (password.charAt(i)==password.charAt(i+1)) {//如果⼀对字母中的两个字母相同,则不变换,直接放⼊加密串中
java源代码加密sb.append(password.charAt(i));
sb.append(password.charAt(i+1));
}else {
int ch1i=0,ch1j=0,ch2i=0,ch2j = 0;
52
for (int j = 0; j < array.length; j++) {
for (int j2 = 0; j2 < array.length; j2++) {
if(array[j][j2]==password.charAt(i)){
ch1i=j;ch1j=j2;
}else if(array[j][j2]==password.charAt(i+1)){
ch2i=j;ch2j=j2;
}
}
}
if(ch1i==ch2i||ch1j==ch2j){//如果字母对出现在⽅阵中的同⼀⾏或同⼀列,如 df 或 hi,则只需
简单对调这两个字母,即变换为 fd 或 ih
sb.append(password.charAt(i+1));
sb.append(password.charAt(i));
}else {
sb.append(array[ch1i][ch2j]);
sb.append(array[ch2i][ch1j]);
}
}
}else {//⼀对⼀对取字母,如果最后只剩下⼀个字母,则不变换,直接放⼊加密串中
sb.append(password.charAt(i));
}
}
String();
}
public static void main(String[] args) {
char array[][]=new char[5][5];
Scanner scanner = new Scanner(System.in);
String pair = Line();
String Line();
char unUsedch=initArray(array, pair);
System.out.println(passwordAfterChange(array, password, unUsedch));
}
}
运⾏结果:
输⼊密钥单词:youandme
输⼊待加密字符:welcometohangzhou
y o u a n
d m
e b c
f g h i j
k l p q r
s t v w x
加密结果:vbrmommvugnagzguu
解密结果:welcometohangzhou
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论