#include <ctype.h>
#include <stdio.h>
char g_table[25]; // 暗号表
int g_reverse[26]; // 逆変換テーブル
char get_table(int x, int y)
{
if (x >= 5) x -= 5;
if (y >= 5) y -= 5;
return g_table[y * 5 + x];
}
int main()
{
char keyword[] = "Playfair";
char message[] = "Abandon hope, all ye who enter here.";
char alphabet[] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
char plaintext[100]; // 平文
char *p, c, c1, c2;
int i, pos, x1, y1, x2, y2;
// 暗号表の作成
pos = 0;
for (p
= keyword
; c
= toupper(*p
); p
++) { for (i = 0; i < pos; i++) {
if (g_table[i] == c) break;
}
if (i == pos) g_table[pos++] = c;
}
for (p = alphabet; c = *p; p++) {
for (i = 0; i < pos; i++) {
if (g_table[i] == c) break;
}
if (i == pos) g_table[pos++] = c;
}
// 暗号表の表示
for (i = 0; i < 25; i++) {
printf("%c%c", g_table
[i
], ((i
+1)%5) ? ' ' : '\n'); }
// 逆変換テーブルの作成
for (i = 0; i < 25; i++) {
c = g_table[i] - 'A';
g_reverse[c] = i;
}
g_reverse[9] = g_reverse[8]; // J <- I
// 逆変換テーブルの表示
for (i = 0; i < 26; i++) {
// printf("%c:%d\n", 'A'+i, g_reverse[i]);
}
// メッセージを加工
pos = 0;
for (p = message; c = *p; p++) {
if (pos > 0 && plaintext[pos-1] == c) {
plaintext[pos++] = 'x';
}
plaintext[pos++] = c;
}
if (pos & 1) plaintext[pos++] = 'x';
plaintext[pos] = '\0';
// 暗号化
for (p = plaintext; *p; ) {
pos
= g_reverse
[toupper(*p
++) - 'A']; x1 = pos % 5;
y1 = pos / 5;
pos
= g_reverse
[toupper(*p
++) - 'A']; x2 = pos % 5;
y2 = pos / 5;
if (x1 == x2) {
// 同じ列の場合
c1 = get_table(x1, y1 + 1);
c2 = get_table(x2, y2 + 1);
} else if (y1 == y2) {
// 同じ行の場合
c1 = get_table(x1 + 1, y1);
c2 = get_table(x2 + 1, y2);
} else {
// 行も列も違う場合
c1 = get_table(x2, y1);
c2 = get_table(x1, y2);
}
}
return 0;
}
I2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKY2hhciBnX3RhYmxlWzI1XTsJLy8g5pqX5Y+36KGoCmludCBnX3JldmVyc2VbMjZdOwkvLyDpgIblpInmj5vjg4bjg7zjg5bjg6sKCmNoYXIgZ2V0X3RhYmxlKGludCB4LCBpbnQgeSkKewoJaWYgKHggPj0gNSkgeCAtPSA1OwoJaWYgKHkgPj0gNSkgeSAtPSA1OwoJcmV0dXJuIGdfdGFibGVbeSAqIDUgKyB4XTsKfQoKaW50IG1haW4oKQp7CgljaGFyIGtleXdvcmRbXSA9ICJQbGF5ZmFpciI7CgljaGFyIG1lc3NhZ2VbXSA9ICJBYmFuZG9uIGhvcGUsIGFsbCB5ZSB3aG8gZW50ZXIgaGVyZS4iOwoJY2hhciBhbHBoYWJldFtdID0gIkFCQ0RFRkdISUtMTU5PUFFSU1RVVldYWVoiOwoJY2hhciBwbGFpbnRleHRbMTAwXTsJLy8g5bmz5paHCgljaGFyICpwLCBjLCBjMSwgYzI7CglpbnQgaSwgcG9zLCB4MSwgeTEsIHgyLCB5MjsKCgkvLyDmmpflj7fooajjga7kvZzmiJAKCXBvcyA9IDA7Cglmb3IgKHAgPSBrZXl3b3JkOyBjID0gdG91cHBlcigqcCk7IHArKykgewoJCWZvciAoaSA9IDA7IGkgPCBwb3M7IGkrKykgewoJCQlpZiAoZ190YWJsZVtpXSA9PSBjKSBicmVhazsKCQl9CgkJaWYgKGkgPT0gcG9zKSBnX3RhYmxlW3BvcysrXSA9IGM7Cgl9Cglmb3IgKHAgPSBhbHBoYWJldDsgYyA9ICpwOyBwKyspIHsKCQlmb3IgKGkgPSAwOyBpIDwgcG9zOyBpKyspIHsKCQkJaWYgKGdfdGFibGVbaV0gPT0gYykgYnJlYWs7CgkJfQoJCWlmIChpID09IHBvcykgZ190YWJsZVtwb3MrK10gPSBjOwoJfQoKCS8vIOaal+WPt+ihqOOBruihqOekugoJZm9yIChpID0gMDsgaSA8IDI1OyBpKyspIHsKCQlwcmludGYoIiVjJWMiLCBnX3RhYmxlW2ldLCAoKGkrMSklNSkgPyAnICcgOiAnXG4nKTsKCX0KCgkvLyDpgIblpInmj5vjg4bjg7zjg5bjg6vjga7kvZzmiJAKCWZvciAoaSA9IDA7IGkgPCAyNTsgaSsrKSB7CgkJYyA9IGdfdGFibGVbaV0gLSAnQSc7CgkJZ19yZXZlcnNlW2NdID0gaTsKCX0KCWdfcmV2ZXJzZVs5XSA9IGdfcmV2ZXJzZVs4XTsJLy8gSiA8LSBJCgoJLy8g6YCG5aSJ5o+b44OG44O844OW44Or44Gu6KGo56S6Cglmb3IgKGkgPSAwOyBpIDwgMjY7IGkrKykgewovLwkJcHJpbnRmKCIlYzolZFxuIiwgJ0EnK2ksIGdfcmV2ZXJzZVtpXSk7Cgl9CgoJLy8g44Oh44OD44K744O844K444KS5Yqg5belCglwb3MgPSAwOwoJZm9yIChwID0gbWVzc2FnZTsgYyA9ICpwOyBwKyspIHsKCQlpZiAoIWlzYWxwaGEoYykpIGNvbnRpbnVlOwoJCWlmIChwb3MgPiAwICYmIHBsYWludGV4dFtwb3MtMV0gPT0gYykgewoJCQlwbGFpbnRleHRbcG9zKytdID0gJ3gnOwoJCX0KCQlwbGFpbnRleHRbcG9zKytdID0gYzsKCX0KCWlmIChwb3MgJiAxKSBwbGFpbnRleHRbcG9zKytdID0gJ3gnOwoJcGxhaW50ZXh0W3Bvc10gPSAnXDAnOwoKCXByaW50ZigiWyVzXVxuIiwgcGxhaW50ZXh0KTsKCgkvLyDmmpflj7fljJYKCWZvciAocCA9IHBsYWludGV4dDsgKnA7ICkgewoJCXBvcyA9IGdfcmV2ZXJzZVt0b3VwcGVyKCpwKyspIC0gJ0EnXTsKCQl4MSA9IHBvcyAlIDU7CgkJeTEgPSBwb3MgLyA1OwoJCXBvcyA9IGdfcmV2ZXJzZVt0b3VwcGVyKCpwKyspIC0gJ0EnXTsKCQl4MiA9IHBvcyAlIDU7CgkJeTIgPSBwb3MgLyA1OwoJCWlmICh4MSA9PSB4MikgewoJCQkvLyDlkIzjgZjliJfjga7loLTlkIgKCQkJYzEgPSBnZXRfdGFibGUoeDEsIHkxICsgMSk7CgkJCWMyID0gZ2V0X3RhYmxlKHgyLCB5MiArIDEpOwoJCX0gZWxzZSBpZiAoeTEgPT0geTIpIHsKCQkJLy8g5ZCM44GY6KGM44Gu5aC05ZCICgkJCWMxID0gZ2V0X3RhYmxlKHgxICsgMSwgeTEpOwoJCQljMiA9IGdldF90YWJsZSh4MiArIDEsIHkyKTsKCQl9IGVsc2UgewoJCQkvLyDooYzjgoLliJfjgoLpgZXjgYbloLTlkIgKCQkJYzEgPSBnZXRfdGFibGUoeDIsIHkxKTsKCQkJYzIgPSBnZXRfdGFibGUoeDEsIHkyKTsKCQl9CgkJcHJpbnRmKCIlYyVjICIsIGMxLCBjMik7Cgl9CglwcmludGYoIlxuIik7CgoJcmV0dXJuIDA7Cn0K