Vigenere Cipher

Hi

Any idea how I could make a Vigenere cipher to only use ascii characters ranging rom 32 to 126 ?

So if I pass the encode function a 'T', how could I encode that ?

Thanks
A Vigenere cipher is more in-depth Caesar cipher in that it the amount of shifting is variable (edit: per index).

Do you know how to make a Caesar cipher? If so, a Vigenere cipher is similar, but you need to keep track of which position you are in your key.

e.g.
Caesar cipher:
plaintext: ABCDEF
key: A (1) (or 0 depending on your notation)
ciphertext: BCDEFG

Vigenere cipher:
plaintext: ABCDEF
key: AB (1, 2) [You repeat the key over the plaintext]
ciphertext: BDDFFH

Last edited on
I understand the concept of the cipher and how it works but no idea how to code it. I do not know the Caesar cipher but I will do some research.

I have 2 functions, one that takes in a char and converts it and then that function gets used in a second function which takes in a string and then I somehow need to step through the string and use the char encoder to encode each char in the string.

eg:
charEncoder(char)

encoder(string)
-call charEncoder() on each loop cycle

Assuming my concept is legit.

Hope that makes sense ?
probably just want lookup tables.

eg:

char lookup[] = {1,2,3};
for(i= ... in.length()... etc)
output[i] = in[i]+lookup[i%3]; //3 is the size of the lookup array ... do you understand this?

abcd would be
bdfe (a+1, b+2, c+3, d+1, ...)

if lookup is long and irregular it should be pretty well scrambled, but you can break these easily if you see what it is from the data, just put in "aaaaaaaaaaaaaaaaaaaaaaaaaa" and it will tell you the cipher (lookup) used.
Last edited on
I find it perplexing that you know of the vigenere cipher but not the caesar cipher. But anyways...

step through the string and use the char encoder to encode each char in the string.

if you have an std::string, you can do this easily with a for loop

1
2
3
4
5
6
std::string my_string = "test";
for (char& ch : my_string)
{
    std::cout << ch << " ";
    ch = encode(...);
}


Your charEncoder function seems like it needs more information, it needs to know how it's being encoded.

For example,

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
// Example program
#include <iostream>
#include <string>

// Actual mathematical modular arithmetic
// (-1) % N == N - 1
int mod(int a, int m)
{
    return (m + (a%m)) % m;
}

// letter should be an ascii value from 32 to 126, inclusive.
// wraps values over 126 or under 32 back around.
// (e.g.  32 - 1 == 126)
// (e.g. 126 + 1 ==   0)
char charEncoder(char letter, int shift)
{
    const int lo =  32;
    const int hi = 126;
    const int range = hi - lo + 1;
    
    return mod(letter + shift - lo, range) + lo;
}

int main()
{
    // example numbers
    std::cout << (int)charEncoder(32,  -1) << "\n";
    std::cout << (int)charEncoder(100,  0) << "\n";
    std::cout << (int)charEncoder(126, +1) << "\n";
}


but you can break these easily if you see what it is from the data, just put in "aaaaaaaaaaaaaaaaaaaaaaaaaa" and it will tell you the cipher (lookup) used.

Most of these types of ciphers assume that you cannot do a known-plaintext attack to "test" it. You're usually only given the ciphertext that you can't control. But you're right, although it should be obvious these ciphers should be for educational purposes only, as they can be cracked almost instantly (even without known-plaintext).
Last edited on
The only reason I even know about the Vigenere cipher is because I have to use it as well as one time pad, but I see the caesar cipher is just moving each character one unit. So if i have 'a' it becomes 'b' and so on - assuming the shift was positive.

Your charEncoder function seems like it needs more information, it needs to know how it's being encoded.

Here is the exact wording and obviously the decryption would be the opposite process:

this function implements Vigenére encoding. A plaintext char is
received as input and shifted according to the current place in the codeword. The shifted
char is returned. No error-checking has to be done in this function.

