凯撒加密

凯撒加密

1.中国古代加密
在这里插入图片描述
2.外国加密
在这里插入图片描述
在这里插入图片描述
3.凯撒位移加密
创建类 KaiserDemo,把 hello world 往右边移动3位

package com.atguigu.kaiser;

/**
 * KaiserDemo
 *
 * @Author: 尚硅谷
 * @CreateTime: 2020-03-17
 * @Description:
 */
public class KaiserDemo {
    public static void main(String[] args) {
        String input = "Hello world";
        // 往右边移动3位
        int key = 3;
        // 用来拼接
        StringBuilder sb = new StringBuilder();
        // 字符串转换成字节数组
        char[] chars = input.toCharArray();
        for (char c : chars) {
            int asciiCode = c;
            // 移动3位
            asciiCode = asciiCode + key;
            char newChar = (char) asciiCode;
            sb.append(newChar);
        }

        System.out.println(sb.toString());
    }
}

运行
在这里插入图片描述
4.凯撒加密和解密

package com.atguigu.kaiser;

/**
 * KaiserDemo
 *
 * @Author: 尚硅谷
 * @CreateTime: 2020-03-16
 * @Description:
 */
public class KaiserDemo {
    public static void main(String[] args) {
        String orignal = "Hello world";
        // 往右边偏移三位
        int key = 3;
        // 选中我即将抽取的代码,按快捷键Ctrl + Alt + M 
        String encryptKaiser =  encryptKaiser(orignal,key);
        System.out.println("加密:" + encryptKaiser);
        String decryptKaiser =  decryptKaiser(encryptKaiser,key);
        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 orignal :原文
     * @param key     :密钥
     * @return :加密后的数据
     */
    public static String encryptKaiser(String orignal, int key) {
        // 将字符串转为字符数组
        char[] chars = orignal.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();
    }
}

5.频度分析法破解恺撒加密
密码棒
在这里插入图片描述
频率分析解密法
在这里插入图片描述
运行 FrequencyAnalysis.java 里面 main 函数里面的 encryptFile 方法 对程序进行加密

public static void main(String[] args) throws Exception {
		//测试1,统计字符个数
		//printCharCount("article.txt");
		
		//加密文件
		int key = 3;
		encryptFile("article.txt", "article_en.txt", key);
		
		//读取加密后的文件
	   // String artile = Util.file2String("article_en.txt");
	    //解密(会生成多个备选文件)
	   // decryptCaesarCode(artile, "article_de.txt");
	}

在根目录会生成一个 article_en.txt 文件,然后我们统计这个文件当中每个字符出现的次数

public static void main(String[] args) throws Exception {
		//测试1,统计字符个数
		printCharCount("article_en.txt");
		
		//加密文件
		int key = 3;
		//encryptFile("article.txt", "article_en.txt", key);
		
		//读取加密后的文件
	   // String artile = Util.file2String("article_en.txt");
	    //解密(会生成多个备选文件)
	   // decryptCaesarCode(artile, "article_de.txt");
	}

运行程序
在这里插入图片描述
我们来看看频度分析法如何工作的

public static void main(String[] args) throws Exception {
		//测试1,统计字符个数
		//printCharCount("article_en.txt");
		
		//加密文件
		int key = 3;
		//encryptFile("article.txt", "article_en.txt", key);
		
		//读取加密后的文件
	   String artile = Util.file2String("article_en.txt");
	    //解密(会生成多个备选文件)
	   decryptCaesarCode(artile, "article_de.txt");
	}

运行程序
在这里插入图片描述
在这里插入图片描述

package com.atguigu.kaiser;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;

public class Util {
	
