Skip to content

Commit 1cf446d

Browse files
[Sync Iteration] c/rail-fence-cipher/1
1 parent b444fde commit 1cf446d

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#include "rail_fence_cipher.h"
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <stddef.h>
5+
6+
char *encode(char *text, size_t rails) {
7+
size_t len = strlen(text);
8+
char *code = malloc(len+1);
9+
if (code == NULL) return NULL;
10+
char **fence = malloc(rails * sizeof(char *));
11+
if (fence == NULL) { free(code); return NULL; }
12+
for (size_t i = 0; i < rails; i++) {
13+
fence[i] = calloc(len + 1, sizeof(char));
14+
if (fence[i] == NULL) {
15+
for (size_t j = 0; j < i; j++) free(fence[j]);
16+
free(fence);
17+
free(code);
18+
return NULL;
19+
}
20+
memset(fence[i], ' ', len);
21+
}
22+
size_t row = 0;
23+
int fence_down = 1;
24+
for (size_t col = 0; col < len; col++) {
25+
char temp = text[col];
26+
fence[row][col] = temp;
27+
if (row == rails - 1 && fence_down == 1) {
28+
fence_down = -1;
29+
}
30+
if (row == 0 && fence_down == -1) {
31+
fence_down = 1;
32+
}
33+
row += fence_down;
34+
}
35+
char *code_write = code;
36+
for (size_t i = 0; i < rails; i++) {
37+
for (size_t j = 0; j < len; j++) {
38+
if (fence[i][j] != ' ') {
39+
*code_write = fence[i][j];
40+
code_write++;
41+
}
42+
}
43+
free(fence[i]);
44+
}
45+
free(fence);
46+
*code_write = '\0';
47+
return code;
48+
}
49+
50+
char *decode(char *code, size_t rails) {
51+
size_t len = strlen(code);
52+
char *text = malloc(len + 1);
53+
if (text == NULL) return NULL;
54+
55+
// a position mark array
56+
int *pos = calloc(len, sizeof(int));
57+
if (pos == NULL) { free(text); return NULL; }
58+
59+
size_t row = 0;
60+
int fence_down = 1;
61+
for (size_t i = 0; i < len; i++) {
62+
pos[i] = row;
63+
if (row == rails - 1 && fence_down == 1) {
64+
fence_down = -1;
65+
}
66+
if (row == 0 && fence_down == -1) {
67+
fence_down = 1;
68+
}
69+
row += fence_down;
70+
}
71+
72+
// group by row
73+
char **groups = malloc(rails * sizeof(char *));
74+
if (groups == NULL) { free(pos); free(text); return NULL; }
75+
int *group_len = calloc(rails, sizeof(int));
76+
if (group_len == NULL) { free(groups); free(pos); free(text); return NULL; }
77+
78+
// calculate length of groups
79+
for (size_t i = 0; i < len; i++) {
80+
group_len[pos[i]]++;
81+
}
82+
83+
// alloc memory
84+
char *code_ptr = code;
85+
for (size_t i = 0; i < rails; i++) {
86+
groups[i] = malloc(group_len[i] + 1);
87+
if (groups[i] == NULL) {
88+
for (size_t j = 0; j < i; j++) free(groups[j]);
89+
free(groups);
90+
free(group_len);
91+
free(pos);
92+
free(text);
93+
return NULL;
94+
}
95+
memcpy(groups[i], code_ptr, group_len[i]);
96+
groups[i][group_len[i]] = '\0';
97+
code_ptr += group_len[i];
98+
}
99+
100+
// decoding
101+
int *group_ptr = calloc(rails, sizeof(int));
102+
if (group_ptr == NULL) {
103+
for (size_t i = 0; i < rails; i++) free(groups[i]);
104+
free(groups);
105+
free(group_len);
106+
free(pos);
107+
free(text);
108+
return NULL;
109+
}
110+
111+
for (size_t i = 0; i < len; i++) {
112+
int r = pos[i];
113+
text[i] = groups[r][group_ptr[r]++];
114+
}
115+
text[len] = '\0';
116+
117+
// free temp heap
118+
for (size_t i = 0; i < rails; i++) free(groups[i]);
119+
free(groups);
120+
free(group_len);
121+
free(group_ptr);
122+
free(pos);
123+
124+
return text;
125+
}
126+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef RAIL_FENCE_CIPHER_H
2+
#define RAIL_FENCE_CIPHER_H
3+
4+
#include <stddef.h>
5+
6+
char *encode(char *text, size_t rails);
7+
8+
char *decode(char *ciphertext, size_t rails);
9+
10+
#endif

0 commit comments

Comments
 (0)