decrypted password

Hi!
I need some recommendation and tips about how can i make these code better, I mean if I want to do it without needing to use const zero.
string decryptPassword(string password)
{
const int ROT7 = 7, ROT9 = 9;
const string VOWELS = "AEIOUYaeiouy";
string decryptedpass;
const string zero = "0";

for (size_t i = 0; i < password.length(); i++)
if (even(i))
{
password[i] += ROT7;
decryptedpass = password;
}
else
{
password[i] += ROT9;
decryptedpass = password;
}
decryptedpass.insert(1, zero);
decryptedpass.insert(3, zero);
decryptedpass.insert(5, zero);
decryptedpass.insert(7, zero);
decryptedpass.insert(9, zero);
decryptedpass.insert(11, zero);
decryptedpass.insert(15, zero);
decryptedpass.insert(17, zero);

return decryptedpass;
}
The main purpose with this function is to validate an input password.
factor it out.
if you always use 'zero' when you call insert, then make insert use "0" directly inside it and stop passing it as a param, or make it over-rideable, eg
void insert(int num, string z = "0")
..
insert(1); //same as insert (1, zero)
string five = "5";
insert(2, five); //over-ride the value if you have a use for this?


I need to make the function agnostic towards the password, I mean if Ineed to add another password.
it looks like it is? You pass in password, which is presumably encrypted when it comes in, and you build the decrypted version.
from what I see here I am imagining the stuff you don't show but it looks like you could do this using what you have?

pwd1 = "l337Sp33k!";
pwd2 = "4R1zz!3";
cout >> decrypt(encrypt (pwd1));
cout >> decrypt(encrypt(pwd2));
and it would print pwd1 and pwd2 as the strings shown in their assignment, since they are encrypted and decrypted back to what they were, is this not the case?

