CFGReader

Japanese 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

This encoding is basically simple at my opinion. As they encode vowels and consonants separately. For vowels,

they use a 6x6 Vigenere Tableau. In order to simplify the question, I choose the same key for both vowels and

consonants. I think Japanese encoding technique is quite primitive compared with most European countries. You

see, this kind of encoding exposes the word pattern with vowels and consonants.

C.The idea of program
¡¡
A E I O U Y
I C D E F A B
N B C D E F A
S A B C D E F
A A B C D E F
N B C D E F A
E E F A B C D
MIFAOUYLDYJXFIFBWXEZIWEEF
CANYOUUNDERSTANDWHATIMEAN
Press any key to continue
¡¡
See this is the 6x6 Vigenere Tableau for vowels. The "key" is "INSANE" and the original text is
¡¡
"can you understand what I mean?" and the encoded string is "MIFAOUYLDYJXFIFBWXEZIWEEF".
¡¡
The last line demonstrate the my decoder works correctly.
¡¡

    D.The major functions

    E.Further improvement

    When I read more about the book.

    F.File listing

    1. JapanCode.cpp (main)

    ¡¡

    ¡¡

    file name: JapanCode.cpp

    #include <iostream>

    using namespace std;

    const int VowelNumber=6;
    enum Letter
    {A,E,I,O,U,Y,B,C,D,F,G,H,J,K,L,M,N,P,Q,R,S,T,V,W,X,Z};

    int vowelIndex[VowelNumber]={A,E,I,O,U,Y};
    char index[26]=
    {
    	'A','E','I','O','U','Y',
    	'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'
    };

    class JapanCode
    {
    private:
    	char vowelVig[VowelNumber][VowelNumber];
    	char vowelCode[VowelNumber];
    	int modulo(int number, int mod);
    	int vCount;//vowel count
    	int cCount;//consonant count
    	bool setCode(const char* codeStr);

    public:
    	JapanCode(char* defaultCode="insane");
    	void translate(char* text, bool encoding=true);
    	void printTable();
    };

    int main()
    {
    	char buffer[256];
    	JapanCode J;
    	strcpy(buffer, "can you understand what I mean?");
    	J.printTable();
    	J.translate(buffer);
    	cout<<buffer<<endl;
    	J.translate(buffer, false);
    	cout<<buffer<<endl;

    	return 0;
    }

    void JapanCode::translate(char* text, bool encoding)
    {
    	char* src=text;
    	char* tgt=text;
    	char ch;
    	int offset=0, vIndex=0, cIndex=0;
    	vCount=cCount=0;
    	while (*src!='\0')
    	{
    		ch=toupper(*src);
    		if (ch>='A'&&ch<='Z')//if it is a letter
    		{
    			for (int i=0; i<26; i++)
    			{
    				if (ch==index[i])
    				{
    					break;//find out the index
    				}
    			}
    			if (i<VowelNumber)//if it is vowel
    			{
    				offset=vCount%VowelNumber;//position
    				offset=(vowelCode[offset]-'A')%VowelNumber;//
    				if (encoding)
    				{
    					offset=(offset+i)%VowelNumber;
    				}
    				else
    				{
    					offset=i-offset;
    					if (offset<0)
    					{
    						offset+=VowelNumber;
    					}
    				}
    				*tgt=index[offset];
    				vCount++;
    				tgt++;
    			}
    			else//if it is consonant
    			{
    				i-=VowelNumber;//the index of consonant
    				offset=cCount%VowelNumber;
    				offset=(vowelCode[offset]-'A')%20;
    				if (encoding)
    				{
    					offset=(offset+i)%20;
    				}
    				else
    				{
    					offset=i-offset;
    					if (offset<0)
    					{
    						offset+=20;
    					}
    				}
    				*tgt=index[offset+VowelNumber];
    				tgt++;
    				cCount++;
    			}
    		}//if it is letter
    		src++;
    	}
    	*tgt='\0';
    }

    int JapanCode::modulo(int number, int mod)
    {
    	int result=number%mod;
    	return result<0?(mod+result):result;
    }

    bool JapanCode::setCode(const char* codeStr)
    {
    	if (strlen(codeStr)!=VowelNumber)
    	{
    		return false;
    	}
    	else
    	{
    		for (int i=0; i<VowelNumber; i++)
    		{
    			vowelCode[i]=toupper(codeStr[i]);
    		}
    	}
    	return true;
    }

    JapanCode::JapanCode(char* defaultCode)
    {
    	int offset=0;
    	if (!setCode(defaultCode))
    	{
    		cout<<"The required code length is "<<VowelNumber<<endl;
    		exit(1);
    	}
    	for (int i=0; i<VowelNumber; i++)
    	{
    		offset=(vowelCode[i]-'A')%VowelNumber;
    		offset=modulo(offset, VowelNumber);

    		for (int j=0; j<VowelNumber; j++)
    		{
    			vowelVig[i][j]='A'+vowelIndex[(j+offset)%VowelNumber];
    		}
    	}
    }

    void JapanCode::printTable()
    {
    	for (int i=0; i<VowelNumber; i++)
    	{
    		cout<<"\t"<<index[i];
    	}
    	cout<<"\n";
    	for (i=0; i<VowelNumber; i++)
    	{
    		cout<<vowelCode[i]<<"\t";
    		for (int j=0; j<VowelNumber; j++)
    		{
    			cout<<vowelVig[i][j]<<"\t";
    		}
    		cout<<"\n";
    	}
    }

    The input is something like following:

    Here is the result: