首页 > 解决方案 > 用于解密 C 中的字符串的蛮力函数(凯撒密码)

问题描述

我发现这个问题很有趣,因为你需要在 C 中使用字母作为数组。任务是以基本的凯撒密码方式暴力破解每个可能的 K 值。

但是,我想出的代码在K = 1. 例如,一封信C被转成Z而不是A等。任何人都可以发现我做错了什么吗?

#include <stdio.h>
#include <string.h>
void bruteforce (char*);  

int main() {
    char cyphertext[] = "kyvtrmrcipnzccrkkrtbwifdkyvefikynvjkrkeffe";
    bruteforce(cyphertext);

    return 0;
}

void bruteforce (char *cyphertext) {
    char alphabet[26] = "abcdefghijklmnopqrstuvwxyz";
    long int size = strlen(cyphertext);

    for (int k = 0; k < 26; k++){
        for (long int i = 0; i < size; i++){
            for (int j = 0; j < 26; j++){
                if (alphabet[j] == cyphertext[i]){
                    cyphertext[i] = alphabet[j - k];
                    if (k > j){
                        cyphertext[i] = alphabet[26 + j - k];
                    }
                    break;
                }
            }
         }
        printf("%s\n ", cyphertext);
    }
}

标签: cfor-loopencryption

解决方案


对于 Caesar Cypher 移位,您不需要使用字母字符串。您可以将字符转换为 ASCII 码。'a' - 'z' 的 ASCII 码是 97 - 122。因此,如果使用 + 1 解码。如果字符是 a - z,您只需为每个字符加一个即可。如果将移位值与字符值相加后字符值大于 122,则取字符值并将其减去 122,然后再加上 96。

如果字符值小于 97,则为负数。将 97 减去字符值。然后将前一个方程值减去 123。尽管如此,我还是构建了代码,以便将负偏移转换为正偏移。如果移位是负数,我们取 26 并加上。例如,移动 -1 将使 a 变为 z。所以这类似于移位 26 + -1 = 25。

移位值可以大于 +25 或小于 -25。尽管如此,如果是,它将是 26 的模数。

如果您想暴力破解字符串的所有可能组合。只需使用下面的函数并在从 1 到 25 的循环中运行它。但是您的函数会修改原始字符串。因此,在进行暴力破解时,您必须将函数的字符串复制到临时字符串并让函数对其进行处理。示例如下。

#include <stdio.h>
#include <string.h>
void bruteforce (char *cyphertext, int shiftBy);

int main() {
    char cyphertext[] = "kyvtrmrcipnzccrkkrtbwifdkyvefikynvjkrkeffe";
    char cyphertext2[] = "yvccf wifd bvmze";
    bruteforce(cyphertext, -17);
    puts("");
    bruteforce(cyphertext2, 9);       

    /* Bruteforce example */
    puts("");
    puts("Bruteforce section:");
    // +9
    char cyphertext3[] = "kyzjkvokzjkfsvtirtb nyrk tre kyzj sv zj zk yvccf nficu";
    char temp[50];

    for (int i = 1; i < 26; i++){
       printf("Trying to crack by shifting %d \n", i );
       strcpy(temp, cyphertext3);
       bruteforce(temp, i);
       puts("");
    }
    /* End Bruteforce example */

    return 0;
}
// If there is no shift i.e 0, 26, 52, -26
// It won't print
void bruteforce (char *cyphertext, int shiftBy){
    size_t size = strlen(cyphertext);

    if ( shiftBy > 25){
        shiftBy = shiftBy % 26;
    } else if ( shiftBy < 0 ) {
        shiftBy = 26 + (shiftBy % 26);
        // If shiftBy is 26 
        // there is no need to shift.
        if ( shiftBy == 26 ) return;
    }

    // If there is no shift return.
    if ( shiftBy == 0 ) return;

    for ( size_t i = 0; i < size; i++){
          // 97 - 122 is a - z
          // if char is a - z
          if ( cyphertext[i] > 96 && cyphertext[i] < 123 ){
              // add shift by
              cyphertext[i] += shiftBy;
              // if char > z
              // then take char - z then add to the ascii code that just before 'a'.
              // Since shiftBy is converted fomr negative to positive., 
              // There will not be a negative shiftBy.
              if ( (unsigned char)cyphertext[i] > 122 )
                  cyphertext[i] = ((unsigned char) cyphertext[i]) - 122 + 96;
          }

          // If want to do A - Z 
          // ASCII code are 65 - 90.
    }
    printf("%s\n", cyphertext);
}

推荐阅读