加密与解密_Playfair密码变种加密方法-解题思路及过程
来源:互联网 发布:java split函数 编辑:程序博客网 时间:2024/06/01 23:12
一.题目描述:
一种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、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中;
4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,即变换为fd或ih;
5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。
解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。
要求输入形式如下:
从控制台输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写字母,不含其它字符。
在标准输出上输出加密后的字符串。
例如,若输入:
youandme
welcometohangzhou
则表示输入的密钥单词为youandme,形成的正方形如上所示;待加密字符串为welcometohangzhou。在正方形中可以找到以第一对字母we为顶点的矩形,对应另一对顶点字母为vb,因此加密后为vb,同理可找到与字母对lc,et,oh,ho对应的顶点字母对。而字母对om位于上述正方形中的同一列,所以直接以颠倒这两个字母来加密,即为mo,字母对an同理。字母对gz中的z不在上述正方形中,因此原样放到加密串中。最后剩一个字母u也原样输出。
因此输出的结果为:
vbrmmomvugnagzguu
二.解题思路:
这条题目我们完全可以根据上述的规定编写出我们所预想的程序。我的想法是:可以先设计一个线性列表,将26个字母一起放入其中,然后定义一个5x5的矩阵,将密钥按顺序放入其中(同时将放入矩阵中的字母从线性表中去除),等到将密钥全部放入矩阵中之后,再按照顺序将线性表中的其他字母一一放入矩阵中,这样就形成了一个密钥矩阵。
然后按照上述规定对其进行一一限制,这里说下加入字母对是为定点的矩形,那么很简单,只要将两个字母的所在的列的值交换下即可。
三.Java代码如下:
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class Test {static String pair = "youandme";//密钥static List<Character> list = new ArrayList<Character>();//线性表static char[][] getMatrix(String pair) {//获取密钥矩阵int length = 0;char[][] matrix = new char[5][5];for (char i = 'a'; i <= 'z'; i++) {list.add(i);//将26个字母放入线性表}for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (length < pair.length()) {char t = pair.charAt(length++);matrix[i][j] = t;//将密钥字母一个个放入矩阵中list.remove((Character) t);//将放入矩阵中的字母从线性表中移除} else {matrix[i][j] = list.remove(0);//将线性表中的字母填充进矩阵中,然后移除该字母}}}return matrix;}static String encoding(String s) {String result = "";char[][] matrix = getMatrix(pair);Map<String, Integer> map = new HashMap<String, Integer>();//获取字母对的x,y轴的坐标for (int k = 0; k < s.length(); k++) {char t1 = s.charAt(k++);char t2;if (s.length() % 2 != 0 && k == s.length()) {//最后如果只有一个人字母则直接加入结果result += t1;break;} elset2 = s.charAt(k);if (list.contains(t1) || list.contains(t2)) {//如果字母对中任一字母在线性表中,//即代表不再矩阵中,则将字母对直接加入结果result += t1 + "" + t2;continue;}if (t1 == t2) {result += t1 + "" + t2;//如果字母对相同,则直接加入结果} else {for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {if (matrix[i][j] == t1) {map.put("t1_x", i);map.put("t1_y", j);}if (matrix[i][j] == t2) {map.put("t2_x", i);map.put("t2_y", j);}}}if ((Integer) map.get("t1_x") == (Integer) map.get("t2_x")//如果字母对在同一个行或列则交换字母后加入结果|| (Integer) map.get("t1_y") == (Integer) map.get("t2_y")) {result += t2 + "" + t1;} else {//如果字母对成一个矩形,调换两个字母的y轴坐标后获取在矩阵中的值加入结果result += matrix[(Integer) map.get("t1_x")][(Integer) map.get("t2_y")]+ ""+ matrix[(Integer) map.get("t2_x")][(Integer) map.get("t1_y")];}}}return result;}public static void main(String[] args) {String s = "welcometohangzhou";String result = encoding(s);System.out.println(result);}}
结果如下:
题目完成,以上为个人思路,仅供参考,有什么不到位的地方欢迎批评指正,谢谢......
- 加密与解密_Playfair密码变种加密方法-解题思路及过程
- 密码加密与解密
- Playfair密码变种加密
- Playfair密码变种加密
- 密码的加密与解密
- java密码加密与解密
- Java密码加密与解密
- Playfair密码 变种加密字符串
- bat加密及解密方法
- 凯撒密码(加密与解密)
- java密码的加密与解密
- mysql密码的加密与解密
- 凯撒密码--简单的加密与解密
- 配置文件项密码加密与解密
- 字符串 密码加密解密
- 密码 加密&解密
- 密码 加密跟解密
- 密码加密解密
- Spring-配置文件Bean定义中parent属性详解
- OCP 1Z0 051 158
- 二分查找法
- 冒泡排序(转载等 要注明出处,谢谢!)
- java在指定路径下查找所有文件及其子文件名中,是否包含指定查询的关键字
- 加密与解密_Playfair密码变种加密方法-解题思路及过程
- 邮件正文及其附件的发送的C++实现
- hid keyboard device异常,电脑键盘驱动出现问题,无法输入,利用虚拟键盘解决问题
- DateTime之时间比较(Compare 方法)
- HDU 4839 The Game of Coins _(:зゝ∠)_
- Scheme 的 xml文件读写
- "",IDC_FRAME,"Static",SS_BLACKFRAME,226,8,20,20 CONTROL IDB_BACK,IDC_BACK,"Static",SS_
- HDOJ 1874 畅通工程续——结构体模拟邻接链表的SPFA算法
- poj 1947 Rebuilding Roads(树形dp)