]> git.sesse.net Git - freerainbowtables/blob - Server Applications/rtperfectp/main.cpp
initial
[freerainbowtables] / Server Applications / rtperfectp / main.cpp
1 /*
2         Copyright (C) 2008 Steve Thomas <SMT837784@yahoo.com>
3
4         This file is part of RT Perfecter.
5
6         RT Perfecter is free software: you can redistribute it and/or modify
7         it under the terms of the GNU General Public License as published by
8         the Free Software Foundation, either version 3 of the License, or
9         (at your option) any later version.
10
11         RT Perfecter is distributed in the hope that it will be useful,
12         but WITHOUT ANY WARRANTY; without even the implied warranty of
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14         GNU General Public License for more details.
15
16         You should have received a copy of the GNU General Public License
17         along with RT Perfecter.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 // Current version "RT Perfecter v0.1"
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <time.h>
25 #include <ctime>
26 #include "RTWrite.h"
27 #include "RTRead.h"
28
29 #ifdef _WIN32
30         #include <conio.h>
31         #define DIRECTORY_SEPERATOR '\\'
32 #else
33         #include <fcntl.h>
34         #define DIRECTORY_SEPERATOR '/'
35 #endif
36
37 #define DISPLAY_STATUS_MIN_LOOPS 2000000
38
39 struct RTChain2
40 {
41         uint64 startpt;
42         unsigned int endpt32_1;
43         unsigned int endpt32_2;
44         unsigned short checkpoint;
45 };
46
47 union RTChainU
48 {
49         RTChainCP c;
50         RTChain2 c2;
51         unsigned short checkpoint;
52 };
53
54 void usage(char *runStr);
55
56 int main(int argc, char **argv)
57 {
58 #ifdef _WIN32
59         uint64 maxIndex = 0xffffffffffffffff;
60 #else
61         uint64 maxIndex = 0xffffffffffffffffll;
62 #endif
63         int argi = 1, i, argsUsed = 0;
64         unsigned int maxChainsPerFile = 67108864;
65         
66         // Get arguments
67         if (argc > 3 && argc < 6)
68         {
69                 for (; argi < argc - 2; argi++)
70                 {
71                         if (strcmp(argv[argi], "-v") == 0 && (argsUsed & 1) == 0)
72                         {
73                                 // Enable verbose mode
74                                 argsUsed |= 1;
75                         }
76                         else if (strncmp(argv[argi], "-s=", 3) == 0 && (argsUsed & 2) == 0)
77                         {
78                                 // Max file size in MiB
79                                 argsUsed |= 2;
80                                 maxChainsPerFile = 0;
81                                 for (i = 3; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
82                                 {
83                                         maxChainsPerFile *= 10;
84                                         maxChainsPerFile += ((int) argv[argi][i]) - 0x30;
85                                 }
86                                 if (argv[argi][i] != '\0')
87                                 {
88                                         printf("Error: Invalid number.\n\n");
89                                         usage(argv[0]);
90                                         return 1;
91                                 }
92                                 if (i > 8 || maxChainsPerFile > 65535) // i - 3 > 5
93                                 {
94                                         printf("Error: Number is to large.\n\n");
95                                         usage(argv[0]);
96                                         return 1;
97                                 }
98                                 maxChainsPerFile <<= 16; // maxChainsPerFile *= 1024 * 1024 / 16
99                         }
100                         else if (strncmp(argv[argi], "-i=", 3) == 0 && (argsUsed & 4) == 0)
101                         {
102                                 // Maximum index for chains
103                                 argsUsed |= 4;
104                                 maxIndex = 0;
105                                 for (i = 3; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
106                                 {
107                                         maxIndex *= 10;
108                                         maxIndex += ((int) argv[argi][i]) - 0x30;
109                                 }
110                                 if (argv[argi][i] != '\0')
111                                 {
112                                         printf("Error: Invalid number.\n\n");
113                                         usage(argv[0]);
114                                         return 1;
115                                 }
116                                 if (i > 23) // i - 3 > 20
117                                 {
118                                         printf("Error: Number is to large.\n\n");
119                                         usage(argv[0]);
120                                         return 1;
121                                 }
122                         }
123                         else
124                         {
125                                 printf("Error: Unknown argument.\n\n");
126                                 usage(argv[0]);
127                                 return 1;
128                         }
129                 }
130         }
131         else if (argc != 3)
132         {
133                 if (argc == 1 || argc == 2 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0))
134                 {
135                         usage(argv[0]);
136                         return 0;
137                 }
138                 printf("Error: Wrong number of arguments.\n\n");
139                 usage(argv[0]);
140                 return 1;
141         }
142
143         // Init
144         RTChainU chain, prevChain;
145         uint64 uniqueChains = 0;
146         RTRead inRt(argv[argi], maxIndex, argsUsed & 1);
147         RTWrite outRt(argv[argi + 1], maxChainsPerFile);
148
149         prevChain.c2.endpt32_1 = 0xffffffff;
150         prevChain.c2.endpt32_2 = 0xffffffff;
151 #ifndef _WIN32
152         // Set stdin to non-blocking
153         fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NDELAY);
154 #endif
155         clock_t t = clock();
156         int loops = 0;
157         for (int ret = inRt.readChain(&(chain.c)); ret == 0; ret = inRt.readChain(&(chain.c)))
158         {
159                 // Show status
160                 loops++;
161                 if (loops >= DISPLAY_STATUS_MIN_LOOPS)
162                 {
163 #ifdef _WIN32
164                         // Pressing any key will show the status
165                         if (kbhit())
166                         {
167                                 inRt.printStatus();
168                         }
169 #else
170                         // Pressing enter will show the status
171                         int ch;
172                         do
173                         {
174                                 ch = getchar();
175                         } while (ch != (int)'\n' && ch != EOF);
176                         if (ch == (int)'\n')
177                         {
178                                 inRt.printStatus();
179                         }
180 #endif
181                         loops = 0;
182                 }
183
184                 // Check the least significate 32 bits first
185                 if (chain.c2.endpt32_1 != prevChain.c2.endpt32_1 || chain.c2.endpt32_2 != prevChain.c2.endpt32_2)
186                 {
187                         outRt.writeChain(&(chain.c));
188                         uniqueChains++;
189                 }
190                 prevChain = chain;
191         }
192 #ifdef _WIN32
193         printf("Unique Chains: %I64u\nTotal time:    %1.2f\n", uniqueChains, (clock() - t) / (double)CLOCKS_PER_SEC);
194 #else
195         printf("Unique Chains: %llu\nTotal time:    %1.2f\n", uniqueChains, (clock() - t) / (double)CLOCKS_PER_SEC);
196 #endif
197         return 0;
198 }
199
200 void usage(char *runStr)
201 {
202         printf("\n                          **** RT Perfecter v0.1 ****\n\n");
203         printf("Converts sorted rt files in a directory to a perfect rainbow table. All rt files\n");
204         printf("in the directory must all be from the same rainbow table.\n\n");
205         printf("%s [Options] input-directory output-file-pattern\n\n", runStr);
206         printf("Options:\n");
207         printf("  -i=number\n");
208         printf("    Maximum index for chains.\n\n");
209         printf("  -s=number\n");
210         printf("    Maximum size for output files in MiB [default is 1024, max is 65535].\n\n");
211         printf("  -v\n");
212         printf("    Verbose mode, displays extra info.\n\n");
213         printf("output-file-pattern:\n");
214         printf("  This will be passed into sprintf() with the number of chains in the file and\n");
215         printf("  the current file number starting at 0. This could look like:\n");
216         printf("  'some-folder%csome-name%%u-%%03u.rt'\n", DIRECTORY_SEPERATOR);
217         printf("  Where '%%u' would be the number of chains in the file and '%%03u' would be the\n");
218         printf("  file number formated like 000, 001, 002, and so on.\n\n");
219         printf("Run-time:\n");
220         printf("  Press [Enter] to display a status message.\n\n");
221         printf("Copyright (c) 2008 Steve Thomas <SMT837784@yahoo.com>\n");
222         printf("  This is free software: you can redistribute it and/or modify it under the\n");
223         printf("  terms of the GNU General Public License as published by the Free Software\n");
224         printf("  Foundation, either version 3 of the License, or (at your option) any later\n");
225         printf("  version. There is NO WARRANTY, to the extent permitted by law.\n");
226 }
227