【问题标题】:Wrong Encryption for some Words/C某些单词/C的加密错误
【发布时间】:2012-05-09 20:45:31
【问题描述】:

我正在尝试用 C 语言编写一个简单的加密程序。我的目标是将“jim”(可以是任何单词)翻译为 10、9、13。然后加上 1,2,3(因为单词有 3 个字母)并得到 11,12,16 然后再次翻译成文本,然后在屏幕上写 klp。我有 2 个算法,一个用于加密,第二个用于返回第一个。它是工作,但这些话有问题 “编译器可执行通过”当我开始第一个算法然后第二个算法(逆)我采取了。“compileo vou euecrqable throrgh”我检查了几次算法我不知道我忽略了哪里

PS:如果你想运行名为 unencrypted.txt 的 make txt 文件并在其中写入单词,那么第一个算法然后是第二个算法

int main() {
    int g,z,o,c,l,i,j,k,*D;

    char alfabe[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'};
    FILE *fp1;
    FILE *mat;
    char word[20];

    fp1 = fopen("unencrypted.txt","r+");
    do {
        g = fscanf(fp1,"%s",word);
        if (g != EOF) {
            mat=fopen("encrypted.txt","a+");
            c=strlen(word);
            D=(int*)calloc(c,sizeof(int));
            for(i=0;i<c;i++) {
                for(j=0;j<26;j++) {
                    if(word[i]==alfabe[j]) {
                         D[i]=(((j+1)+(i+1))%26);
                         break;
                    }
                }
            }
        }

        for(z=0;z<c;z++){
              o=D[z];
              word[z]=alfabe[o-1];
        }

        for(k=0;k<c;k++) {
           fprintf(mat,"%c",word[k]);
        }
        fprintf(mat," ");
        fclose(mat);

    } while (g != EOF);
    fclose(fp1);
}

int main() {
    int g,z,o,c,l,i,j,k,*D;

    char alfabe[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'};
    FILE *fp1;
    FILE *mat;
    char word[20];

    fp1 = fopen("encrypted.txt","a+");
    do {
        g = fscanf(fp1,"%s",word);
        if (g != EOF) {
            mat=fopen("unencrypted1.txt","a+") ;
            c=strlen(word);
            D=(int*)calloc(c,sizeof(int));
            for(i=0;i<c;i++) {
                for(j=0;j<26;j++) {
                    if(word[i]==alfabe[j]) {
                        if(0>((j+1)-(i+1))){
                            D[i]=((j+1)-(i+1)+26);
                        } else D[i]=((j+1)-(i+1));
                        break;
                    }
                }
            }
        }

        for(z=0;z<c;z++){
            o=D[z];
            word[z]=alfabe[o-1];
        }

        for(k=0;k<c;k++) {
           fprintf(mat,"%c",word[k]);
        }
        fprintf(mat," ");
        fclose(mat);

    } while (g != EOF);
    fclose(fp1);
}

【问题讨论】:

  • 尝试先正确缩进你的代码,这样它才可读。
  • 不,它真的不是很可读,而且缩进被关闭了。

标签: c arrays encryption alphabetical


【解决方案1】:

首先,在您的加密例程中,您可以有未定义的行为:

word[z]=alfabe[o-1];

如果o == 0 访问它不应该访问的内存,如果单词中字符的从 1 开始的索引和字母表中从 1 开始的索引的总和是 26 的倍数,就会发生这种情况。

为避免这种情况,您可以设置word[z] = alfabe[(o+25)%26],或者更简单地说,在前一个循环中省略+1s 之一并使用alfabe[o]

alfabe[-1] 的访问,如果发生,是一种未定义的行为,不太可能导致分段错误或类似的剧烈事情,它可能只会导致在加密字中写入意外字节。

在解密中,你也有类似的问题,

if(0>((j+1)-(i+1))){
    D[i]=((j+1)-(i+1)+26);
} else D[i]=((j+1)-(i+1));

如果单词足够长,即使j - i + 26 也可能是否定的(也就是说,对于自然英文文本来说极不可能 - 在许多其他语言中也是如此)。

同样,D[i] 可能被设置为 0,在这种情况下

for(z=0;z<c;z++){
    o=D[z];
    word[z]=alfabe[o-1];
}

将再次访问 alfabe[-1] 并导致未定义的行为。

另请注意,如果您的输入包含除小写字母和空格(被fscanf 丢弃)之外的任何内容,则D 数组的相应条目包含该内存位置发生的任何字节,再次导致未定义的行为。

如果您的输入仅包含小写字母(和空格),您可以通过设置在字母表中找到索引比使用循环更容易

j = word[i] - 'a';

为避免 alfabe[-1] 问题,我建议使用从 0 开始的索引。

【讨论】:

  • 问题不在第一个算法中。因为当我给你写信时,它返回 wqx .qx 正确,但 w 必须是 z。因为它返回你到 wqx 第二个算法工作错误,我得到你。还是我找不到哪里出错了。 PS:输入只包含小写字母
  • 如果你加密“你”,你就遇到了问题。在i == 0,'y' 在alfabe 中的索引是24,所以D[0] = ((24+1)+(0+1))%26; 将是0。然后o = D[0]; word[0] = alfabe[o-1]; 将访问alfabe[-1]。你从中得到什么字节是相当不可预测的,在这种情况下你得到一个'w',但如果编译器在堆栈上以不同的顺序分配变量,它可能是'0'或'\ n',或者。 ..
  • 我解决了问题。但是很奇怪我改变了 mod26 并像这样 if(26
  • 一点也不奇怪。这是我提到的问题的另一种方式。
猜你喜欢
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 2017-06-12
  • 2013-07-12
  • 2014-05-15
相关资源
最近更新 更多