/*
Polyalphabetic substitution: Vigenère-Chiffre
http://www.ogobin.org/home/algorithms/chiffre_poly.php
Operations modes: Repetitive Key, Key Progression, Autoclave
Algorithms: Vigenère
Copyright (C) 2003 Oliver Gobin
Licence type: GNU General Public License
Author: Oliver Gobin <og@ogobin.org>
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char char_shift_int(char c, unsigned int i)
{
char base = 0;
if (i == 0) { return(c); }
if (isupper(c)) { base = 'A'; }
else if (islower(c)) { base = 'a'; }
else { return(c); } // letters only
c -= base;
c = (c + i) % 26 + base;
return(c);
}
char char_shift_char(char c, char c2) {
char base = 0;
char flag_abs = 0;
if (isupper(c)) { base = 'A'; }
else if (islower(c)) { base = 'a'; }
else { return(c); } // letters only
c -= base;
if(c2 < 0) { c2 = abs(c2); flag_abs = 1; }
if (isupper(c2)) { c2 -= 'A'; }
else if (islower(c2)) { c2 -= 'a'; }
else { return(c+base); }
// decoding: P = C - K or P = C + abs(K-26)
if(flag_abs) c2 = abs(c2 -= 26);
c = (c + c2) % 26 + base;
return(c);
}
char *vigenere(char *P, char *K, int mode) {
/*
P Plaintext
K Key
mode == (-)1 Repetitive Key
mode == (-)2 Key Progression
mode == (-)3 Autoclave
^ for decoding
*/
char *C = (char *) malloc(sizeof(char) * strlen(P));
const int k = strlen(K) - 1;
char c;
int k_i = 0;
int i = 0;
unsigned int keyrnd = 0; // for Key Progression Mode
for(i = 0; i < strlen(P); i++) {
switch(mode) {
default:
case -1:
case 1:
c = K[k_i];
break;
case -2:
case 2:
c = char_shift_int(K[k_i], keyrnd);
break;
case 3:
if(i > k) {
c = P[i-k-1];
}
else {
c = K[k_i];
}
break;
case -3:
if(i > k) {
c = C[i-k-1]; // Autoclave decoding: C is the old P!
}
else {
c = K[k_i];
}
break;
}
if(mode < 0) c *= -1; // for decoding, c has to be negative
C[i] = char_shift_char(P[i], c);
k_i++;
if(k_i > k) {
k_i = 0;
keyrnd++;
}
}
return(C);
}
int main(int argc, char *argv[]) {
char *Plaintext = "Hallo Welt, das ist schoen hier!";
char *Chiffre;
char *Key = "test";
strcpy(Chiffre, vigenere(Plaintext, Key, 1));
printf("%s\n", Chiffre);
printf("%s\n", vigenere(Chiffre, Key, -1));
strcpy(Chiffre, vigenere(Plaintext, Key, 2));
printf("%s\n", Chiffre);
printf("%s\n", vigenere(Chiffre, Key, -2));
strcpy(Chiffre, vigenere(Plaintext, Key, 3));
printf("%s\n", Chiffre);
printf("%s\n", vigenere(Chiffre, Key, -3));
return(0);
}