用于对单字母替换密码进行字母频率攻击的程序


挑战在于显示五个可能的最可能的明文,这些明文可以从提供的单字母密码中解密,利用来自表示给定单字母密码的字符串 Str(大小为 K)的字母频率攻击。

让我们看看频率攻击到底是什么。

频率分析的根本基础是,特定字母和字母组合在任何给定文本段落中出现的频率各不相同。此外,实际上,该语言的每个样本在字母分布中都具有共同的模式。为了更清楚起见,

英语字母表有 26 个字母,但并非所有字母在书面英语中使用频率都相同。某些字母的使用频率不同。例如,如果您检查书籍或报纸中的字母,您会注意到字母 E、T、A 和 O 在英语单词中出现的频率非常高。但是,英语文本很少使用字母 J、X、Q 或 Z。此事实可用于解密维吉尼亚加密消息。术语“频率分析”指的是此方法。

在基本的替换密码中,明文中找到的每个字母都替换为不同的字母,并且其明文中的任何给定字符都永久地更改为密码文本中的相同字母。例如,如果每个字母 a 都转换为字母 X,则包含字母 Y 多次重复的密文消息将暗示密码分析员 Y 代表字母 a。

示例 1

让我们取字符串 T,

通过将英语字母按在英语字母表中的频率降序排列连接起来形成的字符串。

String T=ETAOINSHRDLCUMWFGYPBVKJXQZ”
Given string Str = "SGHR HR SGD BNCD";
Output:
THIS IS THE CODE
FTUE UE FTQ OAPQ
LZAK AK LZW UGVW
PDEO EO PDA YKZA
IWXH XH IWT  RDST

问题陈述

实现一个程序,对单字母替换密码进行字母频率攻击。

解决方案方法

为了对单字母替换密码进行字母频率攻击,我们采用以下方法。

解决此问题并对单字母替换密码进行字母频率攻击的方法是应用频率分析。

一种广为人知的破解密文的技术或实践就是频率分析。它基于对不同字母或字母组合在密文中出现频率和规律性的研究。各种字母或字母表在所有语言中以不同的速率使用。

例如,取单词“APPLE”。字母“A”的频率为 1,因为它只出现了一次,类似地,字母“L”的频率为 1,字母“E”的频率也为 1。但字母“P”的频率为 2,因为它重复了两次。

这就是我们找到字母频率的方式。

考虑 26 个字母中的每一个在典型的英语文本中出现的频率。如果我们将这些从最高频率到最低频率进行排序,则最常出现的字母是 E,其次是 T,然后是 A,依此类推 -

“ETAOINSHRDLCUMWFGYPBVKJXQZ”是按频率顺序排列的完整字母列表。

算法

对单字母替换密码进行字母频率攻击的算法如下所示

  • 步骤 1 - 开始

  • 步骤 2 - 定义一个函数,使用频率攻击或分析方法解密单字母替换密码

  • 步骤 3 - 存储最终 5 个可行的解密明文

  • 步骤 4 - 存储密文中每个字母的频率

  • 步骤 5 - 遍历字符串 Str

  • 步骤 6 - 迭代范围 [0, 5]

  • 步骤 7 - 迭代范围 [0, 26]

  • 步骤 8 - 定义一个临时字符串“cur”以一次或在当前时间创建一个明文

  • 步骤 9 - 现在利用计算出的移位创建第 i 个明文

  • 步骤 10 - 将密码的第 T 个字母移位 x

  • 步骤 11 - 将计算出的第 k 个字母添加到临时字符串 cur

  • 步骤 12 - 将输出打印为生成的 5 个可能的明文。

  • 步骤 13 - 停止

示例:C 程序

以下是上述算法的 C 程序实现,以便对单字母替换密码进行字母频率攻击。

#include <stdio.h>
#include <string.h>
// Define a function to decrypt given monoalphabetic substitution cipher by implementing the method of frequency analysis or an attack
void printTheString(char Str[], int K){

   // this stores the final 5 feasible plaintext //which are deciphered
   char ptext[5][K+1];
   
   // the frequency of every letter in the
   // cipher text is stored
   int fre[26] = { 0 }; 
   
   // The letter frequency of the cipher text is stored in the order of descendence
   int freSorted[26]; 
   
   // this stores the used alphabet 
   int Used[26] = { 0 }; 
   
   // Traversing the given string named Str
   for (int i = 0; i < K; i++) {
      if (Str[i] != ' ') {
         fre[Str[i] - 'A']++;
      }
   } 
   
   // Copying the array of frequency
   for (int i = 0; i < 26; i++) {
      freSorted[i] = fre[i];
   } 
   
   //by concatenating the english letters in //decreasing frequency in the english alphabet , the string T is //obtained
   char T[] = "ETAOINSHRDLCUMWFGYPBVKJXQZ"; 
   
   // Sorting the array in the order of descendence
   for (int i = 0; i < 26; i++) {
      for (int j = i + 1; j < 26; j++) {
         if (freSorted[j] > freSorted[i]) {
            int temp = freSorted[i];
            freSorted[i] = freSorted[j];
            freSorted[j] = temp;
         }
      }
   } 
   
   // Iterating in the range between [0, 5]
   for (int i = 0; i < 5; i++) {
      int ch = -1; 
      
      // Iterating in the range between [0, 26]
      for (int m = 0; m < 26; m++) { 
         if (freSorted[i] == fre[m] && Used[m] == 0) {
            Used[m] = 1;
            ch = m;
            break;
         }
      }
      if (ch == -1)
         break; 
         
      //  here numerical equivalent of letter is stored ith index of array letter_frequency
      int x = T[i] - 'A'; 
      
      //  now probable shift is calculated in the monoalphabetic cipher
      x = x - ch; 
      
      // defining a temporary string cur to create one plaintext at a time or at the current time
      char cur[K+1]; 
      
      //  ith plaintext is generated by making use of the shift calculated 
      for (int T = 0; T < K; T++) { 
      
         // whitespaces is inserted without any //change
         if (Str[T] == ' ') {
            cur[T] = ' ';
            continue;
         } 
         
         // Shifting the Tth cipher letter by x we get
         int y = Str[T] - 'A';
         y =y+x; 
         if (y < 0)
            y =y+ 26;
         if (y > 25)
            y -=26; 
            
         // Adding the kth calculated letter to the temporary string cur 
         cur[T] = 'A' + y;        
      }
      cur[K] = '\0';
      
      // The ith feasible plaintext is printed
      printf("%s\n", cur);
   }
}
int main(){
   char Str[] = "SGHR HR SGD BNCD";
   int K = strlen(Str);
   printTheString(Str, K);
   return 0;
}

输出

THIS IS THE CODE
FTUE UE FTQ OAPQ
LZAK AK LZW UGVW
PDEO EO PDA YKZA
IWXH XH IWT RDST

结论

同样,我们可以获得对单字母替换密码进行字母频率攻击的解决方案。

本文解决了获取对单字母替换密码进行字母频率攻击的程序的挑战。

此处提供了 C 编程代码以及对单字母替换密码进行字母频率攻击的算法。

更新于:2023 年 7 月 28 日

1K+ 次浏览

启动你的 职业生涯

通过完成课程获得认证

开始
广告