Playfair密码加密算法 Java实现

信息安全概论

只实现加密算法的Playfair密码算法

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Scanner;

/**
  * 仅含加密算法的Playfair密码算法
  * 按照提示输入关键字和明文,输出相应的密文
  * @author Riyad
  */
public class Playfair
{
	private char[][] matrix = new char[5][5];
	private static String keyword;
	private Scanner scan;
	
	{
		System.out.print("Please enter the keyword of Playfair: ");
		
		//将输入的关键字转化为字符数组,并对输入的关键字进行判空和范围判断
		scan = new Scanner(System.in);
		keyword = scan.nextLine();
		if(keyword.isBlank())
		{
			System.out.println("Please enter the keyword!");
			System.exit(0);
		}
		char[] kc = keyword.toUpperCase().toCharArray();
		for(int i = 0; i < kc.length; i++)
		{
			if(kc[i] > 90 || kc[i] < 65)
			{
				System.out.println("Please enter the correct words!");
				System.exit(0);
			}
		}
		
		//获取字母表(大写字母),忽略字母J,后面在搜索矩阵时与I合并
		char[] alphabet = new char[26];
		for(char c = 'A', i = 0; i < 25; c++, i++) 
		{
			alphabet[i] = c;
			if(alphabet[i] == 'I') c++;
		}
		
		//利用Set的特性获得字符均不相同的字符数组
		LinkedHashSet<Character> set = new LinkedHashSet<Character>();
		for(int i = 0; i < kc.length; i++) set.add(kc[i]);
		for(int i = 0; i < 25; i++)
		{
			set.add(alphabet[i]);
			if(set.size() == 25) break;
		}
		
		//将字符数组中的元素按先行后列的顺序加入矩阵
		Character[] array = set.toArray(new Character[set.size()]);
		int k = 0;
		for(int i = 0; i < matrix.length; i++)
		{
			for(int j = 0; j < matrix[i].length; j++)
			{
				matrix[i][j] = array[k];
				k++;
			}
		}
	}
	
	/**
	  * 在矩阵中寻找目标字母的位置,返回行和列的数组
	  * @param c 所要寻找的字母
	  * @return 长度为2的数组表示的行和列
	  */
	private int[] search(char c)
	{
		int[] in = {5, 5};
		for(int i = 0; i < matrix.length; i++)
		{
			for(int j = 0; j < matrix[i].length; j++)
			{
				if(matrix[i][j] == c)
				{
					in[0] = i;
					in[1] = j;
				}
			}
		}
		
		//若无变化,说明查无此字母,则该字母为J,矩阵中I和J合并,改为搜索I的位置
		if(in[0] == 5 && in[1] == 5) 
		{
			c -= 1;
			return search(c);
		}
		
		return in;
	}
	
	/**
	 * 加密算法
	 */
	public void encrypt()
	{
		//获取明文,将明文中的空格删去,并全部转换为大写字母字符数组
		System.out.print("Please enter the plaintext: ");
		Scanner scan = new Scanner(System.in);
		String plaintext = scan.nextLine();		
		char[] plaintextCharArray = plaintext.replaceAll(" ", "").toUpperCase().toCharArray();
		scan.close();
		
		//将字符数组中所有内容添加进ArrayList中
		ArrayList<Character> list = new ArrayList<Character>();
		for(int i = 0; i < plaintextCharArray.length; i++) list.add(plaintextCharArray[i]);
		
		//若明文分组出现重复字母在一组,则在重复的明文字母中插入一个填充字母k进行分隔后重新分组
		for(int i = 0; i < plaintextCharArray.length; i = i + 2) 
		{
			if(i + 1 == plaintextCharArray.length) break; //防止超出数组范围
			if(list.get(i) == list.get(i + 1)) list.add(i + 1, 'K');
		}
		
		//若分组到最后一组时只有一个字母,则补充字母k
		if(list.size() % 2 != 0) list.add('K');
		
		//输出密文
		System.out.print("The cipher text is: ");
		for(int i = 0; i < list.size(); i = i + 2)
		{
			char a = list.get(i);
			char b = list.get(i + 1);
			
			//获取两个字母在矩阵中的坐标
			int[] posA = search(a);
			int[] posB = search(b);
			
			int lineA = posA[0];
			int lineB = posB[0];
			int rowA = posA[1];
			int rowB = posB[1];
			
			//若明文字母在矩阵中同行,则循环取其右边字母为密文
			if(lineA == lineB) System.out.print(matrix[lineA][(rowA + 1) % 5] + "" + matrix[lineB][(rowB + 1) % 5] + " ");
			
			//若明文字母在矩阵中同列,则循环取其下边字母为密文
			else if(rowA == rowB) System.out.print(matrix[(lineA + 1) % 5][rowA] + "" + matrix[(lineB + 1) % 5][rowB] + " ");
			
			//若明文字母在矩阵中不同行不同列,则取其同行且与下一字母同列的字母为密文
			else System.out.print(matrix[lineA][rowB] + "" + matrix[lineB][rowA] + " ");
		}
	}
	
	public static void main(String[] args)
	{
		//monarchy
		//we are discovered save yourself
		Playfair pf = new Playfair();
		pf.encrypt();
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
playfair密码加密是一种替换密码和重排密码的结合,需要先构建密钥矩阵,然后对明文进行分组,并进行加密转换处理。以下是一个Python实现的代码示例: ```python def create_matrix(key): # 去重并保留字母顺序 key = "".join(sorted(set(key), key=key.index)) # 将密钥矩阵中的J替换为I key = key.replace("J", "I") # 如果密钥不足25位,用剩余字符补齐 alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ" for letter in alphabet: if letter not in key: key += letter # 构建5*5的密钥矩阵 matrix = [list(key[i:i+5]) for i in range(0, len(key), 5)] return matrix def encode(plain, matrix): # 去掉空格和非字母字符 plain = "".join(filter(str.isalpha, plain.upper())) # 将重复的字母用X分隔 i = 0 while i < len(plain)-1: if plain[i] == plain[i+1]: plain = plain[:i+1] + "X" + plain[i+1:] i += 2 # 如果明文长度为奇数,在末尾加一个字符 if len(plain) % 2 != 0: plain += "X" # 对明文进行分组并进行加密转换处理 cipher = "" for i in range(0, len(plain), 2): a, b = plain[i], plain[i+1] row1, col1 = divmod(matrix.index([a]), 5) row2, col2 = divmod(matrix.index([b]), 5) if row1 == row2: cipher += matrix[row1][(col1+1)%5] + matrix[row2][(col2+1)%5] elif col1 == col2: cipher += matrix[(row1+1)%5][col1] + matrix[(row2+1)%5][col2] else: cipher += matrix[row1][col2] + matrix[row2][col1] return cipher key = "PLAYFAIREXAMPLE" matrix = create_matrix(key) plain = "Hide the gold in the tree stump" cipher = encode(plain, matrix) print(cipher) # "BMNDZBXDNABEKUDMUIXMMOUVIF" ``` 此代码实现playfair密码加密算法,使用给定的密钥矩阵对明文进行分组和加密转换处理,最终输出密文。注意,在使用此加密算法时,密钥矩阵的构建必须符合一定规则,并且明文中的空格和非字母字符需要被去掉。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值