1

这段代码我写到现在,现在需要用频率分析来破解我不清楚的代码。

据我了解,我必须首先计算一个字符串中字母的频率,然后我会说它与德语中最常见的字母进行比较,然后用冒泡排序对其进行排序。这个对吗?

如果有人能给我关于从哪里开始的想法或提示,我将不胜感激。先感谢您。

编辑:嗨,伙计们,我刚刚编辑了我的代码,频率分析现在似乎工作正常。如果你们可以对我的代码发表评论或批评,那将对我有所帮助。谢谢!顺便说一句,它的德语,我改变了它。

#include <stdio.h> 
#include <conio.h> 
#include <string.h> 
#include <ctype.h>
#define MAX 100

struct Data
{
    char letter;
    int num;
};
typedef struct Data DATA;

void encode(char message[], int shift)      
{
    int i;
    FILE *pout;
    pout = fopen("Output_encode.txt", "w");
    if (pout == NULL)
    {
        printf("File could not be opened for writing!\n");
        exit(1);
    }



    for(i=0;i<strlen(message);i++) 
    { 
        if (!isalpha(message[i]))
            continue;                           
        // checking for upper case 
        if(isupper(message[i]))
            message[i]=((message[i]-'A') + shift) % 26 + 'A'; 
        else 
            //checking for lower case 
            if(islower(message[i]))  
                message[i]=((message[i]-'a') + shift) % 26 + 'a'; 
    }

    printf("\n\tEncoded text: %s\n", message);
    fprintf(pout, "%s\n", message);
    if (fclose(pout) != 0)
        printf("Error in closing file!\n");
}

void decode(char message[], int shift)
{
    int i;
    FILE *pout;

    pout = fopen("Output_decode.txt", "w");
    if (pout == NULL)
    {
        printf("File could not be opened for writing!\n");
        exit(1);
    }

    for(i=0;i<strlen(message);i++) 
    { 
        if (!isalpha(message[i]))
            continue;                           
        // checking for upper case 
        if(isupper(message[i]))
            message[i]=((message[i]-'A') + (26-shift)) % 26 + 'A'; 
        else 
            //checking for lower case
            if(islower(message[i]))  
                message[i]=((message[i]-'a') + (26-shift)) % 26 + 'a'; 
    }

    printf("\n\tDecoded text: %s\n", message);
    fprintf(pout, "%s\n", message); 
    if (fclose(pout) != 0)
        printf("Error in closing file!\n");
}

