900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Java加密算法—凯撒加密实现以及暴力破解

Java加密算法—凯撒加密实现以及暴力破解

时间:2018-08-26 05:15:54

相关推荐

Java加密算法—凯撒加密实现以及暴力破解

目录

1、概念2、加密实现3、解密实现4、频率分析法破解

1、概念

凯撒密码最早由古罗马军事统帅盖乌斯·尤利乌斯·凯撒在军队中用来传递加密信息,故称凯撒密码。这是一种位移加密方式,只对26个字母进行位移替换加密,规则简单,容易破解,恺撒密码通常被作为其他更复杂的加密方法中的一个步骤。

将明文字母表向后移动1位,A变成了B,B变成了C……,Z变成了A。因为字母移动26位会回到原值,移动27位的结果和移动1位是一样,所以字母表最多可以移动25位。

2、加密实现

public class KaiserTest {public static void main(String[] args) {String text = "KaiserTest";System.out.println("凯撒加密前原文:" + text);// 测试移动3位,进行加密String encryptKaiser = encryptKaiser(text, 3);System.out.println("凯撒加密后密文:" + encryptKaiser);}/*** 使用凯撒加密方式加密数据** @param original :原文* @param key:位移数量* @return :加密后的数据*/public static String encryptKaiser(String original, int key) {// 将字符串转为字符数组char[] chars = original.toCharArray();StringBuilder sb = new StringBuilder();for (char aChar : chars) {// 获取字符的ascii编码int asciiCode = aChar;// 偏移数据asciiCode += key;// 将偏移后的数据转为字符char result = (char) asciiCode;// 拼接数据sb.append(result);}return sb.toString();}}

效果:

3、解密实现

public class KaiserTest {public static void main(String[] args) {String text = "KaiserTest";System.out.println("凯撒加密前原文:" + text);// 测试移动3位,进行加密String encryptKaiser = encryptKaiser(text, 3);System.out.println("凯撒加密后密文:" + encryptKaiser);// 解密操作String decryptKaiser = decryptKaiser(encryptKaiser, 3);System.out.println("凯撒解密后明文:" + decryptKaiser);}/*** 使用凯撒加密方式解密数据** @param encryptedData :密文* @param key :位移数量* @return : 源数据*/public static String decryptKaiser(String encryptedData, int key) {// 将字符串转为字符数组char[] chars = encryptedData.toCharArray();StringBuilder sb = new StringBuilder();for (char aChar : chars) {// 获取字符的ASCII编码int asciiCode = aChar;// 偏移数据asciiCode -= key;// 将偏移后的数据转为字符char result = (char) asciiCode;// 拼接数据sb.append(result);}return sb.toString();}/*** 使用凯撒加密方式加密数据** @param original :原文* @param key:位移数量* @return :加密后的数据*/public static String encryptKaiser(String original, int key) {// 将字符串转为字符数组char[] chars = original.toCharArray();StringBuilder sb = new StringBuilder();for (char aChar : chars) {// 获取字符的ascii编码int asciiCode = aChar;// 偏移数据asciiCode += key;// 将偏移后的数据转为字符char result = (char) asciiCode;// 拼接数据sb.append(result);}return sb.toString();}}

效果:

4、频率分析法破解

使用凯撒加密对字母表进行加密时,采用的是位移方法,如果分析出了合理的位移值,那么就可以对密文进行破解,英文字母出现频率最高的分别是e、t、a……,然后检查要破解的密文,也将每个字母出现的频率整理出来,假设密文中出现频率最高的字母是c,那么明文可能是e,如果密码文中出现频率次高的但是e,那么明文可能是t,以此类推便就能解开加密信息的内容,这就是频率分析法。

字母出现批量对照表-来自百度百科:

代码演示:

public class KaiserAnalysisTest {public static void main(String[] args) {// 字母频率排名char[] orderChar = {'e', 't', 'a', 'o', 'n', 'r', 'i', 's', 'h','d', 'l', 'f', 'c', 'm', 'u', 'g', 'y', 'p', 'w', 'b','v', 'k', 'j', 'x', 'q', 'z'};// 明文,用于最后进行对比String text = "Encrypt the alphabet using Caesar encryption";// 加密后密文,用于破解String secret = "Hqfu|sw#wkh#doskdehw#xvlqj#Fdhvdu#hqfu|swlrq";// 打印各字符出现数量List<Map.Entry<Character, Integer>> mapList = countChars(secret);// 匹配概率值out:for (char ch : orderChar) {for (Map.Entry<Character, Integer> entry : mapList) {System.out.println("猜测最大概率字符为:" + ch);Character key = entry.getKey();int keyNum = key - ch;System.out.println("猜测key为:" + key + ",与" + ch + "的ASCII相差:" + keyNum);// 根据偏移值解密String decryptData = decryptKaiser(secret, keyNum);System.out.println("解密后明文预计为:" + decryptData);boolean result = decryptData.equals(text);System.out.println("是否复合条件:" + result);if (result) {break out;}}}}/*** 解密** @param secret* @param key* @return*/public static String decryptKaiser(String secret, int key) {// 1、将密文转换成字符数组char[] chars = secret.toCharArray();StringBuilder sb = new StringBuilder();for (char aChar : chars) {// 2、获取字符的ascii编码int asciiCode = aChar;// 3、偏移数据asciiCode += key;// 4、将偏移后的数据转为字符char result = (char) asciiCode;// 5、拼接数据sb.append(result);}return sb.toString();}/*** 统计String里出现最多的字符** @param data*/public static List<Map.Entry<Character, Integer>> countChars(String data) {//创建TreeMap集合,键是Character,值是IntegerMap<Character, Integer> map = new HashMap<>(16);//遍历字符串,得到每一个字符for (int i = 0; i < data.length(); i++) {char key = data.charAt(i);//拿到每一个字符作为键到TreeMap集合中去找对应的值,看其返回值Integer value = map.get(key);//如果返回值是null,说明该字符在TreeMap集合中不存在,就把该字符串作为键,1作为值存储if (value == null) {map.put(key, 1);} else {//如果返回值不是null,说明该字符在TreeMap集合中存在,把该值加一,然后重新存储该字符和对应的值value++;map.put(key, value);}}// 对结果进行排序List<Map.Entry<Character, Integer>> mapList = new ArrayList<>(map.entrySet());//根据字符出现次数排序mapList.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));StringBuilder sb = new StringBuilder();//遍历Map集合,得到键和值,按照要求进行拼接mapList.forEach(entry -> {Integer value = entry.getValue();Character key = entry.getKey();sb.append(key).append("出现").append(value).append("次; ");});//调用toString方法,从StringBuilder转为String类型输出String result = sb.toString();System.out.println(result);return mapList;}}

效果:

注意:key指的是当前验证的密文的字符

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。