【问题标题】:C - Vigenere EncryptionC - Vigenere 加密
【发布时间】:2021-10-25 04:44:54
【问题描述】:

我用 c 编写了自己的 vigenere cypher 控制台程序。我的代码有很多我理解的部分,但是输出错误并且不知道如何修复它。我的目标是能够加密整个段落。

第 5-36 行 -> 表格。第 37-51 行 -> 声明、输入、注释。第 52-52 行 -> 设置 j 以获得更长的输入。 59-74 -> 比较输入与字母。 77-81 -> 打印输入。 82-84 -> 输入长度。 85-892 -> 字母表中的位置。 94-121 -> 数组数组。 122 -> 数字声明.. 132-129 -> 打印数组数组。 130-150 -> 我的加密很差。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
    printf("   |\n");
    printf("   |  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  \n");
    printf("---+------------------------------------------------------------------------------  \n");
    printf(" A |  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  \n");
    printf(" B |  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  \n");
    printf(" C |  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  \n");
    printf(" D |  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  \n");
    printf(" E |  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  \n");
    printf(" F |  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  \n");
    printf(" G |  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  \n");
    printf(" H |  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  \n");
    printf(" I |  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  \n");
    printf(" J |  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  \n");
    printf(" K |  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  \n");
    printf(" L |  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  \n");
    printf(" M |  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  \n");
    printf(" N |  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  \n");
    printf(" O |  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  \n");
    printf(" P |  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  \n");
    printf(" R |  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  \n");
    printf(" S |  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  \n");
    printf(" T |  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  \n");
    printf(" U |  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  \n");
    printf(" V |  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  \n");
    printf(" W |  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  \n");
    printf(" X |  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  \n");
    printf(" Y |  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  \n");
    printf(" Z |  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  \n");
    printf("==================================================================================  \n");
    printf("USE ONLY THIS : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
    printf(" CHARRACTERS  : abcdefghijklmnopqrstuvwxyz\n");
    printf("==================================================================================  \n");
    char s1[20],s2[20];
    char abeceda[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    printf("First input:   ");
    scanf("%s",&s1);
    printf("Secound input: ");
    scanf("%s",&s2);
    int i=0,k=0,j=0,l=0,m=0,y=0,x=0;
    j=strlen(s1),l=strlen(abeceda),m=strlen(s2);
    int r=10;
    int array[50],array0[50];
    printf("\n");
    printf("1-means code found agreement with first input.\n");
    printf("2-means code found agreement with secound input.\n");
    printf("\n");
    printf("number of matches:\n");
    if(strlen(s1)<=strlen(s2))
    {
        j=strlen(s2);
    }
    else{
        j=(strlen(s1));
    }
    for(i=0;i<j;i++){
        for(k=0;k<l;k++){
        //first input
        if(s1[i]==abeceda[k]){
            printf("1");
            //printf("%c ",s1[i]);//printf("%i",k);
            array[y]=k;
            y++;
        }
        //druhe slovo
        if(s2[i]==abeceda[k]){
            printf("2");
            //printf("  |  ");//printf("%c\n",s2[i]);    //printf("%i",k);
            array0[x]=k;
            x++;
        }}}
    printf("\n");
    printf("\n");
        printf("-1-|-2-\n");
    for(i=0;i<j;i++){
        /*for(k=0;k<l;k++){if(s1[i]!=abeceda[k]){ s1[i]=" ";}if(s2[i]!=abeceda[k]){ s2[i]=" ";printf("1");}     printf("\n");   }*/
        printf(" %c | %c\n",s1[i],s2[i]);
        }
    printf("\nlen of s1: %i",y);
    printf("\nlen of s2: %i\n",x);
printf("\n");
    for(k=0;k<j;k++){
    printf("%i,",array[k]);
}
printf("\n");
    for(k=0;k<m;k++){
        printf("%i,",array0[k]);
        }
        printf("\n\n");
        printf("comparing table:\n");
    char Row_Of_Row[26][26]={
    {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'},
    {'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a'},
    {'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b'},
    {'d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c'},
    {'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d'},
    {'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e'},
    {'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f'},
    {'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g'},
    {'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h'},
    {'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i'},
    {'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j'},
    {'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k'},
    {'m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l'},
    {'n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m'},
    {'o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n'},
    {'p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'},
    {'q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'},
    {'r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q'},
    {'s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r'},
    {'t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s'},
    {'u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'},
    {'v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u'},
    {'w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v'},
    {'x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w'},
    {'y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'},
    {'z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y'},
};
    int a=0,b=25,c=0,d=0,e=0;
    for(a=0;a<=b;a++){
    for(c=0;c<=b;c++){
    printf("%c",Row_Of_Row[c][a]);
    }
    printf("\n");
    }
    printf("\n");
char NewRoad[j];
printf("Length of output word is: %i",j);
printf("\n");

printf("encryption: ");
for(a=0;a<j;a++){
    d=array[a];
    e=array0[a];
    printf("%i,%i\n",d,e);
    printf("%c",Row_Of_Row[d][e]);
    //NewRoad[a]=Row_Of_Row[d][e];
    //printf("%c",NewRoad[a]);
    NewRoad[a]=Row_Of_Row[d][e];
    printf("\n");
}
printf("Output is: ");
for(a=0;a<j;a++){
printf("%c",NewRoad[a]);
}
printf("\n%s",NewRoad);
}

知道它很丑,但我被困了好几天。我的代码根据输入的大小有不同的输出。我认为这是因为编译器但不确定。当我尝试 Visual Studio Code 时,输出也不同。

开发 c++ Windows 7:

  1. 输入:www
  2. 输入:xxxx
    输出:“tyza”

开发 c++ Windows 10:

  1. 输入:www
  2. 输入:xxxx
    输出:“tttt”

这没关系,但是当我尝试更长的输入时发生了这种情况。

  1. 输入:35*“w”
  2. 输入:35*"x"
    输出:“uuuttttttttttttttttttttttttttttttz”

另一个问题是:

  1. 输入:w
  2. 输入:b
    输出:“xřb”

任何想法为什么会发生这种情况以及如何解决它?对不起,我是初学者。

【问题讨论】:

  • 在你的帖子中你说当你输入35*"w"时,你没有得到你所期望的。你的意思是你输入了 35 个w 字符?如果是这样,您将大大超出 20 个字符的输入缓冲区。顺便说一句,您的编译器应该就您的 scanf 调用向您发出警告。
  • 是的,我的意思是输入 35 w 个字符。 1.)编译器没有给我任何警告,但如果是的话,很多会被解释。 2.) 我将最大尺寸 s1,s2 设置为 120 并输入 35 w, 35 b。选择 64 位编译器时,输出为:35 x。无论如何,32 位编译器的输出是:bikmpkacgikacgikdfilnmpfilnqhjmpfil + 有 Windows 错误的声音。为什么 ? 3.) 当最大大小 s1,s2 设置为 350 时,为什么程序不能处理大小为 100 个字符的较长输入?该程序甚至不打印输出,它以数字结尾,然后程序结束。为什么 ?我应该怎么做才能摆脱这些问题?
  • 您应该做的第一件事是编辑您的帖子,添加该评论的信息,格式正确。人们可以更轻松地查看帖子中的所有内容,而不是阅读评论对话。
  • "windows 错误声音" 如果您的意思是 IDE 发出声音,好像有错误一样,可能是 IDE 检测到程序的退出值不是零。 main 最终会向调用者返回int,如果返回值不为零,则调用者(可能是 IDE)决定发出声音。如果您的int 函数没有显式返回int,则每个编译器可能有不同的行为。我在您的main 中没有看到return 声明,也没有看到对exit 的调用。
  • 您应该做的另一件事是使用 IDE 的“格式化我的代码以便我可以阅读它”按钮。然后,您可以将其复制到您的帖子中。将其复制到您的帖子后,选择所有文本并按此站点的 {} 编辑器的“逐字格式化我的代码”按钮。

