【问题标题】:Vigenere's cipher in C several problemsC中的Vigenere密码几个问题
【发布时间】:2018-02-26 06:16:47
【问题描述】:

我已经制作了加密和解密 Vigenere 密码的程序,但我有几个问题。

  • 这是一个:句子的第一个字母加密不正确。
  • 第二个:句后我有信K。我认为这是因为空间问题,但我不知道如何解决。
  • 第三个问题:我知道很久以前使用 Vigenere 的密码时,加密句子中没有空格,没有空格,但如果可能的话,我希望有 5 个字母为一组。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char **argv) {
    char message[100];
    int choice;
    int i, j;
    char pass[33];
    int value;
    char repeat = 1;

    while (repeat == 1) {
        printf("Enter operation\n");
        printf("Encrypt - 1 \n");
        printf("Decrypt - 2\n");

        scanf("%d", &choice);

        if (choice == 1) {
            printf("Please enter message to encrypt\n");
            while (getchar() != '\n');
            fgets(message, 100, stdin);

            printf("Enter password\n");
            scanf("%s", &pass);

            for (i = 0, j = 0; i < strlen(message); i++, j++) {
                if (message[i] == ' ')
                    continue;

                if (j >= strlen(pass)) {  
                    j = 0;
                }
                if (!isupper(message[i])) {
                    value = (((message[i]) - 97) + ((pass[j]) - 97));
                }
                if (!islower(message[i])) {
                    value = (((message[i]) - 65) + ((pass[j]) - 65));   
                }
                printf("%c", 97 + (value % 26));
            }
            printf("\nWould you like to repeat? [1/0]\n");
            scanf("%d", &repeat);
        } else
        if (choice == 2) {
            printf("Enter message do decrypt\n");
            while (getchar() != '\n');
            fgets(message, 100, stdin);

            printf("Zadejte heslo\n");
            scanf("%s", &pass);

            for (i = 0, j = 0; i < strlen(message); i++, j++) {
                if (message[i] == ' ')
                    continue;

                if (j >= strlen(pass)) {  
                    j = 0;
                }
                if (!isupper(message[i])) {
                    value = (((message[i]) - 96) - ((pass[j]) - 96));
                }
                if (!islower(message[i])) {
                    value = (((message[i]) - 64) - ((pass[j]) - 64));   
                }
                if (value < 0) { 
                    value = value * -1; 
                }
                printf("%c", 97 + (value % 26));
            }
            printf("\nWould you like to repeat? [1/0]\n");
            scanf("%d", &repeat);
        }
    }
    return (EXIT_SUCCESS);
}

[

【问题讨论】:

    标签: c encryption netbeans vigenere


    【解决方案1】:

    您的代码中的主要问题是您将翻译应用于测试不正确的字符:您应该翻译大写字母是您确实有一个大写字母,而不是如果您没有小写字符。按照编码,非字母被翻译两次。

    将代码改为:

                if (islower((unsigned char)message[i])) {
                    value = (((message[i]) - 'a') + ((pass[j]) - 'a'));
                }
                if (isupper((unsigned char)message[i])) {
                    value = (((message[i]) - 'A') + ((pass[j]) - 'a'));   
                }
    

    还要确保使用字符常量而不是硬编码的 ASCII 值,并将密码设为小写。

    在解密的情况下,偏移量似乎不正确。你也应该使用'A''a'

    【讨论】:

    • 好的,我已经解决了,我将使用字符而不是 ASCII 数字。
    • @popcorn:您不应该修复问题中发布的代码,因为它会使 cmets 和答案不一致。您可以添加带有进一步解释和额外问题的 EDIT 段落。
    【解决方案2】:

    首先,消息损坏。如果您在执行加密的循环中添加一些printf() 语句,您应该能够知道出了什么问题。您可以随时将它们注释掉,或完全删除它们。

    最后的 K 可能是加密后的 \n,它会与消息一起读入。

    要以五个字符为一组显示加密消息,请记录您实际显示的字符数(确保增加计数的指令位于如果字符不显示将被跳过的位置);当达到 5 时,显示一个空格并将计数器重置为零。

    【讨论】:

    • 我添加了一些 printf's() 并且看起来一切正常还是?但我想我会在最后用while (getchar() != '\n');撞到那个K
    最近更新 更多