Is your for loop c++ 11?
my loop was just pseudo code. It also may not be right, i don't know the cipher, I thought he was saying add a fixed value based to each letter based off its position (which I did) ... if there is more to it, I didn't show that --- it may need a second modulus if you want to wrap around after z back to a. c++ isnt quite there yet on translating "for (yadda yadda)" into what it thinks you meant. But it does interest me what would happen if someday compilers could actually fix syntax errors for you as they go (correcting the program text alongside it, and marking it for human review). AI and computer speeds are getting close to doing that, if someone took a notion to make it happen...

Last edited on
jonnin, what I showed is the standard vigenere cipher, which uses a specified key.
https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
See the example with key "LEMONLEMONLE".

OP's version sounds like it's a restrictive subset of the Vigenere cipher, which has the key essentially always being [1, 2, 3, 4, 5.... 26, 1, 2, 3, 4, 5, ...] or something along those lines. (the wording here is kinda ambiguous as to whether it should repeat every 26 letters or every (126-32+1) characters)

A plaintext char is received as input and shifted according to the current place in the codeword

To me, that's ambiguous. Is my interpretation that a shift of 127 is equivalent to a shift of 0 correct? Did they provide you an example?

Anyway, this doesn't seem to be going anywhere, I'd prefer if you show us some actual code if you want help, unless it's the concept of the Vigenere cipher itself that you're confused about (If so, I can give a more in-depth example of the standard Vigenere cipher).
Last edited on
Sorry jonnin, I was referring to Ganado's for loop as I've never seen that syntax before, so sorry about that.

But I quite like that idea of the compiler being able to fix errors. It's an interesting concept and I'm sure someone somewhere is working on a solution to that thought.
Ganado they did.

So if you have ascii code 125 and you add 3 to it, it'll go from '}' to '!'.

I'm busy working out the code to that takes in the char and converts it. I've finished the function which makes use of the encodeChar function. Just trying to work out how to compare the codeword or key to each char and then move to the next char in the codeword.

But here is the function that uses the encodeChar function:
1
2
3
4
5
6
7
8
string SubstitutionCipher::encode(string const &enc) {
    string enc_string;
    for (int i = 0; i < enc_string.length(); ++i) {
        enc_string[i];
        encodeChar(enc_string[i]);
    }
    return enc;
}


I can't yet test it but I think it is correct, as I say, still trying to actually code the encodeChar function.
So if you have ascii code 125 and you add 3 to it, it'll go from '}' to '!'.
Okay so it does wrap. Thanks.

About your code:
Line 1: What is enc? Is that supposed to be the string to-be encoded? I would use better names, I think you're confusing yourself with "enc" and "enc_string"

Line 2: This initializes an empty string. You probably want to initialize the string so that it has the same length as the input string (enc), otherwise you'd be going out of bounds.
1
2
string encoded_string;
encoded_string.resize(plaintext.length());


Line 3: enc_string.length() will be 0, due to what I said in Line 2.

Line 4: enc_string[i];
What are you trying to do here? This line, by itself, doesn't do anything.

Line 5: You pass in "enc" as a variable, but you never use it, except to then return it. I doubt that is correct.

charEncoder(char)
Given only a char, how do you know what place that char is in the string (or, how do you know what the shift amount is during the encode)? Think about that.
Last edited on
I'll change the variable names. I have a 13 page pdf for this assignment and it uses classes with inheritance and aggregation. So I am slightly confused with this function that encodes the char. It would make way more sense if you could see the pdf but obviously thats not possible so I'm trying to get help for the this cipher part.


Given only a char, how do you know what place that char is in the string (or, how do you know what the shift amount is during the encode)? Think about that.


I very much have been. My guess would be to store the string in an array and then on each run of charEncoder in the encode function pass the char to the charEnocder function.


What are you trying to do here? This line, by itself, doesn't do anything.


Would I set it = to something ?


Line 2: This initializes an empty string. You probably want to initialize the string so that it has the same length as the input string (enc), otherwise you'd be going out of bounds.


