Vigenere Cipher w/o using ascii Codes :-)

I finally got it! It's extremely messy, but I did a vigenere cipher without using ASCII codes! w00t!
I was told on another post that using the ascii codes for this sort of thing was bad form, so here it is without it. My only real question is how do deal with spaces and punctuation? I'd prefer to strip them from the input string altogether. Right now I know it works with no spaces or punctuation.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  #include <iostream>
#include <string>
#include <cctype>
using namespace std;

string inmsg, key, enkey, cipher;
string alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int msglen, keylen, mIndex[100], kIndex[100], cIndex[100];

void getmsg()
{
    int i, x, j;
    cout<<"Enter the message: ";
    getline(cin, inmsg);
    msglen=inmsg.length();
    for(j=0;j<msglen;j++)
    {
        inmsg[j] = toupper(inmsg[j]);
    }
    for(i=0;i<msglen;i++)
    {
        x=0;
        while(inmsg[i] != alpha[x])
        {
            x++;
        }
        mIndex[i] = x;
    }
}

void getkey()
{
    int i, j, x;
    cout<<"Enter the key: ";
    cin>>key;
    cin.ignore();
    keylen=key.length();
    enkey=inmsg;
    for(i=0; i<msglen; i++)
    {
        enkey[i]=key[i%keylen];
    }
    
    for(int k=0;k<msglen;k++)
    {
        enkey[k] = toupper(enkey[k]);
    }
    for(j=0;j<msglen;j++)
    {
        x=0;
        while(enkey[j] != alpha[x])
        {
            x++;
        }
        kIndex[j] = x;
    }
}
void encrypt()
{
    getmsg();
    getkey();
    cipher=inmsg;
    int x;
    /*** Do Cipher ***/
    cout<<"\nCipher: \n";
    for(int i=0;i<msglen;i++)
    {
        cIndex[i]=(mIndex[i]+kIndex[i])%26;
        x = cIndex[i];
        cipher[i] = alpha[x];
    }
    cout<<cipher;
}

void decrypt()
{
    getmsg();
    getkey();
    cipher=inmsg;
    int x;
    /*** Do Decipher ***/
    cout<<"\nDeciphered: \n";
    for(int i=0;i<msglen;i++)
    {
        cIndex[i]=(mIndex[i]-kIndex[i])%26;
        x = cIndex[i];
        cipher[i] = alpha[x];
    }
    cout<<cipher;
}

int main()
{
    int choice;
    cout<<"\tVigenere Cipher\n";
    cout<<"1. Encrypt"<<endl;
    cout<<"2. Decrypt"<<endl;
    cout<<"Enter choice: ";
    cin>>choice;
    cin.ignore();
    switch(choice)
    {
        case 1:
        encrypt();
        break;
        
        case 2:
        decrypt();
        break;
    }
}
closed account (48T7M4Gy)
http://www.cplusplus.com/forum/beginner/203399/
> I did a vigenere cipher without using ASCII codes! w00t!

Well done, again!


> how do deal with spaces and punctuation?


One option is to leave the non-alpha characters unchanged.
For instance, using a Vigenère table and facilities in the standard library:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <string>
#include <cctype>
#include <array>

// alphabet is the set of upper case alpha characters in the basic execution character set
constexpr std::size_t N = 26 ;
const std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
using table_type = std::array< std::string, N > ; // the table is an array of N strings

// position of c in the alphabet. case-insensitive.
std::size_t pos( char c ) { return alphabet.find( std::toupper(c) ) ; }

table_type make_table()
{
    table_type table ;

    for( std::size_t i = 0 ; i < N ; ++i )
        table[i] = alphabet.substr(i) + alphabet.substr(0,i) ;

    return table ;
}

char encode( char key, char plaintext )
{
    static const table_type table = make_table() ;

    if( std::isalpha(key) && std::isalpha(plaintext) ) // is alphabetic
        return table[ pos(key) ][ pos(plaintext) ] ; // encode

    else return plaintext ; // leave non alpha characters as they are
}

std::string encode( std::string key, std::string plaintext )
{
    while( key.size() < plaintext.size() ) key += key ;

    std::string cyphertext ;

    for( std::size_t i = 0 ; i < plaintext.size() ; ++i )
        cyphertext += encode( key[i], plaintext[i] ) ;

    return cyphertext ;
}

// TO DO: decode

int main()
{
    const std::string key = "Vigenere" ;
    const std::string plaintext = "I finally got it!\nIt's extremely messy, but I did"
                                  " a vigenere cipher without using ASCII codes!\nw00t!" ;
    const std::string cyphertext = encode( key, plaintext ) ;

    std::cout << plaintext << "\n\n" << cyphertext << '\n' ;
}

http://coliru.stacked-crooked.com/a/8d5ebf330a40e3dd


Another option is to include non-alpha characters in the alphabet.
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>
#include <vector>
#include <cctype>

// alphabet is what we define it to be: adjust as required
const std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ \t\n!,.:(){}[]\"<>/?" ;
using table_type = std::vector<std::string> ; // the table is a vector of strings

// position of c in the alphabet. case-insensitive.
std::size_t pos( char c ) { return alphabet.find( std::toupper(c) ) ; }

bool is_in_alphabet( char a, char b )
{ return pos(a) != std::string::npos && pos(b) != std::string::npos ; }

table_type make_table()
{
    table_type table ;

    for( std::size_t i = 0 ; i < alphabet.size() ; ++i )
        table.push_back( alphabet.substr(i) + alphabet.substr(0,i) ) ;

    return table ;
}

char encode( char key, char plaintext )
{
    static const table_type table = make_table() ;

    if( is_in_alphabet( key, plaintext ) ) // part of alphabet
        return table[ pos(key) ][ pos(plaintext) ] ; // encode

    else return plaintext ; // leave unknown characters as they are
}

std::string encode( std::string key, std::string plaintext )
{
    while( key.size() < plaintext.size() ) key += key ;

    std::string cyphertext ;

    for( std::size_t i = 0 ; i < plaintext.size() ; ++i )
        cyphertext += encode( key[i], plaintext[i] ) ;

    return cyphertext ;
}

// TO DO: decode

int main()
{
    const std::string key = "Vigenere cipher" ;
    const std::string plaintext = "I finally got it!\nIt's extremely messy, but I did"
                                  " a vigenere cipher without using ASCII codes!\nw00t!" ;
    const std::string cyphertext = encode( key, plaintext ) ;

    std::cout << plaintext << "\n\n" << cyphertext << '\n' ;
}

http://coliru.stacked-crooked.com/a/eb48afe100ec3a12
JLBorges,
Thanks for the suggestions! I'm trying to relearn and practice as much as possible for this data structures class next semester.
Topic archived. No new replies allowed.