Converting 3 ints to string

I have to compare 3 integers to string that has 3 chars. I want to create a simple program that searches for 3-digit "password". Here's the code:
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.10.12
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {

string password = "456";
string crack;
stringstream convert;
int counter =1;
int l1, l2, l3;
for (l1=0; l1<=9; l1++) {
for (l2=0; l2<=9; l2++) {
for (l3=0; l3<=9; l3++) {
counter++;
convert << l1 << l2 << l3;
crack = convert.str();
if (crack == password) { break; } } } }
cout << "The cracked password is: " << crack << "\n";
cout << "It took " << counter << " tries to crack the password\n";
return 0;
}

Unfortunately the comparison fails and loop ends on its own. Giving one freaking huge number as crack value.

Edit: The value is total of the loop I mean it begins in 000,001,002 and ends in 999. What do I do to have only one combination at the time instead of combinations being added to each other every loop?
Last edited on
That's because you keep appending digits to the same stringstream.
@kox If I am right the problem you are having is due to the following:

convert << l1 << l2 << l3;

this code appends the string epresentations of l1, l2 and l3 to the crack string, since crack is never changed on the first loop crack = "000" the next loop "000001". By clearing convert each loop you can avoid this:

convert.str("");

Do you have to store the pass code as a string (ie could you have a non numerical pass code like "hey")? If not you can store it as an integer and then convert the contents of convert back into an integer which you can compare with the pass code.

Once you will have done that it will still not work properly because if the if statement only breaks out of the first for loop.

Something like the following would work:

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
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {

	int password = 456;
	string crack;
	stringstream convert;
	int counter =1;
	int a;
	int l1, l2, l3;
	for (l1=0; l1<=9; l1++) {
		for (l2=0; l2<=9; l2++) {
			for (l3=0; l3<=9; l3++) {
				counter++;
				convert << l1 << l2 << l3;
				crack = convert.str();
				istringstream(crack) >> a;

				if (a == password) 
					break; 
	
				convert.str(""); 
			} 
			if (a ==password)
				break;
		} 
			if (a ==password)
				break;
	}

	cout << "The cracked password is: " << crack << "\n";
	cout << "It took " << counter << " tries to crack the password\n";

return 0;
}


Btw if you do need to compare string values you could make a function that checks if the characters match up. Btw I am kinda new to c++ and so my solution may not be the most efficient :)
Big thanks, it works.
I enhanced the app a little and have another problem.
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
//25.10.12
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {

string password = "12";
string crack;
stringstream convert;
int counter =1;
int l1, l2, l3, l4, l5, l6, l7, l8;
int const as=59;

char ch[as+2]={"0123456789AabBCcDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvWwXxYyZz"};

for (l1=0; l1<=as; l1++) {
for (l2=0; l2<=as; l2++) {
for (l3=0; l3<=as; l3++) {
for (l4=0; l4<=as; l4++) {
for (l5=0; l5<=as; l5++) {
//for (l6=0; l6<=as; l6++) {
//for (l7=0; l7<=as; l7++) {
//for (l8=0; l8<=as; l8++) {
counter++;
convert.str("");
convert << ch[l1] << ch[l2] << ch[l3] << ch[l4] << ch[l5]; //<< ch[l6] << ch[l7] << ch[l8];
crack = convert.str();
if (crack == password) { break; }

}
if (crack == password) { break; }
}
if (crack == password) { break; }
}
if (crack == password) { break; }
}

if (crack == password) { break; }

}/*
if (crack == password) { break; }
}
if (crack == password) { break; }
}
if (crack == password) { break; }
}*/


cout << "The cracked password is: " << crack << "\n";
cout << "It took " << counter << " tries to crack the password\n";
//cout << "" << ch[0] << "\n";

return 0;

}


If characters in string constant are equal to number of loops, the app will execute properly. If not, for example 12. It will go on forever (probably till the loop ends). Has anyone got an idea how do I make it more universal?
I mean I want the program to decode for example ANY number that is up to 5 digits. Not numbers that ARE 5 digits.
are you saying that you want a program that tests for every combination possible in a 5 digit number ie 0,1,2,3,4,5,6,7,8,9,10,11,12 -> 99999? At the moment I am not sure why you are using your for loops like that. I have a feeling that it is because you want to capture each digit individually. The big question is is this meant to be used for string passwords such as "hello" if so then you have to check each digit against all letter as well as numbers let alone capitals as well. However if the pass word is always a number then you just need a while loop that keeps looping until it finds the value of the password such as:

1
2
3
4
5
6
7
    int password = 25674;
    int crack = 0;
    while (crack != password){
        crack++;
    }

    cout << crack << endl;


