C++ 在一个单字母替代密码上执行字母频率攻击

C++ 在一个单字母替代密码上执行字母频率攻击

挑战是显示出从给定的单字母密码中解密出来的可能的前五个明文,利用字母频率攻击从一个大小为K的字符串Str中进行。该字符串表示给定的单字母密码。

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

频率分析的基本原理是特定的字母和字母组合在任何给定的书面语言节段中以不同的频率出现。此外,该语言的每个样本在字母分布方面都有一个共同的模式。为了更清楚地解释,

英语字母表有26个字母,但并不是所有字母在书面英语中的使用频率相等。某些字母的使用频率是不同的。例如,如果你观察一本书或一份报纸中的字母,你会注意到字母E、T、A和O在英文单词中经常出现。然而,英文文本很少使用字母J、X、Q或Z。这个事实可以用来解密维吉尼亚加密的信息。术语”频率分析”指的就是这种方法。

在明文中找到的每个字母都用一个不同的字母替代,基本的替代密码中的任何给定字符都会永远改变为密码文本中相同的字母。例如,一个密文消息中重复出现多次的字母Y可能意味着密文中每个字母a的实例都被转换为字母X。

示例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,因为它重复了两次。

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

考虑每个字母在典型的英语文本中出现的频率。出现频率最高的字母是 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编程代码以及执行对单字母替代密码进行字母频率攻击的算法。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程