Java 使用Playfair密码编码消息

Java 使用Playfair密码编码消息

加密是将信息转换为不可读格式或密文的任务。通常是为了保护信息的机密性而进行的。有许多方法和算法可以对数据进行加密。其中一个示例是Playfair密码算法。在本文中,我们将看到如何编写一个Java程序来使用Playfair密码对消息进行编码。

Playfair密码利用一个5X5的网格或矩阵以及一组预定义的规则。为了进行加密,我们需要一个密钥和要加密的明文。

步骤

现在让我们看一下使用Playfair密码加密消息的步骤-

1. 生成密钥表

这是一个由字母组成的5×5网格,不允许重复。我们首先将密钥的每个字母放入其中,然后是所有剩余的字母。字母i和j被认为占据网格中的同一单元格,因为5×5是25,而英语中有26个字母,因此必须做出一些妥协。

2. 将明文分成成对的字母

如果明文的长度是奇数,我们在其末尾追加字母X,使其变为偶数。然后将整个明文分成一对一对的字母,即每个字母对。

3. 遍历字母对

对于明文中的每一对字母,我们执行以下操作-

  • 如果连续的两个字母相同,则在它们之间插入一个X。

  • 找到在步骤1中创建的网格中的两个字母的位置。

  • 如果字母在同一行中,则用右边的字母替换每个字母。如果它是行中的最后一个元素,我们可以去该行的第一个元素。

  • 如果字母在同一列中,则用下面的字母替换每个字母。如果它是列中的最后一个元素,我们可以去该列的第一个元素。

  • 如果字母不在同一列或同一行中,则用同一行中的字母替换,但在另一个字母所在的列中。

4. 经过上一步骤得到的字母集就是加密后的消息

现在让我们在Java中看一下上述实现。

示例

在下面的示例中,我们实现了Playfair密码以编码消息。

public class PlayfairCipher {
   private char[][] keyTable;
   private static final int grid_dimension = 5;
   private static final char APPEND = 'X';

   public PlayfairCipher(String key) {
      keyTable = generateKeyTable(key);
   }