Edit: Just realized that you are wanting to has passwords that can have letters in them"
Last edited on
Here is a working solution:

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
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {

	string password = "abrR";
	string crack;
	stringstream convert;
	int counter = 0;

	int const as = 61;

	string ch ="0123456789AabBCcDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvWwXxYyZz";

	for (int a = 0; a < as; a++) {
		for (int b = 0; b < as; b++) {
			for (int c = 0; c < as; c++) {
				for (int d = 0; d < as; d++) {
					for (int e = 0; e < as; e++) {
						counter++;
						convert << ch.substr(a,1) << ch.substr(b,1) << ch.substr(c,1) << ch.substr(d,1) << ch.substr(e,1);
						crack = convert.str();
						int len = crack.length();
						for (int i = 0; i < len - 1; i++)
						{
							if (crack.substr(0, 1) == "0")
							{
								crack = crack.substr(1, len - i);
							}
						}
						if (crack == password) { 
							break;
						}
						else
						{
							cout << "No Match" << endl;
							convert.str("");
						}

					}
				if (crack == password) { break; }
				}
			if (crack == password) { break; }
			}
		if (crack == password) { break; }
		}
	if (crack == password) { break; }
	}


	cout << "The cracked password is: " << crack << "\n";
	cout << "It took " << counter << " tries to crack the password\n";

	while(true){}
	return 0;

}


However for 5 digit numbers you are looking at 61^5 combinations and so it will take your computer some time to go through them all. try it for a 2 or 3 digit number and try entering letters. It should work.

Edit: Thinking about it if you were to expand this for large length passcodes you would need to start using unsigned int data type and then if you had 8 character long passwords you would need to use unsigned __int64 data type for your counter.
Last edited on
Looks like it works, thanks.
So it will take much much longer to decode 3 sign pass code while searching for maximum 5 sign, than to decode 3 sign, while searching for maximum 3 sign? Because it searches "012" for 5 minutes and I bet it will yet take some time to find it.

If I search for 16 characters, even finding "11" would take crapload of time, am I right?

Edit: I think something is not right with your code. If I search for "12345" it will take a few seconds to find it by my old code. With the code above it seems like it goes to infinity.
Last edited on
if your searching for a passcode with 16 chars in it that includes uppder case, lower case and numbers it would take 61^16 iterations (the whole loop) to find "zzzzzzzzzzzzzzzz".

Also it would be worth noting that I realised if you put in "0w3Gn" as your pass code which is legitimate it wont find it. Any pass code starting with a "0" it wont find. That could be easily corrected by checking the passcode in each iteration of the for loop that modifies the string rather than after its finished.
Thanks.
Your code works, but to find 12345 it takes 10 seconds to decode it with my original program, with your code it takes 33 seconds. Why? (I also put out cout << "no match" from your code)
The difference in counter is 1 (just because you determined counter as 0). So it's equal number of inner loop executed, yet it's over 3 times slower.
A whole ton of for loops isn't really the answer, try writing it so that it can crack a string of any length.
i don't know how effective my code is. I am sure there are better solutions. But the reason I would imagine that mine is slower than the code you posted before is because it does more processing of the strings on each loop. This is because you said you wanted it to search for combinations less than the maximum number of digits.

Also its likely that using char arrays is quicker. Hopefully someone else will be able to extrapolate more as to why.
Yep that's what I realized now after interpreting the codes. I will try to base it on chars, but use your method for length.
Anyway big thanks for help.
@Zephilinox I can't think up of any other idea than using for loops. My programming skills are very basic.
That could be easily corrected by checking the passcode in each iteration of the for loop that modifies the string rather than after its finished.

I don't quite understand that, could you explain this to a noob?
I think he meant that instead of having

 
if (crack == password) { break; }


after you try to crack the string, have it before it tries to crack the string.
Just don't laugh xd I still don't get it. I put these at the beginning of each loop instead at the end. But it doesn't make any difference.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for (l1=0; l1<=as; l1++) { if (crack == password) { break; }
for (l2=0; l2<=as; l2++) { if (crack == password) { break; }
for (l3=0; l3<=as; l3++) { if (crack == password) { break; }
for (l4=0; l4<=as; l4++) { if (crack == password) { break; }
for (l5=0; l5<=as; l5++) { if (crack == password) { break; }
//for (l6=0; l6<=as; l6++) {
//for (l7=0; l7<=as; l7++) {
//for (l8=0; l8<=as; l8++) {
counter++;
convert.str("");
convert << ch[l1] << ch[l2] << ch[l3] << ch[l4] << ch[l5]; //<< ch[l6] << ch[l7] << ch[l8];
crack = convert.str();

int len = crack.length();
for (int i = 0; i < len - 1; i++) { if (crack.substr(0, 1) == "0") { crack = crack.substr(1, len - i); } }
}
}
}
}
Topic archived. No new replies allowed.