#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 30
// Convert all the characters
// of a string to lowercase
void toLowerCase(char plain[], int ps)
{
int i;
for (i = 0; i < ps; i++) {
if (plain[i] > 64 && plain[i] < 91)
plain[i] += 32;
}
}
// Remove all spaces in a string
// can be extended to remove punctuation
int removeSpaces(char* plain, int ps)
{
int i, count = 0;
for (i = 0; i < ps; i++)
if (plain[i] != ' ')
plain[count++] = plain[i];
plain[count] = '\0';
return count;
}
// generates the 5x5 key square
void generateKeyTable(char key[], int ks,
char keyT[5][5])
{
int i, j, k, flag = 0, *dicty;
// a 26 character hashmap
// to store count of the alphabet
dicty
= (int*)calloc(26, sizeof(int));
for (i = 0; i < ks; i++) {
if (key[i] != 'j')
dicty[key[i] - 97] = 2;
}
dicty['j' - 97] = 1;
i = 0;
j = 0;
for (k = 0; k < ks; k++) {
if (dicty[key[k] - 97] == 2) {
dicty[key[k] - 97] -= 1;
keyT[i][j] = key[k];
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
for (k = 0; k < 26; k++) {
if (dicty[k] == 0) {
keyT[i][j] = (char)(k + 97);
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
}
// Search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a,
char b, int arr[])
{
int i, j;
if (a == 'j')
a = 'i';
else if (b == 'j')
b = 'i';
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (keyT[i][j] == a) {
arr[0] = i;
arr[1] = j;
}
else if (keyT[i][j] == b) {
arr[2] = i;
arr[3] = j;
}
}
}
}
// Function to find the modulus with 5
int mod5(int a)
{
return (a % 5);
}
// Function to decrypt
void decrypt(char str[], char keyT[5][5], int ps)
{
int i, a[4];
for (i = 0; i < ps; i += 2) {
search(keyT, str[i], str[i + 1], a);
if (a[0] == a[2]) {
str[i] = keyT[a[0]][mod5(a[1] - 1)];
str[i + 1] = keyT[a[0]][mod5(a[3] - 1)];
}
else if (a[1] == a[3]) {
str[i] = keyT[mod5(a[0] - 1)][a[1]];
str[i + 1] = keyT[mod5(a[2] - 1)][a[1]];
}
else {
str[i] = keyT[a[0]][a[3]];
str[i + 1] = keyT[a[2]][a[1]];
}
}
}
// Function to call decrypt
void decryptByPlayfairCipher(char str[], char key[])
{
char ps, ks, keyT[5][5];
// Key
ks = removeSpaces(key, ks);
toLowerCase(key, ks);
// ciphertext
toLowerCase(str, ps);
ps = removeSpaces(str, ps);
generateKeyTable(key, ks, keyT);
decrypt(str, keyT, ps);
}
// Driver code
int main()
{
char str[SIZE], key[SIZE];
// Key to be encrypted
printf("Key text: %s\n", key
);
// Ciphertext to be decrypted
printf("Plain text: %s\n", str
);
// encrypt using Playfair Cipher
decryptByPlayfairCipher(str, key);
printf("Deciphered text: %s\n", str
);
return 0;
}
// This code is contributed by AbhayBhat
I2luY2x1ZGUgPHN0ZGlvLmg+IAojaW5jbHVkZSA8c3RkbGliLmg+IAojaW5jbHVkZSA8c3RyaW5nLmg+IAojZGVmaW5lIFNJWkUgMzAgCgovLyBDb252ZXJ0IGFsbCB0aGUgY2hhcmFjdGVycyAKLy8gb2YgYSBzdHJpbmcgdG8gbG93ZXJjYXNlIAp2b2lkIHRvTG93ZXJDYXNlKGNoYXIgcGxhaW5bXSwgaW50IHBzKSAKeyAKCWludCBpOyAKCWZvciAoaSA9IDA7IGkgPCBwczsgaSsrKSB7IAoJCWlmIChwbGFpbltpXSA+IDY0ICYmIHBsYWluW2ldIDwgOTEpIAoJCQlwbGFpbltpXSArPSAzMjsgCgl9IAp9IAoKLy8gUmVtb3ZlIGFsbCBzcGFjZXMgaW4gYSBzdHJpbmcgCi8vIGNhbiBiZSBleHRlbmRlZCB0byByZW1vdmUgcHVuY3R1YXRpb24gCmludCByZW1vdmVTcGFjZXMoY2hhciogcGxhaW4sIGludCBwcykgCnsgCglpbnQgaSwgY291bnQgPSAwOyAKCWZvciAoaSA9IDA7IGkgPCBwczsgaSsrKSAKCQlpZiAocGxhaW5baV0gIT0gJyAnKSAKCQkJcGxhaW5bY291bnQrK10gPSBwbGFpbltpXTsgCglwbGFpbltjb3VudF0gPSAnXDAnOyAKCXJldHVybiBjb3VudDsgCn0gCgovLyBnZW5lcmF0ZXMgdGhlIDV4NSBrZXkgc3F1YXJlIAp2b2lkIGdlbmVyYXRlS2V5VGFibGUoY2hhciBrZXlbXSwgaW50IGtzLCAKCQkJCQljaGFyIGtleVRbNV1bNV0pIAp7IAoJaW50IGksIGosIGssIGZsYWcgPSAwLCAqZGljdHk7IAoKCS8vIGEgMjYgY2hhcmFjdGVyIGhhc2htYXAgCgkvLyB0byBzdG9yZSBjb3VudCBvZiB0aGUgYWxwaGFiZXQgCglkaWN0eSA9IChpbnQqKWNhbGxvYygyNiwgc2l6ZW9mKGludCkpOyAKCglmb3IgKGkgPSAwOyBpIDwga3M7IGkrKykgeyAKCQlpZiAoa2V5W2ldICE9ICdqJykgCgkJCWRpY3R5W2tleVtpXSAtIDk3XSA9IDI7IAoJfSAKCWRpY3R5WydqJyAtIDk3XSA9IDE7IAoKCWkgPSAwOyAKCWogPSAwOyAKCWZvciAoayA9IDA7IGsgPCBrczsgaysrKSB7IAoJCWlmIChkaWN0eVtrZXlba10gLSA5N10gPT0gMikgeyAKCQkJZGljdHlba2V5W2tdIC0gOTddIC09IDE7IAoJCQlrZXlUW2ldW2pdID0ga2V5W2tdOyAKCQkJaisrOyAKCQkJaWYgKGogPT0gNSkgeyAKCQkJCWkrKzsgCgkJCQlqID0gMDsgCgkJCX0gCgkJfSAKCX0gCglmb3IgKGsgPSAwOyBrIDwgMjY7IGsrKykgeyAKCQlpZiAoZGljdHlba10gPT0gMCkgeyAKCQkJa2V5VFtpXVtqXSA9IChjaGFyKShrICsgOTcpOyAKCQkJaisrOyAKCQkJaWYgKGogPT0gNSkgeyAKCQkJCWkrKzsgCgkJCQlqID0gMDsgCgkJCX0gCgkJfSAKCX0gCn0gCgovLyBTZWFyY2ggZm9yIHRoZSBjaGFyYWN0ZXJzIG9mIGEgZGlncmFwaCAKLy8gaW4gdGhlIGtleSBzcXVhcmUgYW5kIHJldHVybiB0aGVpciBwb3NpdGlvbiAKdm9pZCBzZWFyY2goY2hhciBrZXlUWzVdWzVdLCBjaGFyIGEsIAoJCQljaGFyIGIsIGludCBhcnJbXSkgCnsgCglpbnQgaSwgajsgCgoJaWYgKGEgPT0gJ2onKSAKCQlhID0gJ2knOyAKCWVsc2UgaWYgKGIgPT0gJ2onKSAKCQliID0gJ2knOyAKCglmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7IAoJCWZvciAoaiA9IDA7IGogPCA1OyBqKyspIHsgCgkJCWlmIChrZXlUW2ldW2pdID09IGEpIHsgCgkJCQlhcnJbMF0gPSBpOyAKCQkJCWFyclsxXSA9IGo7IAoJCQl9IAoJCQllbHNlIGlmIChrZXlUW2ldW2pdID09IGIpIHsgCgkJCQlhcnJbMl0gPSBpOyAKCQkJCWFyclszXSA9IGo7IAoJCQl9IAoJCX0gCgl9IAp9IAoKLy8gRnVuY3Rpb24gdG8gZmluZCB0aGUgbW9kdWx1cyB3aXRoIDUgCmludCBtb2Q1KGludCBhKSAKeyAKCXJldHVybiAoYSAlIDUpOyAKfSAKCi8vIEZ1bmN0aW9uIHRvIGRlY3J5cHQgCnZvaWQgZGVjcnlwdChjaGFyIHN0cltdLCBjaGFyIGtleVRbNV1bNV0sIGludCBwcykgCnsgCglpbnQgaSwgYVs0XTsgCglmb3IgKGkgPSAwOyBpIDwgcHM7IGkgKz0gMikgeyAKCQlzZWFyY2goa2V5VCwgc3RyW2ldLCBzdHJbaSArIDFdLCBhKTsgCgkJaWYgKGFbMF0gPT0gYVsyXSkgeyAKCQkJc3RyW2ldID0ga2V5VFthWzBdXVttb2Q1KGFbMV0gLSAxKV07IAoJCQlzdHJbaSArIDFdID0ga2V5VFthWzBdXVttb2Q1KGFbM10gLSAxKV07IAoJCX0gCgkJZWxzZSBpZiAoYVsxXSA9PSBhWzNdKSB7IAoJCQlzdHJbaV0gPSBrZXlUW21vZDUoYVswXSAtIDEpXVthWzFdXTsgCgkJCXN0cltpICsgMV0gPSBrZXlUW21vZDUoYVsyXSAtIDEpXVthWzFdXTsgCgkJfSAKCQllbHNlIHsgCgkJCXN0cltpXSA9IGtleVRbYVswXV1bYVszXV07IAoJCQlzdHJbaSArIDFdID0ga2V5VFthWzJdXVthWzFdXTsgCgkJfSAKCX0gCn0gCgovLyBGdW5jdGlvbiB0byBjYWxsIGRlY3J5cHQgCnZvaWQgZGVjcnlwdEJ5UGxheWZhaXJDaXBoZXIoY2hhciBzdHJbXSwgY2hhciBrZXlbXSkgCnsgCgljaGFyIHBzLCBrcywga2V5VFs1XVs1XTsgCgoJLy8gS2V5IAoJa3MgPSBzdHJsZW4oa2V5KTsgCglrcyA9IHJlbW92ZVNwYWNlcyhrZXksIGtzKTsgCgl0b0xvd2VyQ2FzZShrZXksIGtzKTsgCgoJLy8gY2lwaGVydGV4dCAKCXBzID0gc3RybGVuKHN0cik7IAoJdG9Mb3dlckNhc2Uoc3RyLCBwcyk7IAoJcHMgPSByZW1vdmVTcGFjZXMoc3RyLCBwcyk7IAoKCWdlbmVyYXRlS2V5VGFibGUoa2V5LCBrcywga2V5VCk7IAoKCWRlY3J5cHQoc3RyLCBrZXlULCBwcyk7IAp9IAoKLy8gRHJpdmVyIGNvZGUgCmludCBtYWluKCkgCnsgCgljaGFyIHN0cltTSVpFXSwga2V5W1NJWkVdOyAKCgkvLyBLZXkgdG8gYmUgZW5jcnlwdGVkIAoJc3RyY3B5KGtleSwgImNoZWF0ZXIiKTsgCglwcmludGYoIktleSB0ZXh0OiAlc1xuIiwga2V5KTsgCgoJLy8gQ2lwaGVydGV4dCB0byBiZSBkZWNyeXB0ZWQgCglzdHJjcHkoc3RyLCAiWEVOUFpUVk5UWCIpOyAKCXByaW50ZigiUGxhaW4gdGV4dDogJXNcbiIsIHN0cik7IAoKCS8vIGVuY3J5cHQgdXNpbmcgUGxheWZhaXIgQ2lwaGVyIAoJZGVjcnlwdEJ5UGxheWZhaXJDaXBoZXIoc3RyLCBrZXkpOyAKCglwcmludGYoIkRlY2lwaGVyZWQgdGV4dDogJXNcbiIsIHN0cik7IAoKCXJldHVybiAwOyAKfSAKCi8vIFRoaXMgY29kZSBpcyBjb250cmlidXRlZCBieSBBYmhheUJoYXQgCg==