fork download
  1. #include <ctype.h>
  2. #include <stdio.h>
  3.  
  4. char g_table[25]; // 暗号表
  5. int g_reverse[26]; // 逆変換テーブル
  6.  
  7. char get_table(int x, int y)
  8. {
  9. if (x >= 5) x -= 5;
  10. if (y >= 5) y -= 5;
  11. return g_table[y * 5 + x];
  12. }
  13.  
  14. int main()
  15. {
  16. char keyword[] = "Playfair";
  17. char message[] = "Abandon hope, all ye who enter here.";
  18. char alphabet[] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
  19. char plaintext[100]; // 平文
  20. char *p, c, c1, c2;
  21. int i, pos, x1, y1, x2, y2;
  22.  
  23. // 暗号表の作成
  24. pos = 0;
  25. for (p = keyword; c = toupper(*p); p++) {
  26. for (i = 0; i < pos; i++) {
  27. if (g_table[i] == c) break;
  28. }
  29. if (i == pos) g_table[pos++] = c;
  30. }
  31. for (p = alphabet; c = *p; p++) {
  32. for (i = 0; i < pos; i++) {
  33. if (g_table[i] == c) break;
  34. }
  35. if (i == pos) g_table[pos++] = c;
  36. }
  37.  
  38. // 暗号表の表示
  39. for (i = 0; i < 25; i++) {
  40. printf("%c%c", g_table[i], ((i+1)%5) ? ' ' : '\n');
  41. }
  42.  
  43. // 逆変換テーブルの作成
  44. for (i = 0; i < 25; i++) {
  45. c = g_table[i] - 'A';
  46. g_reverse[c] = i;
  47. }
  48. g_reverse[9] = g_reverse[8]; // J <- I
  49.  
  50. // 逆変換テーブルの表示
  51. for (i = 0; i < 26; i++) {
  52. // printf("%c:%d\n", 'A'+i, g_reverse[i]);
  53. }
  54.  
  55. // メッセージを加工
  56. pos = 0;
  57. for (p = message; c = *p; p++) {
  58. if (!isalpha(c)) continue;
  59. if (pos > 0 && plaintext[pos-1] == c) {
  60. plaintext[pos++] = 'x';
  61. }
  62. plaintext[pos++] = c;
  63. }
  64. if (pos & 1) plaintext[pos++] = 'x';
  65. plaintext[pos] = '\0';
  66.  
  67. printf("[%s]\n", plaintext);
  68.  
  69. // 暗号化
  70. for (p = plaintext; *p; ) {
  71. pos = g_reverse[toupper(*p++) - 'A'];
  72. x1 = pos % 5;
  73. y1 = pos / 5;
  74. pos = g_reverse[toupper(*p++) - 'A'];
  75. x2 = pos % 5;
  76. y2 = pos / 5;
  77. if (x1 == x2) {
  78. // 同じ列の場合
  79. c1 = get_table(x1, y1 + 1);
  80. c2 = get_table(x2, y2 + 1);
  81. } else if (y1 == y2) {
  82. // 同じ行の場合
  83. c1 = get_table(x1 + 1, y1);
  84. c2 = get_table(x2 + 1, y2);
  85. } else {
  86. // 行も列も違う場合
  87. c1 = get_table(x2, y1);
  88. c2 = get_table(x1, y2);
  89. }
  90. printf("%c%c ", c1, c2);
  91. }
  92. printf("\n");
  93.  
  94. return 0;
  95. }
  96.  
Success #stdin #stdout 0.01s 1676KB
stdin
Standard input is empty
stdout
P L A Y F
I R B C D
E G H K M
N O Q S T
U V W X Z
[Abandonhopealxlyewhoenterherex]
BH PQ RT QE NL HP YV AF HU GQ NU NM BG GI KU