Vigenere 密码陷入无限循环

Vigenere cipher runs into infinite loop

我原来有一个凯撒的密码,看起来是这样的:

#include <stdio.h>
#include <string.h>

int main (int argc, char const *argv[])
{
        printf("Insira a frase:\n");
        char frase [256];
        //strcpy(frase, argv[1]);
        scanf("%s", frase);
        int size = (int)strlen(frase);
        printf("Insira o tamanho da divergência: \n");
        int diff = 0;
        scanf("%i", &diff);
        char fraseout [size+1];
        int i = 0;
        for (i = 0; i<=size-1; i++)
        {
                int val = (int)frase[i];
                if (val + diff > 126)
                {
                        while (val + diff >126)
                        {
                                val = 31+diff-(126-val);
                        }
                }
                else if (val + diff < 32)
                {
                        while (val + diff < 32)
                        {
                                val = 127 + diff+(val-32);
                        }
                }
                else
                {
                        val +=diff;
                }
                fraseout [i] = (char)val;
        }
        fraseout[size] = '[=10=]';
        printf("\"%s\" -> \"%s\"\n", frase, fraseout);
        return 0;
}

然后我决定将它变成 Vinegere 的密码,其中每个字符的编码编号由密码给出,并遍历单词的长度。因此,如果我的单词是 "abcde" 并且我的密码是 "zx",则 (char, diff) 对将是 (a,z)(b,x)(c,z)(d,x)。 .. 代码如下所示:

#include <stdio.h>
#include <string.h>

int main(int argc, char const *argv[]) {
        /* code */
        char senha [256];
        if (argv[1] != NULL)
        {
                strcpy(senha, argv[1]);
        }
        char frase [256];
        printf("Insira a frase: \n");
        scanf("%s", frase);
        int sizeS = (int)strlen(senha);
        int sizeF = (int)strlen(frase);
        char fraseout [sizeF+1];
        int i;
        int j;
        for (i=0; i<=sizeF-1; i++)
        {
                if(j>sizeS)
                {
                        j=0;
                }
                int valF = (int)frase[i];
                int valS = (int)senha[i];
                printf(" F = %c = %i \n S = %c = %i\n", frase[i], valF, senha[i], valS);
                if (valF+valS > 126)
                {
                        while (valF+valS >126)
                        {
                                printf("ValF = %i\n", valF);
                                printf("ValS = %i\n", valS);
                                valF = 31 + valS-(valF-126);
                                printf("NewV = %i\n", valF);
                        }
                }
                else if (valF+valS < 32)
                {
                        while (valF+valS<32)
                        {
                                valF = 127 + valS+(valF-32);
                        }
                }
                else
                {
                        valF += valS;
                }
                printf("OUT = %i = %c\n",valF, (char)valF);
                printf("_________________________________\n");
                fraseout[i] = (char)valF;
                j++;
        }
        fraseout[sizeF] = '[=11=]';
        printf("\"%s\" -> \"%s\"\n", frase, fraseout);
        return 0;
}

但是出于某种原因,此代码只是在第一个 while() 语句中进入无限循环,我不明白为什么。我该如何解决这个问题?

我能看到两个问题:

首先,senha[i]应该是senha[j]

其次,if (j > sizeS)应该是if (j >= sizeS)。否则,您将尝试访问 senha[sizeS],其中包含空终止符,而不是字符串中的字符之一。

我认为所有试图处理超出打印范围的字符的代码都可以替换为:

valF = 32 + ((valF - 32) + (valS - 32)) % (128-32);

这个:

while (a + b > 126)
    a = 31 + b - (a-126);

是一个无限循环,当:

a + b = 127  && a < 95    
a + b = 128  && a < 96    
etc.

a + b = 127a = 94 的情况下,对于 a + b,我们得到 127129 的交替值。对于 a = 96,它在 127132 之间交替,第二个值仅在 a 下降或 b 上升时上升。