2016-01-03 21 views
0

Это мое упражнение для занятий, которое мы должны выполнить с помощью «hdvb wr euhdn» и найти ключ, который работает, но мой код разбивает его (я думаю, правильно), но два разных ключа дают одинаковый результат. Является ли это нормальным, или я делаю это неправильно?Caesar Cipher bruteforce

Ключи 2 и 11 работают, а некоторые другие, которые не работают, повторяют одни и те же символы. Мы просто написали основные шифры цезарного сдвига, и я подумал, что этот подход был лучшей грубой силой. enter image description here

#include<iostream> 
#include<String> 

using std::string; 
using std::endl; 

void bruteForce(string x); 

void bruteForce(string x) 
{ 

    int key = 0; 

    int length = (int)x.length(); 

    for (int i = 0; i < 25; i++) 
    { 
     key++; 
     std::cout << "The key is " << key << endl; 
     std::cout << endl; 
     for (int j = 0; j < length; j++) 
     { 

      if (x[j] == ' ') 
      { 
       x[j] = ' '; 
       std::cout << x[j]; 
       j++; 
      } 
      x[j] = tolower(x[j]); 
      x[j] -= 97; 
      x[j] -= key; 
      if (x[j] < 0) 
      { 
       x[j] += 26; 

      } 
      x[j] += 97; 

      std::cout << x[j]; 
     } 

     std:: cout << endl; 

    } 

} 
+3

Похоже, вы изменяете строку на месте, что означало бы каждый цикл становится другой вход. –

ответ

0

Каждый цикл модификации вход, как упомянуто Александр О'Мара - рефакторинг отделить ключ перехода от теста.

Объявляет функцию для тестирования (отдельно от грубой силы)

void Test(std::string x, int key); 

Вызывается из BruteForce.

void bruteForce(string x) 
{ 

    int key = 0; 

    for (int i = 0; i < 25; i++) 
    { 
     key++; 
     Test(x, key); 
    } 
} 

Реализация

void Test(std::string x, int key) 
{ 
    int length = (int)x.length(); 
    std::cout << "The key is " << key << endl; 
    std::cout << endl; 
    for (int j = 0; j < length; j++) 
    { 
     if (x[j] == ' ') 
     { 
      x[j] = ' '; 
      std::cout << x[j]; 
     } 
     else { 
      x[j] = tolower(x[j]); 
      x[j] -= 97; 
      x[j] -= key; 
      if (x[j] < 0) 
      { 
       x[j] += 26; 

      } 
      x[j] += 97; 
     } 
     std::cout << x[j]; 
    } 

    std::cout << endl; 



} 

Я немного изменил свой пропуск для пространства, так что 2 пробела подряд, не путайте.

Код работает, потому что каждый вызов Test является новой копией нетронутой строки. Каждый последующий ключ для cesear cypher сдвигается на один символ, поэтому вы должны предупредить вас о повторном использовании строки.

+0

Ваша декларация для 'Test' неверна. Это должно быть 'void Test (std :: string x, int key);', но у вас есть 'void Test (std :: string s, int key);'. –

+0

Больше непоследовательности, чем неверно - имена игнорируются в объявлении – mksteve

+0

О, спасибо. Не знал этого. –

0

Вы можете просто использовать следующую функцию, чтобы расшифровать код шифра Цезаря

void decrypt(char arr[],int key){ 
int i,j; 
for(i=0;i<strlen(arr);i++){ 
    if(arr[i]==' ') 
     continue; 
    for(j=0;j<key;j++){ 
     arr[i]--; 
     if(arr[i]<97 && arr[i] > 90) 
      arr[i] = 122; 
     if(arr[i] < 65) 
      arr[i] = 90; 
    } 

}} 

Для грубой силы, вы можете просто поставить вышеуказанную функцию в цикл, который будет итерацию от 1 до 26, предоставляя все 26 возможные ключи к функции дешифрования. Ниже приведен пример

int main(){ 
int i; 
char arr[100],copy[100]; 
printf("Enter a string: "); 
scanf ("%[^\n]s", arr); 
strcpy(copy,arr); 
for(i=1;i<=26;i++){ 
    encrypt(arr,i); 
    printf("Bute Force key : %d ---> %s\n",i,arr); 
    strcpy(arr,copy); 
}} 

источник Encrypt Функция: C program to implement Caesar Cipher Algorithm