标签: c encryption vigenere


【解决方案1】:

除了您的代码没有向其调用者返回退出值之外,您还有内存管理问题。

如果某些代码没有正确管理内存,您通常可以通过使用valgrind 来找出位置。在将输入数组的大小从 20 更改为 100 后,它对代码的说明如下:

$ cat x
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ gcc -g t.c # more recent versions complain about the `scanf` parameters
$ valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ./a.out <x

==20737== Memcheck, a memory error detector
... lots of lines elided
number of matches:
1212121212121212121212121212121212121212121212121212121212121212121212
... lots of lines elided
len of s1: 35
len of s2: 35
... lots of lines elided
22,23
t
22,23
t
22,23
t
==20737== Conditional jump or move depends on uninitialised value(s)
==20737==    at 0x4E79C7B: vfprintf (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E82AE8: printf (in /usr/lib64/libc-2.18.so)
==20737==    by 0x400E0A: main (t.c:149)
==20737==  Uninitialised value was created by a stack allocation
==20737==    at 0x400C5F: main (t.c:130)
==20737==
==20737== Syscall param write(buf) points to uninitialised byte(s)
==20737==    at 0x4F176B0: __write_nocancel (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EA79E2: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EA8E4B: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EAA9CD: _IO_flush_all_lockp (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EAAB29: _IO_cleanup (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E6A09A: __run_exit_handlers (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E6A134: exit (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E52D6B: (below main) (in /usr/lib64/libc-2.18.so)
==20737==  Address 0x402112a is not stack'd, malloc'd or (recently) free'd
==20737==  Uninitialised value was created by a stack allocation
==20737==    at 0x400C5F: main (t.c:130)
==20737==
22,23
t
22,23
... lots of lines elided
==20737== ERROR SUMMARY: 5 errors from 3 contexts (suppressed: 2 from 2)

有关vfprintf 中条件跳转问题的警告是由来自文件第149 行的printf 的调用引起的,部分原因是您为@987654325 分配内存的方式@。您的代码正在为其分配j 字节,但稍后,在打印NewRoadj 字符后,您的代码正在打印NewRoad,就好像它是一个以null 结尾的字符串一样。但它不是一个以 null 结尾的字符串。

剩下的问题是你没有在 NewRoad[j] 中存储 0。当 printf 尝试将 NewRoad 打印为以空字符结尾的字符串 (%s) 时,它超出了分配给它的内存,这导致了 C 语言未定义的行为。这就是所谓的“未定义行为 (UB)”,这是本网站上不断出现的 C 语言主题。

两个编译器导致不同行为的事实正是为什么 UB 是阴险的。毕竟,这两个编译器是一种语言的两种实现,因此它们可以避免表现不同,因为它们必须在未定义的用例中表现相同。

您可以做的一件事是将 j+1 个字节分配给NewRoad,而不是只分配 j 个字节。然后,在您最后一次修改NewRoad 之后,在您将NewRoad 打印为空终止字符串之前的某个时间,您可以将0 分配给NewRoad[j]

或者,您可以进行更简单的更改,而无需修改分配给NewRoad 的内存量或不必将空终止符存储在字符数组中。这个

printf("\n%s",NewRoad);

变成

printf("\n%.*s", j, NewRoad);

“说”不超过NewRoad 的前j 个字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多