i think it needs to be declared and set in the main.cpp but I'm not there yet, but thanks for pointing that out. I should have spotted that.
I very much have been. My guess would be to store the string in an array and then on each run of charEncoder in the encode function pass the char to the charEnocder function.
Previously, you stated,
A plaintext char is received as input and shifted according to the current place in the codeword. The shifted char is returned.

From that, are you allowed to change the signature of the charEncoder function?
i.e. make it char charEncoder(char ch, int place)? Otherwise, the requirements don't make sense.
However, since you're using a class, you could skirt around this by having a class member variable that keeps track of the current place in the string, but I don't condone this.

Would I set it = to something
Yes, since your charEncoder function returns a char, set it to the return value of the charEncoder function.

I suggest testing your charEncoder function by itself, because you can't test your encode function until you know your charEncoder function works. Since encode depends on charEncoder.
Last edited on

From that, are you allowed to change the signature of the charEncoder function?
i.e. make it char charEncoder(char ch, int place)? Otherwise, the requirements don't make sense.
However, since you're using a class, you could skirt around this by having a class member variable that keeps track of the current place in the string, but I don't condone this.


I spoke to my lecturer and she that you can alter the functions and if I want I can just use the encode function to do all the work. So yes I can do this:
i.e. make it char charEncoder(char ch, int place)?





Yes, since your charEncoder function returns a char, set it to the return value of the charEncoder function.


I shall do that, thank you.

I'm trying to decompose this entire cipher into pieces and so far I'm making progress but still far off.
Last edited on
Hopefully this helps.
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
#include <iostream>
#include <string>

using namespace std; 

// set range and shift
const int MIN = 65; 
const int MAX = 90; 
const int SHIFT = 0; 

// char encrption 
char Encrypt(char message, char key){
	int shift = int(key) - MIN + SHIFT; 

	if ((int(message) + shift) <= MAX) 
		return (int(message) + shift);
	else
		return (int(message) + shift) - (MAX + 1 - MIN); 
}

// string encrption
string VinCipher(string message, string key) {
	string cipher; 
	cipher.resize(message.length()); 
	int i = 0; 
	int j = 0; 

	for (auto m : message){
		if (j == key.length()) { j = 0; }
		
		cipher[i] += Encrypt(m, key[j]);

		j++;
		i++; 
	}


	return cipher; 
}

int main() {
	cout << VinCipher("ATTACKATDAWN", "LEMON") << endl;

	system("pause"); 
	return 0; 
}
I'm making progress and I think I have the whole thing nearly done.
Last edited on
what you are looking for is the % operator. I tried to explain this above, but here,

if you wanted 1 to 100

int shift = 0;
for(int i = 0; i < 550; i++)
{
shift = (i)%100 +1; //0%100 = 0 + 1 -> 1 first value
// 1%100 = 1 + 1 -> 2 second value
// ... 99%100 = 99 + 1 -> 100
// ... 100%100 = 0 + 1 -> 1
// ... 101%100 = 1 + 1 -> 2 .. and so on
}

look up how % works, and use it to wrap around your shift. If your shifts are not min, min+1, min+2 .. min +N = max format, then you should put them in a vector and use the index as your wrap around and the data at the index location can be anything

see if you can understand this. % is a critical tool in programming as its properties make a number of tasks very easy (including wrap around as seen here, forcing values into a range (random values usually), and a few nifty integer maniuplation algorithms (gcd, for example).
Last edited on
I managed to get the wrap to work. Just need to figure out how to make reuse the codeword if the plaintext string is longer than the codeword string.

eg:
Plaintext: hello
Codework: hi

Plaintext: hello
codeword: hihih

Obviously i need to compare string lengths but actaully figuring out how much of the codeword to use extra I have no idea.

Thanks jonnin, I'll go and give that a sqiuzz.
Alrighty.

So i managed to get the codeword to be the length of the plaintext.
Just used a while loop and an index to check each char in codeword and then added a char to codeword until it was the correct length.

Thanks everybody for any and al input you gave. Really enjoy this forum page, the users are awesome.
Topic archived. No new replies allowed.