title: rail fence cipher algorithm c
body: <p>i am writing a rail fence cipher algorithm in c for fun and to brush up on my C programming skills. i have it working well for smallish input phrases, but it gets garbled for some reason when the input phrase is large.</p>
  
  <p>here is the code: (sorry, i couldnt reduce it to a SSCCE, i dont know which part of the algorithm is causing the problem)</p>
  
  <pre><code>#include&lt;stdio.h&gt;
  #include&lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  
  /* 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 &lt; 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 &lt; num_rails; i++)
     {
        if ((lines[i] = malloc(sizeof(char))) == NULL)
        {
           printf("\nUnable to allocate memory.\n");
           return EXIT_FAILURE;
        }
     }
  
     for (repeats = 0; repeats &lt; ((word_len/period)+1); repeats++)
     {
        if (repeats*period &lt; word_len)
           append(lines[0], message[repeats*period]);
  
        for (j = 1; j &lt; period/2; j++)
        {
           if ((j + (repeats*period)) &lt; word_len)
              append(lines[j], message[j + (repeats*period)]);
  
           if ((((repeats+1)*period) - j) &lt; word_len)
              append(lines[j], message[((repeats+1)*period) - j]);
        }
  
        if (((period/2) + (repeats*period)) &lt; word_len)
           append(lines[j], message[(period/2)+(repeats*period)]);
     }
  
     char encrypted[word_len];
     strcpy(encrypted,lines[0]);
  
     for (i = 1; i &lt; num_rails; i++)
        strcat(encrypted, lines[i]);
  
     printf("\nciphertext: %s\n", encrypted);
  
     /* decryption */
  
     for (i = 0; i &lt; 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 &lt; num_rails - 1; i++)
        len_rails[i] = len_rails[0] * 2;
  
     for (i = 0; i &lt; mod &amp;&amp; i &lt; num_rails; i++)
     {
        len_rails[i]++;
     }
  
     for (j = i-2; i &lt; mod &amp;&amp; j &gt; -1; j--)
     {
        len_rails[j]++;
        i++;
     }
  
     printf("\nrail lengths:");
     for (i = 0; i &lt; num_rails; i++)
        printf(" %d", len_rails[i]);
  
     putchar('\n');
     k = 0;
  
     for (i = 0; i &lt; num_rails; i++)
     {
        for (j = 0; j &lt; len_rails[i]; j++)
        {
           append(rails[i], encrypted[k++]);
        }
     }
  
     char deciphered[word_len];
     strcpy(deciphered, "");
  
     for (i = 0; i &lt; ((word_len/period)+1); i++)
     {
        if (rails[0][i])
           append(deciphered, rails[0][i]);
  
        for (j = 1; j &lt; 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 &gt; 0; j--)
        {
           if (rails[j][(i*2)+1])
              append(deciphered, rails[j][(i*2)+1]);
        }
     }
  
     printf("\ndeciphered: %s\n", deciphered);
  
     printf("==========================================\n");
     }
  }
  </code></pre>
  
  <p>it should compile and run fine so you can test it.</p>
  
  <p>it is supposed to print the plain text, then encipher it and print that, then decipher the enciphered text back to plain text and print that for 2, 3, 4, 5 rails but it should work for any number of rails.</p>
  
  <p>the problem is that the output gets garbled if the input variable "message" gets over a certain size for different numbers of rails.</p>
  
  <p>eg. </p>
  
  <p>2 rails becomes garbled at 63 characters</p>
  
  <p>3 rails becomes garbled at 64 characters</p>
  
  <p>4 rails becomes garbled at 95 characters</p>
  
  <p>5 rails becomes garbled at 126 characters</p>
  
  <p>etc.</p>
  
  <p>the closest i have been able to come to working out what is wrong is that whenever any value for len_rails[] exceeds 31 the output gets garbled for that amount of rails..</p>
  
  <p>does anyone have any idea why this would be? is it to do with how i am allocating memory? its been a while since i did any C programming and my memory handling is a bit rusty.</p>
  
  <p>any help would be greatly appreciated..</p>