void textfile_decode()
{
    FILE *pin, *pout;
    char filename_in[MAX], filename_out[MAX];
    char text[MAX];
    char text3[MAX]={0};
    char table[26] = {'e','n','i','r','s','t','a','d','h','u','l','c','g','o','m','b','f','w','k','z','p','v','j','y','x','q'}; //Frequency letters in German dictionary
    DATA temptext, text2[26];
    int temp, position;
    int i, m, max, trial, l=0, n=0, k=0;

    printf("Enter name of input file: "); 
    scanf("%s", filename_in);
    pin = fopen(filename_in, "r");
    if (pin == NULL)
    {
        printf("File could not be opened for reading!");
    }

    printf("Enter name of output file: ");
    scanf("%s", filename_out);
    pout = fopen(filename_out, "w");
    if (pout == NULL)
    {
        printf("File could not be opened for writing!");
    }

    printf("\nOriginal Code:\n");
    while(!feof(pin))
    {
        fgets(text, MAX, pin);     //Read from textfile
        fputs(text, stdout);         //Show original code on console
    }
    printf("\n");
    if (pin == NULL)
    {
        printf("File could not be opened for reading!");
    }
    fclose(pin);
    pin = fopen(filename_in, "r");

    for (i = 0; i <= 25; i++)       
    {                               
        text2[i].letter = 'a' + i;  //Array elements A-Z     
        text2[i].num = 0;           //Number of letters (Frequency)
    }

    while(!feof(pin))
    {
        i = 0;
        fgets(text, MAX, pin);  //Read from textfile per line
        while(text[i] != '\0')
        {
            if(1 == isupper(text[i]))  // Replace capital letters with small
            {                          
                text[i] += 32;
            }
            switch(text[i]) //Counting letters (letter frequency)
            {
            case 'a': 
                text2[0].num += 1;
                break;
            case 'b': 
                text2[1].num += 1;
                break;
            case 'c':
                text2[2].num += 1;
                break;
            case 'd': 
                text2[3].num += 1;
                break;
            case 'e': 
                text2[4].num += 1;
                break;
            case 'f': 
                text2[5].num += 1;
                break;
            case 'g': 
                text2[6].num += 1;
                break;
            case 'h': 
                text2[7].num += 1;
                break;
            case 'i': 
                text2[8].num += 1;
                break;
            case 'j': 
                text2[9].num += 1;
                break;
            case 'k': 
                text2[10].num += 1;
                break;
            case 'l': 
                text2[11].num += 1;
                break;
            case 'm': 
                text2[12].num += 1;
                break;
            case 'n': 
                text2[13] .num+= 1;
                break;
            case 'o': 
                text2[14].num += 1;
                break;
            case 'p': 
                text2[15].num += 1;
                break;
            case 'q': 
                text2[16].num += 1;
                break;
            case 'r': 
                text2[17].num += 1;
                break;
            case 's': 
                text2[18].num += 1;
                break;
            case 't': 
                text2[19].num += 1;
                break;
            case 'u': 
                text2[20].num += 1;
                break;
            case 'v': 
                text2[21].num += 1;
                break;
            case 'w': 
                text2[22].num += 1;
                break;
            case 'x': 
                text2[23].num += 1;
                break;
            case 'y': 
                text2[24].num += 1;
                break;
            case 'z': 
                text2[25].num += 1;
                break;
            default: break;
            }   
            i++;    
        }
    }

    for(i = 0; i <= 26; i++)          // Sorting array text2 according to letter frequency
    {                                 
        temp = text2[i].num;
        for(m = i+1; m <= 27; m++)
        {
            if(text2[m].num > temp)
            {
                max = m;
                temp = text2[m].num;
            }
        }
        temptext = text2[max];
        text2[max] = text2[i];
        text2[i] = temptext;
    }
    fclose(pin);
    fclose(pout);

    pin = fopen(filename_in, "r");
    pout = fopen(filename_out, "w");

    do
    {
        k += 1;
    } while (text2[k].num == text2[k+1].num);        //Check--> How many letters have the same frequency

    trial = 2;

    while(!feof(pin))
    {
        fgets(text, MAX, pin);
        do
        {
            position = table[l] - text2[n].letter;        // determine letter position
            i = 0;
            do
            {
                if(0 !=isalpha(text[i]))
                {
                    if(0 != isupper(text[i]))         // Checking for uppercase
                    {
                        text3[i] = text[i];
                        text3[i] = text3[i] + position;
                        if(text3[i] > 90)        // If exceeds Alphabets, start again from 'A'
                        {
                            text3[i] = text3[i] - 26;
                        }
                        else if (text3[i] < 65)
                        {
                            text3[i] += 26;
                        }
                    }
                    else if (0 != islower(text[i]))         // checking for lowercase
                    {
                        text3[i] = text[i];
                        text3[i] = text3[i] + position;
                        if(text3[i] > 122)       // If exceeds Alphabets, start again from 'a'
                        {
                            text3[i] = text3[i] - 26;
                        }
                        else if(text3[i] < 97)
                        {
                            text3[i] += 26;
                        }
                    }
                }
                else
                {
                    text3[i] = text[i];      // All other non letters are simply replaced
                }
                i++;
            }while(text[i] != '\0' );

            if (trial== 2)
            {
                printf("\n");
                fputs(text3, stdout);
                printf("\nCode decrypted? (0)NO (1)YES : ");
                scanf("%d", &trial);
                printf("\n");
            }

            if (trial == 0 && n != k)      // Code not decrypted, letters have different frequency
            {                              
                n++;
                trial = 2;
            }
            if (trial == 0 && n == k)        // Code not decrypted, letters have same frequency
            {                                
                l++;
                n = 0;
                trial = 2;
            }
            if (trial == 3)         // First line of code is decrypted, following lines will decrypted using same shift position 
            {                      
                trial = 1;
            }
        }while(trial != 1);
        fputs(text3, stdout);       //Show on console window
        fputs(text3, pout);
        memset(text3,'\0',100);        // Reset text3 array
        memset(text,'\0',100);         // Reset text array
        trial = 3;        // First line of code decrypted, shift position is saved
    }
    fclose(pin);
    fclose(pout);

}


int main()
{ 
    int shift, choice1, choice2; 
    char message[MAX]; 

    do{
        printf("Selection: \n");
        printf("(1) Encode/Decode\n");
        printf("(2) Decode Textfile\n");
        printf("(3) End Programme\n");
        printf("User input: ");
        scanf("%d", &choice1);
        fflush(stdin);


        switch(choice1){
        case 1:
            printf("\nEnter message to be encrypted: "); 
            gets(message);
            printf("Enter shift amount (1-25): ");  
            scanf("%d", &shift); 
            printf("\nSelection: \n");
            printf("(1) Encode\n");
            printf("(2) Decode\n");
            printf("User input: ");
            scanf("%d", &choice2);
            switch(choice2)
            {
            case 1:
                encode(message, shift);
                break;
            case 2:
                decode(message, shift);
                break;
            }
            break;
        case 2:
            textfile_decode();
            break;
        }
        printf("\n\n");
    }while(choice1!=3);

    printf("\n");
    return 0; 
}
4

2 回答 2

3

凯撒密码通过移动字符位置来改变字符n

有两种非常简单的方法可以解决移位密码:

  1. 打印所有 25 种可能的解决方案。手动选择包含可读文本的那个。

  2. 获取字符(而不是单词)的频率。然后执行与编写消息所用语言的频率表(在您的情况下是英语?)最一致的转变。

于 2013-11-04T10:11:05.557 回答
2

要破解代码,您可以使用 3 种不同的方法:

第一个是您引用的内容:计算文本中单词的频率(我宁愿使用 Map ,使用字符串作为键并增加命中数作为值。),并通过比较来猜测字母普通文本中使用单词的频率。

第二种解决方案是对字母做同样的事情,并通过将您的频率与普通文本中字母的频率进行比较来猜测其含义。

第三种解决方案是取文本中的单个单词并尝试所有可能的字母转换,直到你得到有意义的单词。

在这里你可以找到一些好的资源!

于 2013-11-04T09:30:21.130 回答