Vigenere table! I did it!

I am just sharing this because I'm proud of figuring it out myself :-)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  #include <iostream>
using namespace std;

int main()
{
    int alpha[26][26];
    for(int i=0; i<26; i++)
    {
        for(int j=0; j<26; j++)
        {
            alpha[i][j]=(i+j)+65;
            if(alpha[i][j]>=91)
            {
                alpha[i][j]-=26;
            }
            cout<<(char) alpha[i][j];
        }
        cout<<endl;
    }
    return 0;
}
Good. Now read about operator %. Would calculating remainder (of something) allow a sightly different solution?
> I'm proud of figuring it out myself :-)

Well done.

Now, consider this: C++ does not specify that the character 'A' must have a value of 65; nor does it specify that the upper case characters in the basic execution character set must have contiguous values.

Other than that a. the null character has a value of zero, b. the value of each character after 0 in the list of decimal digits shall be one greater than the value of the previous, and c. the values of the characters in the basic execution character set are non-negative, "the values are locale specific".

Learning to write robust, portable code is not difficult; unlearning bad programming habits (often encouraged/insisted-on by 'career' teachers) is hard.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>

int main()
{
    constexpr std::size_t N = 26 ;
    std::string alpha[N] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" } ;

    for( std::size_t i = 1 ; i < N ; ++i )
        alpha[i] = alpha[i-1].substr(1) + alpha[i-1][0] ;

    for( const auto& row : alpha ) std::cout << row << '\n' ;
}
I can think of using that by calculating everything in one go and using%26 to break up the line into rows. I'm sure you can use % to calculate the letters more efficiently, but I'm at a loss on how to do that currently. What I don't understand is how to use % when starting the alphabet over, going from z to a.
JLBorges,
The more I look at these forums, the more bad habits I realize that I've been taught. I will look up a couple of things in your code that I'm not familiar with and hopefully learn more. Thank you for your reply!
I can think of using that by calculating everything in one go and using%26 to break up the line into rows. I'm sure you can use % to calculate the letters more efficiently, but I'm at a loss on how to do that currently. What I don't understand is how to use % when starting the alphabet over, going from z to a.


Not nearly as elegant or as bug/error proof as JLBorges' solution.
1
2
3
4
5
6
const int NUM_LETTERS{ 26 };
for( int i{}; i < NUM_LETTERS; i++ ) {
    for( int j{}; j < NUM_LETTERS j++ ) {
        alpha[i][j] = 'A' + (i + j) % NUM_LETTERS;
    }
}
closed account (48T7M4Gy)
Yes, well done OP.
Here's another dimension that might be of interest.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

int main()
{
    char alphabet[26] = {0};
    
    // SETUP ALPHABET ARRAY
    for ( char i = 'A'; i <= 'Z'; i++)
    {
        alphabet[i - 'A'] = i;
    }
    
    // DISPLAY ARRAY CONTENTS
    for ( char i = 'A'; i <= 'Z'; i++)
    {
        std::cout << alphabet[i - 'A'];
    }
    std::cout << '\n';
    
    // TEST A SINGLE CHARACTER
    char test = 'T';
    std::cout << alphabet[test - 'A'] << '\n';
    
    // SET VIGNERE SHIFT (SAY, T -> P, AND DISPLAY ALPHABET)
    int shift = 'T' - 'P' ;
    
    for ( char i = 'A'; i <= 'Z'; i++)
    {
        std::cout << i << " -> " << alphabet[(i - shift + 'A') % 26] << '\n';
    }
    
    return 0;
}
Taking into account what JLBorges said (which I agree with),I'm trying to figure out now how to do a vigenere cipher without the bad programming habits. I'm still not quite understanding the algorithm. I know how to use the table on paper, but coming up with an algorithm and coding it is difficult.
closed account (48T7M4Gy)
1. There are 26 characters, each with an index number in the array between 0 and 25 inclusive
2. Take any plaintext character and find its corresponding index number, i
3. Add the shift number to i to encrypt the plaintext character
4. If the shifted index number is > 25 then subtract 25 ( hence %, modular arithmetic, because the index number must always remain in the 0 to 25 range.
closed account (48T7M4Gy)
http://www.cplusplus.com/forum/beginner/203513/
Topic archived. No new replies allowed.