often, by the way, you do it the other way around.
that is, the user types something in and you encrypt and destroy what they typed as fast as you can do so, and then you compare what you encrypted against a stored encrypted version and see if those match. You don't keep the password in memory in decrypted format.
Last edited on
decryptPassword(..) takes
the user provided password as argument and should return the string value i0J0u0j0u0J0Zys0r0{ to another function that calls
authenticateUser(..) for successful validation. I need to develop the code to be suitable to more passwords not only just one certain password.
ok.
so you need to do this, in my opinion:
you need to write an encrypt and decrypt pair of functions. The encrypt should take a string and return the encrypted version of that string. Decrypt should take the encrypted version and return the original back.
Once you have those, you can, outside these 2 functions, manage your passwords somehow, for example you can have a file of valid passwords on your disk, in the encrypted format, and you can check what the user types to see if it matches, and so on.

If you are allowed to use any sort of encryption you like, I recommend making it a reversible function instead, so you only have one instead of 2 functions. that is, foo(foo(x)) == x, much like sqrt(x*x) == x for unsigned values. Xor is reversible. If you have to use some goofy thing like the above round robin garble, you probably need two functions as it does not appear to be self reversing.

and, again, decryption of passwords may be not useful. consider instead:
user types password first time. encrypted version is stored in file.
user types password to get access. compare encrypted version of input vs stored data, without decryption. This allows you to make the encryption difficult, or even near impossible, to reverse, because you never need to reverse it, and in fact, being able to reverse it is a liability.


Last edited on
The name of the function was chosen by our teacher, and we are not allowed to alter any of the original code.

Of course hard for you to know since you haven't seen the original which is:

#include "Prototypes.h"
using std::string;
using std::stringstream;
using std::cout;
using std::endl;

string mainArgumentParser(int argc, char* argv[]) {
if (argc < 3)
return "fail";
stringstream ss;
ss << argv[1] << "," << argv[2];
return ss.str();
}

bool authenticateUser(string value) {
const string USERNAME = "Kalle";
const string PASSWORD = "i0J0u0j0u0J0Zys0r0{";
bool authPassed = false;
/**
* Add needed code as stated in the lab description
*/

return authPassed;
}

string decryptPassword(string pass) {
const int ROT7 = 7, ROT9 = 9;
const string VOWELS = "AEIOUYaeiouy";
string decrypted;
/**
* Add needed code as stated in the lab description
*/
return decrypted;

}
Last edited on
The name decryptPassword() sounds like it takes an encrypted password and decrypts it into its plain text. But your code inserts zeros, which seems to imply that it's encrypting, not decrypting. Are you sure you're doing the right thing here?

DecryptPassword() defines VOWELS but doesn't use it. How do vowels factor into the result?

The names ROT7 and ROT9 imply that you should rotate the character values, but you are just adding. Should "Z" get rotated (to G or I)? Right now it will become 'a' or 'c', depending on whether ROT7 or ROT9 is applied.

You insert 8 zeros. What if the original password is too small for that? What if it's larger? If the goal is to make every other character a zero then you need to take the length into account.

Also do you need to insert at position 13 too? You currently insert at all odd positions from 1 to 17 except for 13.

All of these questions boil down to this: exactly what should decryptPassword() do?

This function is like yours but it ensures that every other character of the result is '0'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string
decryptPassword2(string password)
{
    const int ROT7 = 7, ROT9 = 9;
    // const string VOWELS = "AEIOUYaeiouy";  // unused

    string result;              // I always call the return value "result"

    for (size_t i = 0; i < password.length(); i++) {
        if (even(i)) {
            result += password[i] + ROT7;
        } else {
            result += password[i] + ROT9;
        }
        result += '0';
    }

    return result;
}



Hi!
The name of function is choosen by our teacher and I cant modify it. This function is a part of a program that should be used as an authentication system. First The user will input following username and passwoed as a initial arguments to be validated
by the program. These arguments are stated in the command line and should consist of two values, one for username and the other for password. Fortunately, the client has already specified that Kalle will use the following credentails:
Username: Kalle
Password: bAnanASplit
These arguments are passed to main(..) which in turn hands them over to mainArgumentsParser(..), a function devoted to the process of parsing out values The parser will return a string value containing user credentials in the form ”username,password”, or simply ”fail” to inform main(..) that too few arguments were provided. The string of credentails are then passed to authenticateUser(..) which will need to separate the
username from password and store them in separate strings. As can be seen in the function definition, there
already exists two string constants...
const string USERNAME = "Kalle";
const string PASSWORD = "i0J0u0j0u0J0Zys0r0{";
… which will be used to validate the credentials. Since Kalle is intended to be the first command argument it
should be pretty straight forward validating the username, but the second argument bAnanASplit doesn’t look anything like the required password. In order to be able to confirm that the password is correct it first needs to be decrypted. This will be performed by yet another function decryptPassword(..) which takes the user provided password as argument and should return the string value i0J0u0j0u0J0Zys0r0{ to authenticateUser(..) for successful validation.
I wrote decrypted pass() function as shown up but I want to make the function completly agnostic towards password. I hope that I have answered all your questions.
Thanks for the explanation. For what it's worth, your professor is teaching you bad design habits. It makes no sense to start with separate user name and password, then put them together into a single string, only to separate them again in the next step. It also makes zero sense to call a function "decrypt" when it actually encrypts.

Let's look at that constant PASSWORD string:
const string PASSWORD = "i0J0u0j0u0J0Zys0r0{";
Shouldn't "Zy" be "Z0y0"? If not then what rule should the code use to create Zy instead of Z0y0?

Also, shouldn't the last "{" be followed by a 0?

The code that I posted produces what I think is the correct "decrypted" password: i0J0u0j0u0J0Z0y0s0r0{0
Hi!
Thank for your answer. I agree with all you have said that is a bad design habits but we are not allowed to modify names of functions. About your other questions so I think that I missed to clerify some things. In decryptedpassword functions should we do the follwoing comparison before we return password so the final result can be "i0J0u0j0u0J0Zys0r0{"
string decryptPassword(const string& pass) {
const size_t ROT7 = 7, ROT9 = 9;
const string VOWELS = "AEIOUYaeiouy";

stringstream ss;
for (size_t i = 0; i < pass.size(); i++) {
const size_t KEY = (i % 2 == 0) ? ROT7 : ROT9;
char currentChar = pass[i], decryptedChar = currentChar + KEY;

// determine whether current char is a vowel
...
// if we have a vowel, add '0' before and after decryptedChar
...

}

return ss.str();
}

should we do the follwoing comparison before we return password
1
2
3
4
// determine whether current char is a vowel
...
// if we have a vowel, add '0' before and after decryptedChar
...
This is the first time you've mentioned this requirement. I supposed yes, you should add it.

Are there any other requirements that you haven't mentioned?
Execuse me that I didnt mention it before. Yes we should do the the determining first before we return the password and because of this reason we have a string vowels as you see in my first post. Sory if Im not clerifying my question, Im not native english speaker.
Okay. Try to modify one of the versions of the code here to add the '0' characters. I have verified that if you '0' before and after each vowel then the "decrypted" string for "bAnanASplit" is "i0J0u0j0u0J0Zys0r0{"

Your English is good enough :)
Hi!
Thank for your answer, I see that you havent use the vowels string in the following code:
string
decryptPassword2(string password)
{
const int ROT7 = 7, ROT9 = 9;
// const string VOWELS = "AEIOUYaeiouy"; // unused

string result; // I always call the return value "result"

for (size_t i = 0; i < password.length(); i++) {
if (even(i)) {
result += password[i] + ROT7;
} else {
result += password[i] + ROT9;
}
result += '0';
}

return result;


I have a requierment to use it in the functions code.
if you have to use it, tie it to your logic to do something special after a vowel, something like
if find(VOWELS, letter) == string::nopos //i may have the not found word wrong
then its not a vowel, else it is, and put the vowel handler logic in a condition sort of like that...
its not great way to do it, but if you must use it for something...

I see that you haven't use the vowels string in the following code:
Can you modify the code to do what's needed with the vowels? This version of your code looks almost right to me (althnough I wouldn't use a stringsteam. I'd just append to the result string as I went):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string decryptPassword(const string& pass) {
    const size_t ROT7 = 7, ROT9 = 9;
    const string VOWELS = "AEIOUYaeiouy";

    stringstream ss;
    for (size_t i = 0; i < pass.size(); i++) {
        const size_t KEY = (i % 2 == 0) ? ROT7 : ROT9;
        char currentChar = pass[i], decryptedChar = currentChar + KEY;

        // determine whether current char is a vowel
        ...
        // if we have a vowel, add '0' before and after decryptedChar
        ...
    }
    return ss.str();
}

Topic archived. No new replies allowed.