value suddenly turns negative, and counts down

Feb 9, 2011 at 7:27am
the problem: the percentDone value is calculated using values that are always positive, and not using the subtraction operator. it suddenly turns negative, and starts counting towards 0 from the negative side. this only happens when trying to crack passwords that have 5+ digits. it would be helpful if someone could compile this code and see for themselves how it acts.

the code: the code is a program i made to get reacquainted with c++. it's a "password cracker" this will never be implemented, so no flaming please.

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
#include <iostream>
#include <string>
#include <array>
#include <cmath>
#include <time.h>
#include <iomanip>
using namespace std;

int main(){ 
	char* passArray = NULL;
	int charArray[] = {0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 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, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122};
	int number, numRemain, findRemain, length, timeLeft;
	char thisChar;
	time_t start = 0,end;
	string passCheck = "";
	string passWord = "9f2Al";
	cout << "Enter the maximum length of the password: ";
	cin >> length;
	passArray = new char[length];
	double timeDifference;
	double percentDone = 0, percentDoneLast = 0, percentDoneDiff = 0;
	double availChars = 63;
	double possible = pow(availChars,length);
	double updateSpeed = 10-(length/2);
	int updateRate = possible/pow(updateSpeed,length);
	for(number = 0; number < possible; number ++){
		percentDone = 100*number/possible;
		percentDoneDiff = percentDone - percentDoneLast;
		for(int i = 0; i < length; i++){
			if(i==0){
					findRemain = pow(availChars,(length-(i+1)));
					numRemain = number % findRemain;
					thisChar = char(charArray[number/findRemain]);
					passArray[i] = thisChar;
			}else if(i==(length-1)){
					findRemain = pow(availChars,(length-(i)));
					numRemain = number % findRemain;
					thisChar = char(charArray[numRemain]);
					passArray[i] = thisChar;
			}else{
					numRemain = numRemain % findRemain;
					findRemain = pow(availChars,(length-(i+1)));
					thisChar = char(charArray[numRemain/findRemain]);
					passArray[i] = thisChar;
			}
		}

			for(int f=0; f < length; f++){
				if(passArray[f] != NULL){
					passCheck += passArray[f];
				}
			}
				if(passCheck == passWord){
					cout << passCheck << " -- This is the password.                                              "<< endl;
					system("pause");
					break;
				}else{
					passCheck.clear();
				}
		if(number%updateRate==0){	
		time(&end);
		timeDifference = difftime (end,start);
		timeLeft = timeDifference*((100-percentDone)/percentDoneDiff);
		if(timeLeft >0){
			cout  << setprecision(5) << percentDone << "%" << "     Time Remaining:  " << timeLeft  << '\r';
		}else{
			cout  << setprecision(5) << percentDone << "%" << '\r';
		}
		percentDoneLast = percentDone;
		time(&start);
		}
	}
	cout<< endl;
	system("pause");
	return 0;
}


the lines that are relevant to the problem are:

double percentDone = 0, percentDoneLast = 0, percentDoneDiff = 0;

percentDone = 100*number/possible;

1
2
3
4
5
if(timeLeft >0){
			cout  << setprecision(5) << percentDone << "%" << "     Time Remaining:  " << timeLeft  << '\r';
		}else{
			cout  << setprecision(5) << percentDone << "%" << '\r';
		}

Last edited on Feb 9, 2011 at 7:51am
Feb 9, 2011 at 7:48am
I think it is probably the number variable. Try changing number to double... Let me know if that works. (Reason: the variable 'possible' is probably very large, you are probably exceeding the max limits of int).
Last edited on Feb 9, 2011 at 7:51am
Feb 9, 2011 at 7:56am
thanks for the reply.

just tried it out, and i'm getting an error. apparently, it won't let me use a double on the left side of the % operand. what you said makes perfect sense though, and i do believe that that is in fact the problem.

and if you feel like it, are there any simple things i could do to optimize this code that you could point out?

Feb 9, 2011 at 8:01am
Use std::modf from the <cmath> library. Let me know how that goes - then I'll look into optimization.

http://www.cplusplus.com/reference/clibrary/cmath/modf/

(I'll let you try get that working by yourself first - good for learning).
Last edited on Feb 9, 2011 at 8:03am
Feb 9, 2011 at 8:07am
i changed number to an unsigned long long int, and i have success.

thank you for pointing out what was wrong. i never would've found that by myself. i'm still a newbie with c++, this is day number 4 for me haha.
Feb 9, 2011 at 8:12am
Well done! I'd probably suggest using double - I don't think "unsigned long long int" is supported in the latest C++ standards (but I'm not really sure about that).

By the way, a char can be assigned an numeric value, for example:

 
char a = 65;


So you should define charArray as char - not int. This probably won't help with optimisation - it is more just a memory thing.
Feb 9, 2011 at 8:18am
hmmm... makes sense.

i had charArray as an int so i could use each node as an ascii code, but now that you bring that up, it seems like the long way to do it forsure. i'm sure it won't slow it down any :D
Feb 9, 2011 at 8:33am
You can still use the ascii code. Don't think of char as strictly a character - think of it as a short short int - 1 byte. So... change charArray to char, get rid of the (char) casts and tell me if it still works.
Last edited on Feb 9, 2011 at 8:34am
Feb 10, 2011 at 5:16pm
still works.
thanks, nick.
Topic archived. No new replies allowed.