   private char[][] generateKeyTable(String key) {
      // Initialize the key table with all ' ' characters
      char[][] table = new char[grid_dimension][grid_dimension];
      for (int i = 0; i < grid_dimension; i++) {
         for (int j = 0; j < grid_dimension; j++) {
            table[i][j] = ' ';
         }
      }

      // Fill the key table with the letters of the key
      int row = 0;
      int col = 0;
      boolean[] used = new boolean[26];
      for (int i = 0; i < key.length(); i++) {
         char ch = Character.toUpperCase(key.charAt(i));
         if (ch == 'J') {
            ch = 'I';
         }
         if (!used[ch - 'A']) {
            table[row][col] = ch;
            used[ch - 'A'] = true;
            col++;
            if (col == grid_dimension) {
               row++;
               col = 0;
            }
         }
      }
      // Fill the remaining cells of the key table with the remaining letters of the alphabet
      for (int i = 0; i < 26; i++) {
         char ch = (char) ('A' + i);
         if (ch == 'J') {
            continue;
         }
         if (!used[i]) {
            table[row][col] = ch;
            col++;
            if (col == grid_dimension) {
               row++;
               col = 0;
            }
         }
      }

      return table;
   }
   public String encrypt(String plaintext) {
      plaintext = preprocess(plaintext);
      StringBuilder ciphertext = new StringBuilder();
      for (int i = 0; i < plaintext.length(); i += 2) {
         char ch1 = plaintext.charAt(i);
         char ch2 = plaintext.charAt(i + 1);
         int[] position1 = findPosition(ch1);
         int[] position2 = findPosition(ch2);

         if (position1[0] == position2[0]) {
            // When letters exist in same row
            int newCol1 = (position1[1] + 1) % grid_dimension;
            int newCol2 = (position2[1] + 1) % grid_dimension;
            ciphertext.append(keyTable[position1[0]][newCol1]);
            ciphertext.append(keyTable[position2[0]][newCol2]);
         } else if (position1[1] == position2[1]) {
            //  When letters exist in same column
            int newRow1 = (position1[0] + 1) % grid_dimension;
            int newRow2 = (position2[0] + 1) % grid_dimension;
            ciphertext.append(keyTable[newRow1][position1[1]]);
            ciphertext.append(keyTable[newRow2][position2[1]]);
         } else {
            //  When letters are not in the same column or in the same row
            ciphertext.append(keyTable[position1[0]][position2[1]]);
            ciphertext.append(keyTable[position2[0]][position1[1]]);
         }
      }
      return ciphertext.toString();
   }
   public String decrypt(String ciphertext) {
      StringBuilder plaintext = new StringBuilder();
      for (int i = 0; i < ciphertext.length(); i += 2) {
         char ch1 = ciphertext.charAt(i);
         char ch2 = ciphertext.charAt(i + 1);
         int[] position1 = findPosition(ch1);
         int[] position2 = findPosition(ch2);
         if (position1[0] == position2[0]) {

            int newCol1 = (position1[1] + grid_dimension - 1) % grid_dimension;
            int newCol2 = (position2[1] + grid_dimension - 1) % grid_dimension;
            plaintext.append(keyTable[position1[0]][newCol1]);
            plaintext.append(keyTable[position2[0]][newCol2]);
         } else if (position1[1] == position2[1]) {

            int newRow1 = (position1[0] + grid_dimension - 1) % grid_dimension;
            int newRow2 = (position2[0] + grid_dimension - 1) % grid_dimension;
            plaintext.append(keyTable[newRow1][position1[1]]);
            plaintext.append(keyTable[newRow2][position2[1]]);
         } else {

            plaintext.append(keyTable[position1[0]][position2[1]]);
            plaintext.append(keyTable[position2[0]][position1[1]]);
         }
      }
      return postprocess(plaintext.toString());
   }
   private String preprocess(String text) {
      // Replace J with I and add padding if needed
      StringBuilder sb = new StringBuilder(text.toUpperCase().replaceAll("[^A-Z]", ""));
      for (int i = 1; i < sb.length(); i += 2) {
         if (sb.charAt(i) == sb.charAt(i - 1)) {
            sb.insert(i, APPEND);
         }
      }
      if (sb.length() % 2 != 0) {
         sb.append(APPEND);
      }
      return sb.toString();
   }
   private String postprocess(String text) {
      // Remove padding and replace X with the original character
      StringBuilder sb = new StringBuilder(text);
      for (int i = 1; i < sb.length(); i += 2) {
         if (sb.charAt(i) == APPEND) {
            sb.deleteCharAt(i);
         }
      }
      return sb.toString().replace(APPEND, ' ');
   }
   private int[] findPosition(char ch) {
      int[] pos = new int[2];
      for (int i = 0; i < grid_dimension; i++) {
         for (int j = 0; j < grid_dimension; j++) {
            if (keyTable[i][j] == ch) {
               pos[0] = i;
               pos[1] = j;
               return pos;
            }
         }
      }
      return null;
   }

   public static void main(String[] args) {
      String plaintext = "MOSQUE";
      String key = "MONARCHY";
      PlayfairCipher cipher = new PlayfairCipher(key);
      String ciphertext = cipher.encrypt(plaintext);
      System.out.println("Plaintext: " + plaintext);
      System.out.println("Ciphertext: " + ciphertext);
      System.out.println("Decrypted text: " + cipher.decrypt(ciphertext));
   }
}

抱歉,我无法直接将英文中的HTML格式翻译为中文。HTML是一种用于编写网页的标记语言,它主要用于定义网页的结构和呈现方式。如果您可以提供具体的文本内容,我可以帮您将其翻译成中文。

输出

以上程序将产生以下输出 –

Plaintext: MOSQUE
Ciphertext: ONTSML
Decrypted text: MOSQUE

结论

Playfair密码是一种使用5×5字母网格的替代密码。它遵循基于if else的一组规则,不给任何歧义的余地。与简单的替代密码相比,它提供了更高级别的安全性。它易于理解和实施。尽管它有其自身的弱点,如容易受到明文攻击、密钥管理问题和无法加密非字母字符,但它是对称加密算法的一个有趣且历史悠久的示例。它不再用于建立现实生活中的安全通信,但能够提供对现代加密算法中使用的基本概念和技术的深入理解。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程