You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未知密钥的移位密码(Shift Cipher)解密程序问题排查与优化咨询

Hey there! Let's work through your shift cipher program issues—first fixing that bug in the top-5 selection module, then making your code cleaner without all those messy if statements. I'll keep things clear and beginner-friendly.


First: Fixing the Top-5 Selection Bug

Your current code has two critical issues causing wrong results (especially with inputs like "VDDDDDDDDC"):

1. You're Not Resetting Your Count Variables

In the second for(x=1;x<=25;x++) loop, your e,a,r,i,o counters aren't reset to 0 before each new shift. This means counts from previous shifts are added to the current one, leading to inflated, incorrect numbers.

2. Your Selection Logic Is Misaligned

Right now, you're tracking which shift has the most E, which has the most A, etc.—but this often leads to duplicate shifts (one shift might top multiple character counts) and ignores the total number of all high-frequency characters combined. We need to score each shift by the sum of E+A+R+I+O, then pick the top 5 highest scores.

Fixed Code for the Selection Module

Add this code after generating all 25 decrypted results:

// First, calculate total score for each shift
int total_score[26] = {0}; // Index 0 unused, 1-25 map to shifts
char target_chars[] = {'E', 'A', 'R', 'I', 'O'};

for(int x=1;x<=25;x++){
    int score = 0;
    for(int f=0;store[x][f]!='\0';f++){
        char c = store[x][f];
        // Check if current character is one of our high-frequency targets
        for(int k=0;k<5;k++){
            if(c == target_chars[k]){
                score++;
                break;
            }
        }
    }
    total_score[x] = score;
}

// Now find the top 5 shifts by score
int top_shifts[5];
int top_scores[5] = {-1, -1, -1, -1, -1}; // Initialize to low values

for(int x=1;x<=25;x++){
    for(int k=0;k<5;k++){
        if(total_score[x] > top_scores[k]){
            // Shift existing top entries down to make space
            for(int m=4;m>k;m--){
                top_scores[m] = top_scores[m-1];
                top_shifts[m] = top_shifts[m-1];
            }
            top_scores[k] = total_score[x];
            top_shifts[k] = x;
            break;
        }
    }
}

// Output the top 5 results
printf("The program thinks the possible solutions are:\n");
for(int k=0;k<5;k++){
    printf("%s\n", store[top_shifts[k]]);
}

Second: Code Optimization (Ditch the Spaghetti ifs!)

Here are practical, beginner-friendly optimizations to clean up your code:

1. Use Arrays Instead of Individual Variables

Instead of separate e,a,r,i,o variables, use an array paired with a list of target characters. This makes it easy to add/remove high-frequency characters later without rewriting code:

// Define your target characters once
char target_chars[] = {'E', 'A', 'R', 'I', 'O'};
int char_counts[5] = {0}; // Indexes match target_chars

// Inside your counting loop:
for(int f=0;store[x][f]!='\0';f++){
    char c = store[x][f];
    for(int k=0;k<5;k++){
        if(c == target_chars[k]){
            char_counts[k]++;
            break;
        }
    }
}
int total = char_counts[0] + char_counts[1] + char_counts[2] + char_counts[3] + char_counts[4];

2. Simplify Shift Logic with Modulo Arithmetic

Your current decryption code uses multiple if statements to handle wrap-around. Use modulo (%) to simplify this to one line (no more nested ifs!):

// For uppercase letters (your input is all caps)
// Adjust the formula based on your shift direction (you said your first part works, so tweak if needed)
if(isupper(code[f])){
    store[x][f] = ((code[f] - 'A') + x) % 26 + 'A';
}
// If decryption requires shifting backward (more standard for shift ciphers), use:
// store[x][f] = ((code[f] - 'A') - x + 26) % 26 + 'A';

You'll need to include <ctype.h> for the isupper() function, which checks if a character is uppercase (way more readable than comparing ASCII values directly).

3. Use Structs for Organized Data

For more professional code, use a struct to store all data related to a single shift (shift number, decrypted text, score). Then use the standard library's qsort() function to sort shifts by score:

// Add this at the top of your file
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

// Define a struct to hold all shift-related data
typedef struct {
    int shift_num;
    int score;
    char decrypted_text[400];
} ShiftResult;

// Comparison function for qsort (sorts from highest to lowest score)
int compare_shifts(const void *a, const void *b){
    ShiftResult *sa = (ShiftResult*)a;
    ShiftResult *sb = (ShiftResult*)b;
    return sb->score - sa->score;
}

// In main(), replace your store array with this:
ShiftResult results[25];

// When generating decrypted text:
for(int x=0;x<25;x++){
    results[x].shift_num = x+1; // Keep shift numbering 1-25
    // Generate decrypted text into results[x].decrypted_text
    // Calculate score and assign to results[x].score
}

// Sort all results by score
qsort(results, 25, sizeof(ShiftResult), compare_shifts);

// Output top 5
printf("Top 5 possible solutions:\n");
for(int k=0;k<5;k++){
    printf("Shift %d: %s\n", results[k].shift_num, results[k].decrypted_text);
}

4. Fix Input Handling

Your scanf("%[^'\n']s", code); has a format error—remove the trailing s so it's scanf("%[^\n]", code);. Also, add a getchar() after reading the ciphertext to clear the newline from the input buffer (prevents issues with subsequent scanf calls):

printf("Enter your code here:\n");
scanf("%[^\n]", code);
getchar(); // Eat the leftover newline character

内容的提问来源于stack exchange,提问作者SirJames Longbottom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:32:34