【问题标题】:rail fence cipher algorithm c围栏密码算法c
【发布时间】:2016-03-02 11:24:06
【问题描述】:

我正在用 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 rails 在 63 个字符处变成乱码

3 rails 在 64 个字符处变成乱码

4 个轨道在 95 个字符处变成乱码

5 个 rails 在 126 个字符处变成乱码

等等

我能够找出问题的最接近的一点是,每当 len_rails[] 的任何值超过 31 时,对于该数量的导轨,输出都会出现乱码。..

有人知道为什么会这样吗?这与我如何分配内存有关吗?自从我做任何 C 编程以来已经有一段时间了,我的内存处理有点生疏了。

任何帮助将不胜感激..

【问题讨论】:

    标签: c algorithm memory-management cryptography


    【解决方案1】:

    在这一行:

    if ((lines[i] = malloc(sizeof(char))) == NULL)
    

    您只是为单个字符分配内存,然后尝试使用缓冲区来存储多个char 的数据。将 sizeof(char)(顺便说一下,始终为 1)乘以您计划存储在数组中的字符数。

    记得在结束前释放()内存。

    【讨论】:

    • 哈哈哈,我是个白痴,对不起,我将它乘以输入长度的一半,它起作用了,再次感谢!
    • 你需要声明一些至少 5*126 大于 600 的字符串数组,所以 ** char input[1024]; ** 等等,这取决于最长的字符串将增长到多大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2014-04-17
    • 1970-01-01
    • 2016-04-14
    • 2015-10-28
    • 2011-10-18
    • 1970-01-01
    相关资源
    最近更新 更多