	public static void print(byte[] bytes) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			sb.append(bytes[i]).append(" ");
		}
		System.out.println(sb);
	}
	
	public static String file2String(String path) throws IOException {
		FileReader reader = new FileReader(new File(path));
		char[] buffer = new char[1024];
		int len = -1;
		StringBuffer sb = new StringBuffer();
		while ((len = reader.read(buffer)) != -1) {
			sb.append(buffer, 0, len);
		}
		return sb.toString();
	}
	
	public static void string2File(String data, String path){
		FileWriter writer = null;
		try {
			writer = new FileWriter(new File(path));
			writer.write(data);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
	
	public static String inputStream2String(InputStream in) throws IOException {
		int len = -1;
		byte[] buffer = new byte[1024];
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		while((len = in.read(buffer)) != -1) {
			baos.write(buffer, 0, len);
		}
		baos.close();
		
		return baos.toString("UTF-8");
	}
	
	
}

package com.atguigu.kaiser;

/**
 * KaiserDemo
 *
 * @Author: 马伟奇
 * @CreateTime: 2020-05-05
 * @Description:
 *       凯撒加密
 */
public class KaiserDemo {
    public static void main(String[] args) {
        // 定义原文
        String input = "Hello World";
        // 把原文右边移动3位
        int key = 3;
        // 凯撒加密
        String s = encrypt(input,key);
        System.out.println("加密==" + s);
        String s1 = decrypt(s,key);
        System.out.println("明文=="+s1);
    }

    /**
     * 解密
     * @param s 密文
     * @param key 密钥
     * @return
     */
    public static String decrypt(String s, int key) {
        char[] chars = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (char aChar : chars) {
            int b = aChar;
            // 偏移数据
            b -= key;
            char newb = (char) b;
            sb.append(newb);
        }
        return sb.toString();
    }

    /**
     * 加密
     * @param input 原文
     * @return
     */
    public static String encrypt(String input,int key) {
        // 抽取快捷键 ctrl + alt + m
        // 把字符串变成字节数组
        char[] chars = input.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (char aChar : chars) {
            int b = aChar;
            // 往右边移动3位
            b = b + key;
            char newb = (char) b;
            sb.append(newb);
        }
//        System.out.println("密文==="+sb.toString());
        return sb.toString();
    }
}
package com.atguigu.kaiser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 频率分析法破解凯撒密码
 */
public class FrequencyAnalysis {
	//英文里出现次数最多的字符
	private static final char MAGIC_CHAR = 'e';
	//破解生成的最大文件数
	private static final int DE_MAX_FILE = 4;
	
	public static void main(String[] args) throws Exception {
		//测试1,统计字符个数
		printCharCount("article_en.txt");
		
		//加密文件
//		int key = 3;
//		encryptFile("article.txt", "article_en.txt", key);
		
		//读取加密后的文件
	    String artile = Util.file2String("article_en.txt");
	    //解密(会生成多个备选文件)
	    decryptCaesarCode(artile, "article_de.txt");
	}
	
	public static void printCharCount(String path) throws IOException{
		String data = Util.file2String(path);
		List<Entry<Character, Integer>> mapList = getMaxCountChar(data);
		for (Entry<Character, Integer> entry : mapList) {
			//输出前几位的统计信息
			System.out.println("字符'" + entry.getKey() + "'出现" + entry.getValue() + "次");
		}
	}
	
	public static void encryptFile(String srcFile, String destFile, int key) throws IOException {
		String artile = Util.file2String(srcFile);
		//加密文件
		String encryptData = KaiserDemo.encrypt(artile, key);
		//保存加密后的文件
		Util.string2File(encryptData, destFile);
	}
	
	/**
	 * 破解凯撒密码
	 * @param input 数据源
	 * @return 返回解密后的数据
	 */
	public static void decryptCaesarCode(String input, String destPath) {
		int deCount = 0;//当前解密生成的备选文件数
		//获取出现频率最高的字符信息(出现次数越多越靠前)
		List<Entry<Character, Integer>> mapList = getMaxCountChar(input);
		for (Entry<Character, Integer> entry : mapList) {
			//限制解密文件备选数
			if (deCount >= DE_MAX_FILE) {
				break;
			}
			
			//输出前几位的统计信息
			System.out.println("字符'" + entry.getKey() + "'出现" + entry.getValue() + "次");
			
			++deCount;
			//出现次数最高的字符跟MAGIC_CHAR的偏移量即为秘钥
			int key = entry.getKey() - MAGIC_CHAR;
			System.out.println("猜测key = " + key + ", 解密生成第" + deCount + "个备选文件" + "\n");
			String decrypt = KaiserDemo.decrypt(input, key);
			
			String fileName = "de_" + deCount + destPath;
			Util.string2File(decrypt, fileName);
		}
	}
	
	//统计String里出现最多的字符
	public static List<Entry<Character, Integer>> getMaxCountChar(String data) {
		Map<Character, Integer> map = new HashMap<Character, Integer>();
		char[] array = data.toCharArray();
		for (char c : array) {
			if(!map.containsKey(c)) {
				map.put(c, 1);
			}else{
				Integer count = map.get(c);
				map.put(c, count + 1);
			}
		}
		
		//输出统计信息
		/*for (Entry<Character, Integer> entry : map.entrySet()) {
			System.out.println(entry.getKey() + "出现" + entry.getValue() +  "次");
		}*/
		
		//获取获取最大值
		int maxCount = 0;
		for (Entry<Character, Integer> entry : map.entrySet()) {
			//不统计空格
			if (/*entry.getKey() != ' ' && */entry.getValue() > maxCount) { 
				maxCount = entry.getValue();
			}
		}
		
		//map转换成list便于排序
		List<Entry<Character, Integer>> mapList = new ArrayList<Entry<Character,Integer>>(map.entrySet());
		//根据字符出现次数排序
		Collections.sort(mapList, new Comparator<Entry<Character, Integer>>(){

			public int compare(Entry<Character, Integer> o1,
					Entry<Character, Integer> o2) {
				return o2.getValue().compareTo(o1.getValue());
			}
		});
		return mapList;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值