1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 University of California
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
10 // BOINC is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC. If not, see <http://www.gnu.org/licenses/>.
18 // This program serves as both
19 // - An example BOINC application, illustrating the use of the BOINC API
20 // - A program for testing various features of BOINC
22 // NOTE: this file exists as both
23 // boinc/apps/upper_case.C
25 // boinc_samples/example_app/uc2.C
26 // If you update one, please update the other!
28 // The program converts a mixed-case file to upper case:
29 // read "in", convert to upper case, write to "out"
31 // command line options
32 // -run_slow: sleep 1 second after each character
33 // -cpu_time N: use about N CPU seconds after copying files
34 // -early_exit: exit(10) after 30 chars
35 // -early_crash: crash after 30 chars
39 #include "boinc_win.h"
57 #include "boinc_api.h"
60 #include "ChainWalkContext.h"
65 bool early_exit = false;
66 bool early_crash = false;
67 bool early_sleep = false;
68 double cpu_time = 20, comp_result;
70 int QuickSortPartition(RainbowChainCP* pChain, int nLow, int nHigh)
72 int nRandomIndex = nLow + ((uint32)rand() * ((uint32)RAND_MAX + 1) + (uint32)rand()) % (nHigh - nLow + 1);
73 RainbowChainCP TempChain;
74 TempChain = pChain[nLow];
75 pChain[nLow] = pChain[nRandomIndex];
76 pChain[nRandomIndex] = TempChain;
78 TempChain = pChain[nLow];
79 uint64 nPivotKey = pChain[nLow].nIndexE;
82 while (nLow < nHigh && pChain[nHigh].nIndexE >= nPivotKey)
84 pChain[nLow] = pChain[nHigh];
85 while (nLow < nHigh && pChain[nLow].nIndexE <= nPivotKey)
87 pChain[nHigh] = pChain[nLow];
89 pChain[nLow] = TempChain;
93 void QuickSort(RainbowChainCP* pChain, int nLow, int nHigh)
97 int nPivotLoc = QuickSortPartition(pChain, nLow, nHigh);
98 QuickSort(pChain, nLow, nPivotLoc - 1);
99 QuickSort(pChain, nPivotLoc + 1, nHigh);
103 int main(int argc, char **argv) {
106 char output_path[512], chkpt_path[512];
108 retval = boinc_init();
110 fprintf(stderr, "boinc_init returned %d\n", retval);
115 // get size of input file (used to compute fraction done)
117 //file_size(input_path, fsize);
119 // See if there's a valid checkpoint file.
120 // If so seek input file and truncate output file
126 fprintf(stderr, "Not enough parameters");
129 string sHashRoutineName, sCharsetName, sSalt, sCheckPoints;
130 int nRainbowChainCount, nPlainLenMin, nPlainLenMax, nRainbowTableIndex, nRainbowChainLen;
132 sHashRoutineName = argv[1];
133 sCharsetName = argv[2];
134 nPlainLenMin = atoi(argv[3]);
135 nPlainLenMax = atoi(argv[4]);
136 nRainbowTableIndex = atoi(argv[5]);
137 nRainbowChainLen = atoi(argv[6]);
138 nRainbowChainCount = atoi(argv[7]);
141 nChainStart = _atoi64(argv[8]);
144 nChainStart = atoll(argv[8]);
146 sCheckPoints = argv[9];
147 vector<int> vCPPositions;
148 char *cp = strtok((char *)sCheckPoints.c_str(), ",");
151 vCPPositions.push_back(atoi(cp));
152 cp = strtok(NULL, ",");
158 //std::cout << "Starting ChainGenerator" << std::endl;
159 // Setup CChainWalkContext
160 //std::cout << "ChainGenerator started." << std::endl;
162 if (!CChainWalkContext::SetHashRoutine(sHashRoutineName))
164 fprintf(stderr, "hash routine %s not supported\n", sHashRoutineName.c_str());
167 //std::cout << "Hash routine validated" << std::endl;
169 if (!CChainWalkContext::SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))
171 std::cerr << "charset " << sCharsetName << " not supported" << std::endl;
174 //std::cout << "Plain charset validated" << std::endl;
176 if (!CChainWalkContext::SetRainbowTableIndex(nRainbowTableIndex))
178 std::cerr << "invalid rainbow table index " << nRainbowTableIndex << std::endl;
181 //std::cout << "Rainbowtable index validated" << std::endl;
183 if(sHashRoutineName == "mscache")// || sHashRoutineName == "lmchall" || sHashRoutineName == "halflmchall")
185 // Convert username to unicode
186 const char *szSalt = sSalt.c_str();
187 int salt_length = strlen(szSalt);
188 unsigned char cur_salt[256];
189 for (int i=0; i<salt_length; i++)
191 cur_salt[i*2] = szSalt[i];
192 cur_salt[i*2+1] = 0x00;
194 CChainWalkContext::SetSalt(cur_salt, salt_length*2);
196 else if(sHashRoutineName == "halflmchall")
197 { // The salt is hardcoded into the hash routine
198 // CChainWalkContext::SetSalt((unsigned char*)&salt, 8);
200 else if(sHashRoutineName == "oracle")
202 CChainWalkContext::SetSalt((unsigned char *)sSalt.c_str(), sSalt.length());
204 //std::cout << "Opening chain file" << std::endl;
208 // fclose(fopen(sFilename.c_str(), "a"));
209 // FILE* file = fopen(sFilename.c_str(), "r+b");
210 boinc_resolve_filename("result", output_path, sizeof(output_path));
211 fclose(boinc_fopen(output_path, "a"));
212 FILE *outfile = boinc_fopen(output_path, "r+b");
216 std::cerr << "failed to create " << output_path << std::endl;
221 // Check existing chains
222 unsigned int nDataLen = (unsigned int)GetFileLen(outfile);
223 unsigned int nFileLen;
226 nDataLen = nDataLen / 18 * 18;
227 if ((int)nDataLen == nRainbowChainCount * 18)
229 std::cerr << "precomputation of this rainbow table already finished" << std::endl;
233 nChainStart += (nDataLen / 18);
234 fseek(outfile, nDataLen, SEEK_SET);
236 CChainWalkContext cwc;
238 time_t tStart = time(NULL);
239 // std::cout << "Starting to generate chains" << std::endl;
240 for(int nCurrentCalculatedChains = nDataLen / 18; nCurrentCalculatedChains < nRainbowChainCount; nCurrentCalculatedChains++)
243 unsigned short checkpoint = 0;
244 fd = (double)nCurrentCalculatedChains / (double)nRainbowChainCount;
245 boinc_fraction_done(fd);
246 cwc.SetIndex(nChainStart++); // use a given index now!
247 nIndex[0] = cwc.GetIndex();
249 for (int nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
251 // std::cout << "IndexToPlain()" << std::endl;
253 // std::cout << "PlainToHash()" << std::endl;
255 // std::cout << "HashToIndex()" << std::endl;
256 cwc.HashToIndex(nPos);
257 if(cpcheck < vCPPositions.size() && nPos == vCPPositions[cpcheck])
260 checkpoint |= (1 << cpcheck) & (unsigned short)cwc.GetIndex() << cpcheck;
264 //std::cout << "GetIndex()" << std::endl;
266 nIndex[1] = cwc.GetIndex();
267 // Write chain to disk
268 if ((nReturn = fwrite(nIndex, 1, 16, outfile)) != 16)
270 std::cerr << "disk write fail" << std::endl;
274 if((nReturn = fwrite(&checkpoint, 1, 2, outfile)) != 2)
276 std::cerr << "disk write fail" << std::endl;
282 //std::cout << "Generation completed" << std::endl;
283 fseek(outfile, 0, SEEK_SET);
284 nFileLen = GetFileLen(outfile);
285 nRainbowChainCount = nFileLen / 18;
287 RainbowChainCP* pChain = (RainbowChainCP*)new unsigned char[sizeof(RainbowChainCP) * nRainbowChainCount];
292 fseek(outfile, 0, SEEK_SET);
293 for(int i = 0; i < nRainbowChainCount; i++)
295 if(fread(&pChain[i], 1, 16, outfile) != 16)
297 printf("disk read fail\n");
300 if(fread(&pChain[i].nCheckPoint, 1, sizeof(pChain[i].nCheckPoint), outfile) != 2)
302 printf("disk read fail\n");
308 QuickSort(pChain, 0, nRainbowChainCount - 1);
311 fseek(outfile, 0, SEEK_SET);
312 for(int i = 0; i < nRainbowChainCount; i++)
314 fwrite(&pChain[i], 1, 16, outfile);
315 fwrite(&pChain[i].nCheckPoint, 2, 1, outfile);
322 // main loop - read characters, convert to UC, write
325 boinc_fraction_done(1);
330 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) {
335 command_line = GetCommandLine();
336 argc = parse_command_line( command_line, argv );
337 return main(argc, argv);
341 const char *BOINC_RCSID_33ac47a071 = "$Id: upper_case.C 12135 2007-02-21 20:04:14Z davea $";