Question

As the post title suggests, I'm working to strengthen my grasp on C++ and character manipulation, this time through creating a Vigenere Cipher. For those unfamiliar with it, it's a fairly simple way to encrypt a text file.

The basic way it works is that there exists a string "key", and each character (in my case at least) is a lowercase alphabetical character. These are stored into an array and are used to "shift" the value of the file being encoded. A character of 'a' will shift the target by 0, while 'z' will shift it by 25. The "shift" is cyclical, meaning that if 'z' is shifted by 'b' (1) it should result in an 'a'.


My current method is found below:

//Assume cipher[] contains "[a][b][c][x ][y ][z ]" Cipher is a <string> object
//Assume ptr[] contains    "[0][1][2][23][24][25]
#A whole bunch of includes
char c;
ifstream is;
ofstream os;
is.open(argv[3]) //"myinput.txt"
os.open(argv[4])  //"myoutput.txt"

int i = 0;

while( is.good() ) {

    c = is.get();

    if( is.good() ) { //did we just hit the EoF?

        c = tolower( c - 0 ); //just make sure it's lowercase

        c = c + ptr[ i % cipher.size() ] % 26;

        if( c> 122 )
            c = ( c % 123 ) + 97;

        i++;
        os.put( c );
    }
}

My problem lies in my modulo operations, I believe. Maybe it's because I've spent so much time hashing this out, but I spent hours last night writing this, and then another hour lying in bed trying to wrap my mind around how to effectively create what I want:

grab char.
check char.                            //let char = 'z'
check the cipher.                      //let the cipher = 'y'
eval cipher shift                      //'y' shift value = 24
shift z 24 places (cyclically)         //'z'==25, 25+24=49, 49%26=23. 23='x'

HERE IS THE ISSUE: How to do this with ACSII? ('a'=97, z='121')

Was it helpful?

Solution

Imagine that you want to "shuffle" the "ones" digits 0-9 between 20 and 29 by two steps, such that 20 becomes 22, and 29 becomes 21,. How would you do that?

Well, I would subtract 20 [our base number], and then shuffle the remaining digit, and then add 20 back in again.

newnum = num - 20; newnum %= 10; newnum += 20;

The same principle would apply for ascii - just that of course the base isn't 20.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top