CFGReader

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.

    B.The problem

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".

¡¡

C.The idea of program
¡¡
Look at the following table of Vigenere, the top row is the plain text and from that row below, each line is
¡¡
a key letter. And each of them shifts by one character.
¡¡
The essence of this kind of encoding is just use a "key" which is arbitrary. Then align the key to plain text so
¡¡
that you will use following formula to find ciphered character: coded = table[cipher, plain] where "plain" is
¡¡
the character to be encoded. The cipher is the "key" letter when you align the key one after another to plain
¡¡
text.
¡¡
For example, key="CIPHER"; plain text ="IAMHEREWHEREAREYOU";
¡¡
To align the key:
¡¡
CIPHERCIPHERCIPHER
IAMHEREWHEREAREYOU
¡¡
¡¡
¡¡
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
A A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
¡¡

    D.The major functions

    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: