Vigenere encoding
A. First Edition
This is a quite simple demo of what I read from book <battle of wits> which described the code-breaking war in
world war II.
Encoding can be as early as in Roman times, it said in "discrete mathematics" text book that Caesar encoded his
message to his general with a very simple "shift". The idea is simple but I think it is the essential of
encoding. The real problem is how to shift. No matter how complicated calculating formula you might use for each
character to shift. Nevertheless, the rule for each character is fixed. A simple statistic frequency of each
character in English language will reveal the secret. Therefore, encoded character MUST show different "face"
in same message. For example, the message "I am here" contains two "e"'s. In ciphered text, two "e" should be
different letters. Otherwise, no matter what kind of permutation or combination you make for the message. The
frequency of "showing-up" will reveal that cipher character is "e".
E.Further improvement
When I read more about the book.
F.File listing
1. vigenere.cpp (main)
file name: 24revisited.cpp
#include <iostream> using namespace std; class Vigenere { private: int* key; int keyLen; bool validateKey(const char* theKey); void run(const char* text, char* target, bool encoding=true); public: void setKey(const char* theKey); void printTable(); void encode(char* text, char* coded); void decode(const char* text, char* decoded); }; int main() { char buffer[256]; char message[256]; char text[256]; strcpy(text, "I am here"); Vigenere V; V.setKey("xyz"); //V.printTable(); V.encode(text, buffer); cout<<buffer<<endl; V.decode(buffer, message); cout<<message<<endl; return 0; } void Vigenere::encode(char* text, char* coded) { char* pt=text, *ps=text; while (*ps!='\0') { if (!isalpha(*ps)) { ps++; } else { *pt=toupper(*ps); ps++; pt++; } } *pt='\0'; run(text, coded, true); } void Vigenere::decode(const char* text, char* decoded) { run(text, decoded, false); } //just make sure the length of key won't exceed 26 //make sure the letter in key won't repeat bool Vigenere::validateKey(const char*theKey) { /* bool chUsed[26]; int theLen; theLen=strlen(theKey); if (theLen>26) { cout<<"the key is too long\n"; return false; } for (int i=0; i<26; i++) { chUsed[i]=false; } for (i=0; i<theLen; i++) { char ch=toupper(theKey[i]); if (chUsed[ch-'A']) { return false; } else { chUsed[ch-'A']=true; } } */ return true; } void Vigenere::setKey(const char* theKey) { int i=0; if (validateKey(theKey)) { keyLen=strlen(theKey); key=new int[keyLen]; while (theKey[i]!='\0') { key[i]=toupper(theKey[i])-'A'; i++; } } } void Vigenere::printTable() { for (int i=0; i<26; i++) { if (i==0) { cout<<" "; for (int j=0; j<26; j++) { cout<<" "<<(char)('A'+j); } } cout<<"\n"; cout<<(char)('A'+i); for (int j=0; j<26; j++) { cout<<" "<<(char)('A'+(j+i)%26); } cout<<"\n"; } cout<<"\n"; } void Vigenere::run(const char* text, char* target, bool encoding) { int index=0; int keyIndex; while (text[index]!='\0') { /* if (!isalpha(text[index])) { if (encoding) { index++; continue; } else { cout<<"corrupted coding!\n"; exit(1); } } */ char ch=text[index];//it must be in capital case keyIndex=index%keyLen; if (encoding) { target[index]=(char)('A'+(ch-'A'+key[keyIndex])%26); } else { if (ch-'A'-key[keyIndex]>=0) { target[index]=(char)('A'+ ch-'A'-key[keyIndex]); } else { target[index]=(char)('A'+26+ch-'A'-key[keyIndex]); } } index++; } target[index]='\0'; }
The input is something like following:
Here is the result: