我正在用 C 语言编写一个铁路围栏密码算法,目的是为了好玩并复习我的 C 编程技能。我让它适用于较小的输入短语,但当输入短语较大时,由于某种原因它会出现乱码。
这是代码:(抱歉,我无法将其简化为 SSCCE,我不知道算法的哪一部分导致了问题)
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
/* function to append a char to a char array */
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main(void)
{
int num_rails;
for (num_rails = 2; num_rails < 6; num_rails++)
{
char* message = "therailfencecipheristrickyespeciallywhentheinputisverylongabcdefghijklmnopqrstuvwxyzblerpblorp";
int word_len = strlen(message);
char* lines[num_rails];
char* rails[num_rails];
int len_rails[num_rails];
memset(len_rails, 0, num_rails*sizeof(int));
int i,j,k,mod;
int repeats;
int period = (2*num_rails) - 2;
printf("%d characters, %d rails:\n", word_len, num_rails);
printf("\nplaintext: %s\n", message);
/* encryption */
for (i = 0; i < num_rails; i++)
{
if ((lines[i] = malloc(sizeof(char))) == NULL)
{
printf("\nUnable to allocate memory.\n");
return EXIT_FAILURE;
}
}
for (repeats = 0; repeats < ((word_len/period)+1); repeats++)
{
if (repeats*period < word_len)
append(lines[0], message[repeats*period]);
for (j = 1; j < period/2; j++)
{
if ((j + (repeats*period)) < word_len)
append(lines[j], message[j + (repeats*period)]);
if ((((repeats+1)*period) - j) < word_len)
append(lines[j], message[((repeats+1)*period) - j]);
}
if (((period/2) + (repeats*period)) < word_len)
append(lines[j], message[(period/2)+(repeats*period)]);
}
char encrypted[word_len];
strcpy(encrypted,lines[0]);
for (i = 1; i < num_rails; i++)
strcat(encrypted, lines[i]);
printf("\nciphertext: %s\n", encrypted);
/* decryption */
for (i = 0; i < num_rails; i++)
{
if ((rails[i] = malloc(sizeof(int) * 40)) == NULL)
{
printf("\nUnable to allocate memory.\n");
return EXIT_FAILURE;
}
}
mod = word_len % period;
len_rails[0] = word_len / period;
len_rails[num_rails-1] = len_rails[0];
for (i = 1; i < num_rails - 1; i++)
len_rails[i] = len_rails[0] * 2;
for (i = 0; i < mod && i < num_rails; i++)
{
len_rails[i]++;
}
for (j = i-2; i < mod && j > -1; j--)
{
len_rails[j]++;
i++;
}
printf("\nrail lengths:");
for (i = 0; i < num_rails; i++)
printf(" %d", len_rails[i]);
putchar('\n');
k = 0;
for (i = 0; i < num_rails; i++)
{
for (j = 0; j < len_rails[i]; j++)
{
append(rails[i], encrypted[k++]);
}
}
char deciphered[word_len];
strcpy(deciphered, "");
for (i = 0; i < ((word_len/period)+1); i++)
{
if (rails[0][i])
append(deciphered, rails[0][i]);
for (j = 1; j < num_rails-1; j++)
{
if (rails[j][i*2])
append(deciphered, rails[j][i*2]);
}
if (rails[num_rails-1][i])
append(deciphered, rails[num_rails-1][i]);
for (j = num_rails-2; j > 0; j--)
{
if (rails[j][(i*2)+1])
append(deciphered, rails[j][(i*2)+1]);
}
}
printf("\ndeciphered: %s\n", deciphered);
printf("==========================================\n");
}
}
它应该可以正常编译和运行,以便您可以对其进行测试。
它应该打印纯文本,然后加密并打印,然后将加密文本解密回纯文本并打印 2、3、4、5 条导轨,但它应该适用于任意数量的导轨。
问题是如果输入变量“message”对于不同数量的导轨超过一定大小,输出会出现乱码。
例如。
2 条导轨在 63 个字符时变成乱码
3 轨在 64 个字符时变成乱码
4 个导轨在 95 个字符时变成乱码
5 条导轨在 126 个字符时变成乱码
等等
我能够得出的最接近的错误是,每当 len_rails[] 的任何值超过 31 时,该数量的导轨的输出就会出现乱码..
有人知道为什么会这样吗?这与我分配内存的方式有关吗?我已经有一段时间没有进行任何 C 编程了,我的内存处理有点生疏。
任何帮助将不胜感激..
最佳答案
在这一行:
if ((lines[i] = malloc(sizeof(char))) == NULL)
您只为单个字符分配内存,但随后尝试使用缓冲区存储多于一个 char
的数据。将 sizeof(char)
(顺便说一下,它始终为 1)乘以您计划存储在数组中的字符数。
记得在结束前释放内存。
关于c - 围栏密码算法c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22573871/