fork(2) download
  1. /* PlayFair chiper */
  2.  
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #define MAXSTR 1000
  9. #define WIDTH 5
  10. #define TABLESIZE 25
  11. #define NLETTER 26
  12. #define ENCRYPTION 1
  13. #define DECRYPTION (WIDTH - ENCRYPTION)
  14.  
  15. char *extract(char *, const char *);
  16. void delX(char *);
  17. char *getpair(char *, const char *);
  18. int lookup(const char *, int);
  19. void makepair(char *, const char *);
  20. void maketable(char *, const char *);
  21. char *playfair(const char *, const char *, int, int);
  22. char *replace(char *, const char *, int);
  23. void replace_all(char *, const char *, int);
  24. int rowcoltochar(const char *, int, int);
  25. void showpair(const char *);
  26. const char *topair(char *, const char *);
  27. void showtable(char *);
  28.  
  29. int main(int argc, char *argv[])
  30. {
  31. char *out = NULL, *out2 = NULL;
  32. printf("<< ENCRYPTION >>\n");
  33. out = playfair("hello, world", "fairplay", ENCRYPTION, 1);
  34. printf("%s\n", out);
  35. printf("\n<< DECRYPTION >>\n");
  36. out2 = playfair(out, "fairplay", DECRYPTION, 1);
  37. printf("%s\n", out2);
  38. free(out);
  39. free(out2);
  40. return 0;
  41. }
  42.  
  43. char *playfair(const char *src, const char *key, int direction, int verbose)
  44. {
  45. char table[TABLESIZE];
  46. char *es = (char *) malloc(strlen(src) + 1);
  47. char *ek = (char *) malloc(strlen(src) + 1);
  48. char *out = NULL;
  49.  
  50. if (direction != ENCRYPTION && direction != DECRYPTION)
  51. goto error;
  52. if (es == NULL || ek == NULL)
  53. goto error;
  54.  
  55. ek = extract(ek, key);
  56. if (verbose)
  57. printf("key:\n%s\n%s\n", key, ek);
  58. maketable(table, key);
  59. if (verbose)
  60. showtable(table);
  61. es = extract(es, src);
  62. if (verbose)
  63. printf("src:\n%s\n%s\n", src, es);
  64. out = (char *) malloc(strlen(es) * 2 + 1);
  65. if (out == NULL)
  66. goto error;
  67. if (direction == ENCRYPTION) {
  68. makepair(out, es);
  69. } else {
  70. strcpy(out, es);
  71. }
  72. if (verbose)
  73. showpair(out);
  74. replace_all(out, table, direction);
  75. if (verbose) {
  76. showpair(out);
  77. fflush(stdout);
  78. }
  79. if (direction == DECRYPTION)
  80. delX(out);
  81. return out;
  82.  
  83. error:
  84. free(ek);
  85. free(es);
  86. free(out);
  87. return NULL;
  88. }
  89.  
  90. void maketable(char *table, const char *key)
  91. {
  92. int i, j;
  93. char used[NLETTER];
  94. static char k[MAXSTR];
  95.  
  96. memset(table, '\0', TABLESIZE);
  97. memset(used, 0, sizeof(used));
  98. used['J' - 'A'] = 1;
  99. extract(k, key);
  100. for (i = 0, j = 0; k[i]; i++) {
  101. int c = (k[i] == 'J') ? 'I' : k[i];
  102. if (used[c - 'A'])
  103. continue;
  104. used[c - 'A'] = 1;
  105. table[j++] = c;
  106. }
  107. for (i = 0; j < TABLESIZE; j++) {
  108. while (used[i])
  109. i++;
  110. table[j] = i++ + 'A';
  111. }
  112. }
  113.  
  114. void showtable(char *table)
  115. {
  116. int i;
  117. for (i = 0; i < TABLESIZE; i++) {
  118. int c = table[i];
  119. if (c == '\0')
  120. c = '.';
  121. printf((i % WIDTH) ? " %c" : "%c", c);
  122. if ((i + 1) % WIDTH == 0)
  123. printf("\n");
  124. }
  125. }
  126.  
  127. char *extract(char *to, const char *from)
  128. {
  129. char *retval = to;
  130. for (; *from; from++)
  131. if (isalpha(*from))
  132. *to++ = toupper(*from);
  133. *to = '\0';
  134. return retval;
  135. }
  136.  
  137. void makepair(char *out, const char *p)
  138. {
  139. while (p = topair(out, p))
  140. out += 2;
  141. out = '\0';
  142. }
  143.  
  144. const char *topair(char *pair, const char *s)
  145. {
  146. if (*s == '\0')
  147. return NULL;
  148. pair[0] = *s++;
  149. if (pair[0] == *s || *s == '\0')
  150. pair[1] = 'X';
  151. else
  152. pair[1] = *s++;
  153.  
  154. return s;
  155. }
  156.  
  157. void showpair(const char *s)
  158. {
  159. int isfirst = 1;
  160. while (*s) {
  161. if (!isfirst)
  162. printf("-");
  163. isfirst = 0;
  164. if (s[1] == '\0') {
  165. /* ありえないと思うが */
  166. printf("%c", s[0]);
  167. s++;
  168. } else {
  169. printf("%c%c", s[0], s[1]);
  170. s += 2;
  171. }
  172. }
  173. printf("\n");
  174. }
  175.  
  176. void replace_all(char *s, const char *table, int dec)
  177. {
  178. while (s[0] && s[1]) {
  179. replace(s, table, dec);
  180. s += 2;
  181. }
  182. }
  183.  
  184. char *replace(char *pair, const char *table, int dec)
  185. {
  186. int i, pos[2], row[2], col[2];
  187. for (i = 0; i < 2; i++) {
  188. pos[i] = lookup(table, pair[i]);
  189. row[i] = pos[i] / WIDTH;
  190. col[i] = pos[i] % WIDTH;
  191. }
  192. if (row[0] == row[1]) {
  193. for (i = 0; i < 2; i++)
  194. col[i] = (col[i] + dec) % WIDTH;
  195. } else if (col[0] == col[1]) {
  196. for (i = 0; i < 2; i++)
  197. row[i] = (row[i] + dec) % WIDTH;
  198. } else {
  199. int tmp = col[0];
  200. col[0] = col[1];
  201. col[1] = tmp;
  202. }
  203. for (i = 0; i < 2; i++)
  204. pair[i] = rowcoltochar(table, row[i], col[i]);
  205. return pair;
  206. }
  207.  
  208. int lookup(const char *table, int c)
  209. {
  210. char *p = strchr(table, c);
  211. return p - table;
  212. }
  213.  
  214. int rowcoltochar(const char *table, int row, int col)
  215. {
  216. return table[row * WIDTH + col];
  217. }
  218.  
  219. void delX(char *s)
  220. {
  221. char *t = s;
  222. while (s[0] && s[1]) {
  223. *t++ = *s++;
  224. if (*s != 'X')
  225. *t++ = *s;
  226. s++;
  227. }
  228. *t = '\0';
  229. }
  230.  
  231. /* END OF FILE */
Success #stdin #stdout 0.01s 2860KB
stdin
Standard input is empty
stdout
<< ENCRYPTION >>
key:
fairplay
FAIRPLAY
F A I R P
L Y B C D
E G H K M
N O Q S T
U V W X Z
src:
hello, world
HELLOWORLD
HE-LX-LO-WO-RL-DX
KG-CU-YN-VQ-FC-CZ
KGCUYNVQFCCZ

<< DECRYPTION >>
key:
fairplay
FAIRPLAY
F A I R P
L Y B C D
E G H K M
N O Q S T
U V W X Z
src:
KGCUYNVQFCCZ
KGCUYNVQFCCZ
KG-CU-YN-VQ-FC-CZ
HE-LX-LO-WO-RL-DX
HELLOWORLD