Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Created by Safety0ff, derived from Jon King's work @ http://theamazingking.com/lock-rake.html
- */
- #include <iostream>
- #include <ctime>
- #include <cctype>
- #include <cmath>
- #include <string>
- #include <sstream>
- #include <fstream>
- using namespace std;
- //----------------- Deflection options
- #define DEFLEC // Defining DEFLECT uses model which is more difficult to pick
- //----------------- Progress Report options
- #define PROGRES // Defining PROGRESS enables progress output as % complete (more useful)
- #define NOPROGRESS // Defining NOPROGRESS means you'll only get final results (faster)
- #define ITERATIONDISPLA // Define ITERATIONDISPLAY and NOPROGRESS for iteration display
- //---------------------------------------
- #define numOfPinLengths 10
- #define numPinTolerances 100
- #define numTopCombos 5
- void convertConvention();
- class Lock
- {
- private:
- int numPins;
- int *pins; // Pin lengths
- int *pinTolerance; // Determines bind order
- bool *pinSet; // Pin set or not
- int patience; // Number of times to rake
- int *rakeOrder;
- bool isBinding(int index)
- {
- if (pinSet[index])
- {
- return false;
- }
- for (int i=0;i<numPins;i++)
- {
- if ((pinTolerance[i]>pinTolerance[index])&&(!pinSet[i]))
- {
- return false;
- }
- }
- return true;
- }
- public:
- Lock (int thisManyPins,int rakeThisManyTimes ) // Constructor
- {
- int i;
- srand(time(NULL));
- numPins=thisManyPins;
- patience=rakeThisManyTimes;
- pins=new int [numPins];
- pinTolerance=new int [numPins];
- pinSet=new bool [numPins];
- rakeOrder=new int [patience];
- for (i=0;i<numPins;i++)
- {
- pins[i] = rand() % numOfPinLengths;
- pinTolerance[i] = rand() % numPinTolerances;
- pinSet[i]=false;
- }
- for (i=0;i<patience;i++)
- {
- rakeOrder[i]=numPins-1;
- }
- }
- ~Lock () // Destructor
- {
- delete [] pins;
- delete [] pinTolerance;
- delete [] pinSet;
- delete [] rakeOrder;
- }
- bool isOpen()
- {
- for (int i=0;i<numPins;i++)
- {
- if (pinSet[i]==false)
- {
- return false;
- }
- }
- return true;
- }
- void setRandomCombo()
- {
- int i;
- for (i = 0; i < patience; i++)
- {
- rakeOrder[i] = rand() % numPins;
- }
- }
- void setRandomPins()
- {
- int i;
- for (i=0;i<numPins;i++)
- {
- pins[i] = rand() % numOfPinLengths;
- pinTolerance[i] = rand() % numPinTolerances;
- pinSet[i]=false;
- }
- }
- void lockLock()
- {
- int i;
- for (i=0;i<numPins;i++)
- {
- pinSet[i]=false;
- }
- }
- void setZeroCombo()
- {
- int i;
- for (i = 0; i < patience; i++)
- {
- rakeOrder[i] = 0;
- }
- }
- void setCombo()
- {
- int temp,i;
- for (i=0;i<patience;i++)
- {
- cout<<"Position #"<<i+1<<" rake pin number:";
- cin>>temp;
- if (cin.fail())
- {
- cin.clear();
- cin.ignore(INT_MAX, '\n');
- cout << "\n\nAn input error occured - please try again.\n\n";
- i--;
- continue;
- }
- temp--;
- if (temp<numPins&&temp>=0)
- {
- rakeOrder[i]=temp;
- }
- else
- {
- cout<<"Invalid pin number, try again.\n";
- i--;
- continue;
- }
- }
- }
- bool incrementCombo()
- {
- int i;
- rakeOrder[0]++;
- for (i = 0; i<patience-1; i++)
- {
- if (rakeOrder[i]>=numPins)
- {
- rakeOrder[i+1]++;
- rakeOrder[i]=0;
- }
- else
- {
- break;
- }
- }
- if (rakeOrder[patience-1]>=numPins)
- {
- setZeroCombo();
- return false;
- }
- else
- {
- return true;
- }
- }
- int getNumberOfPins()
- {
- return numPins;
- }
- void newLock ()
- {
- for (int i=0;i<numPins;i++)
- {
- pins[i] = rand() % numOfPinLengths;
- pinTolerance[i] = rand() % numPinTolerances;
- pinSet[i]=false;
- }
- }
- bool rakeUpwards()
- {
- int i,j,rakeHeight;
- for (i=0;i<patience;i++)
- {
- rakeHeight=numOfPinLengths; // Greater than the max height
- // The following line determines the "direction" you rake in
- // ex: for(j=rakeOrder[i]; j >=0; j--) will rake out
- for (j=rakeOrder[i]; j <numPins ; j++)
- {
- #ifdef DEFLECT
- if (pins[j] <= rakeHeight-1) // Requires the rake to be higher to set pins
- {
- if (isBinding(j))
- {
- pinSet[j] = true;
- rakeHeight=pins[j];
- }
- else if (pinSet[j])
- {
- rakeHeight=pins[j]; // Deflecting off a set pin
- }
- }
- #endif
- if (pins[j] <= rakeHeight)
- {
- #ifndef DEFLECT
- if (isBinding(j))
- {
- pinSet[j] = true;
- rakeHeight=pins[j];
- }
- else if (pinSet[j])
- {
- rakeHeight=pins[j]; // Deflecting off a set pin
- }
- #endif
- #ifdef DEFLECT
- if (isBinding(j)) // In this model the rake has to be 1 higher than the pin length to set, otherwise it deflects
- {
- rakeHeight--;
- }
- #endif
- if (rakeHeight < numOfPinLengths)
- {
- rakeHeight++;
- }
- }
- }
- }
- if (isOpen())
- {
- return true;
- }
- return false;
- }
- bool rake()
- {
- int i,j,rakeHeight;
- for (i=0;i<patience;i++)
- {
- rakeHeight=numOfPinLengths; // Greater than the max height
- // The following line determines the "direction" you rake in
- // ex: for(j=rakeOrder[i]; j >=0; j--) will rake out
- for (j=rakeOrder[i]; j <numPins ; j++)
- {
- #ifdef DEFLECT
- if (pins[j] <= rakeHeight-1)
- {
- if (isBinding(j))
- {
- pinSet[j] = true;
- rakeHeight=pins[j];
- }
- else if (pinSet[j])
- {
- rakeHeight=pins[j];
- }
- }
- #endif
- if (pins[j] <= rakeHeight)
- {
- #ifndef DEFLECT
- if (isBinding(j))
- {
- pinSet[j] = true;
- rakeHeight=pins[j];
- }
- else if (pinSet[j])
- {
- rakeHeight=pins[j];
- }
- #endif
- #ifdef DEFLECT
- if (isBinding(j)) // In this model the rake has to be 1 higher than the pin length to set, otherwise it deflects
- {
- rakeHeight--;
- }
- #endif
- }
- }
- }
- if (isOpen())
- {
- return true;
- }
- return false;
- }
- string currentCombo()
- {
- stringstream temp;
- temp<<(rakeOrder[0]+1);
- for (int i=1;i<patience;i++)
- {
- temp<<'-';
- temp<<(rakeOrder[i]+1);
- }
- return temp.str();
- }
- };
- int main()
- {
- char command,saveFile;
- int iterations,timesToRake,numberOfPins,lockTrials,updateFreq=0,bestPercentages[numTopCombos],openedLocks=0,progress=0;
- bool rakeUpwards;
- Lock *bogusLock;
- string fastestCombo[numTopCombos],filename,firstCombo;
- cout<<"JK's Raking Analyser rewritten in funky C++ BY Safety0ff\n"
- "--------------------------------------------------------\n"
- "Pin number convention:\n"
- " i.e.:\n"
- " pin # 1 2 3 4 5 6...etc\n"
- " back of lock <======> front of lock\n"
- " tip of key <=========> bow of key\n"
- "----------------------------------------\n"
- "The values in parentheses represent static test parameters used to generate the results on JK's site\n\n"
- "Upward raking consists of moving the pick up by one position for each pin you pass\n"
- "----------------------------------------\n";
- while (true) // Main loop
- {
- for (int k=0;k<numTopCombos;k++)
- {
- bestPercentages[k]=0;
- }
- cout<<
- "\n\n--------------------\n"
- "Menu\n"
- "--------------------\n"
- "(R)andom Rakes\n"
- "(S)ingle Rake\n"
- "(B)rute Force all Rakes\n"
- "(D)Brute force range of rakes\n"
- "(T)ranslate pin # conventions\n"
- "(Q)uit\n"
- "\nCommand: ";
- cin>>command;
- cin.sync();
- command=toupper(command);
- switch (command)
- {
- case 'T':
- convertConvention();
- continue;
- case 'D':
- case 'R':
- case 'B':
- break;
- case 'Q':
- cout<<"Quitting...";
- return 0;
- case 'S':
- iterations=1;
- updateFreq=0;
- break;
- default:
- cout<<"**Invalid choice**";
- continue;
- }
- while (true) // Setup loop
- {
- cout<<"Rake upwards(Y/N)? ";
- if (toupper(getchar())=='Y')
- {
- rakeUpwards=true;
- }
- else
- {
- rakeUpwards=false;
- }
- cin.sync();
- cout<<"How many pins? ";
- cin>>numberOfPins;
- cout<<"How many rakes per combo? ";
- cin>>timesToRake;
- cout<<"How many locks to test each combo(20000)? ";
- cin>>lockTrials;
- if (command!='S')
- {
- if (command=='B')
- {
- iterations=(int) pow((float)numberOfPins,(float)timesToRake);
- cout<<"Going to iterate through "<<iterations<<" rake(s)\n";
- }
- else if (command=='R')
- {
- cout<<"How many random combos to try (200000)? ";
- cin>>iterations;
- }
- else
- {
- cout<<"How many combos to try? ";
- cin>>iterations;
- }
- #ifndef NOPROGRESS
- #ifndef PROGRESS
- cout<<"How often do you want results so far? ";
- cin>>updateFreq;
- #endif
- #endif
- }
- if (numberOfPins<=0||timesToRake<=0||lockTrials<=0||iterations<=0
- #ifndef PROGRESS
- #ifndef NOPROGRESS
- ||updateFreq<0
- #endif
- #endif
- )
- {
- cout<<"\n\nNo values less than or equal to zero dummy.\n\n";
- continue;
- }
- if (cin.fail())
- {
- cin.clear();
- cin.ignore(INT_MAX, '\n');
- cout << "\n\nAn input error occured - please try again.\n\n";
- continue;
- }
- else
- {
- break;
- }
- }
- bogusLock=new Lock(numberOfPins,timesToRake);
- if (command=='R')
- {
- bogusLock->setRandomCombo();
- }
- else if (command=='B')
- {
- bogusLock->setZeroCombo();
- }
- else
- {
- bogusLock->setCombo();
- firstCombo=bogusLock->currentCombo();
- }
- progress=iterations/100;
- #ifdef PROGRESS
- cout<<"\rSimulation 0% completed";
- #endif
- for (int i=1;i<=iterations;i++)
- {
- openedLocks=0;
- if (rakeUpwards)
- {
- for (int j=0;j<lockTrials;j++)
- {
- bogusLock->newLock();
- if (bogusLock->rakeUpwards())
- {
- openedLocks++;
- }
- }
- }
- else
- {
- for (int j=0;j<lockTrials;j++)
- {
- bogusLock->newLock();
- if (bogusLock->rake())
- {
- openedLocks++;
- }
- }
- }
- if (openedLocks>0)
- {
- for (int k=0;k<numTopCombos;k++)
- {
- if (openedLocks>=bestPercentages[k])
- {
- for (int i=numTopCombos-1;i>k;i--)
- {
- bestPercentages[i]=bestPercentages[i-1];
- fastestCombo[i]=fastestCombo[i-1];
- }
- bestPercentages[k]=openedLocks;
- fastestCombo[k]=bogusLock->currentCombo();
- break;
- }
- }
- }
- #ifndef NOPROGRESS
- #ifndef PROGRESS
- if ((updateFreq>0)&&((i)%updateFreq==0))
- {
- cout<<endl<<i<<" combo's tested!\nBest so far:\n";
- for (int k=0;k<numTopCombos;k++)
- {
- cout<<(k+1)<<". "<<fastestCombo[k]<<" ["<<(int)((double)bestPercentages[k]*100/(double)lockTrials)<<"%]\n";
- }
- }
- #endif
- #ifdef PROGRESS
- if (i%progress==0)
- {
- cout<<"\rSimulation "<<(int)((double)i*100/(double)iterations)<<"% completed";
- }
- #endif
- #endif
- #ifdef ITERATIONDISPLAY
- cout<<"\rCombo "<<i<<"/"<<iterations;
- #endif
- if (command=='R')
- {
- bogusLock->setRandomCombo();
- }
- else
- {
- if (!bogusLock->incrementCombo())
- {
- break;
- }
- }
- }
- cout<<"\nSimulation Ended.\n"
- "Results:\n";
- for (int j=0;j<numTopCombos;j++)
- {
- if (bestPercentages[j]!=0)
- {
- cout<<(j+1)<<". "<<fastestCombo[j]<<" ["<<(int)((double)bestPercentages[j]*100/(double)lockTrials)<<"%] ["<<bestPercentages[j]<<"]\n";
- }
- }
- cout<<"\nSave results?";
- cin>>saveFile;
- cin.sync();
- if (saveFile=='Y'||saveFile=='y')
- {
- ofstream fout;
- while (true)
- {
- cout << "Enter filename for data file: ";
- cin >> filename;
- filename+=".txt";
- fout.open (filename.c_str(),ios_base::app);
- if (fout.fail())
- {
- cout << "Unable to open file output stream <" << filename << ">.\nPlease try again.";
- fout.clear();
- }
- else
- {
- fout.seekp(0, ios::end);
- fout<<
- "-----------------\n"
- "Settings:\n";
- #ifdef DEFLECT
- fout<<" DEFLECT defined\n";
- #endif
- if (command=='R')
- {
- fout<<" Random mode:\n";
- }
- else if (command=='S')
- {
- fout<<" Single mode:\n";
- if (rakeUpwards)
- {
- fout<<" -Raking upwards\n";
- }
- fout<<" # of Pins: "<<numberOfPins;
- fout<<"\n Rakes per combo: "<<timesToRake;
- fout<<"\n # of locks to test: "<<lockTrials;
- fout<<"\nResults:\n"
- <<firstCombo<<" ["<<(int)((double)openedLocks*100/(double)lockTrials)<<"%] ["<<openedLocks<<"]\n";
- fout<<"-----------------";
- cout<<"Results saved to: "<<filename<<endl;
- break;
- }
- else if (command=='B')
- {
- fout<<" Brute force mode:\n";
- }
- else if (command=='D')
- {
- fout<<" Range mode:\n";
- fout<<" First combo: "<<firstCombo<<endl;
- fout<<" Last combo: "<<bogusLock->currentCombo()<<endl;
- }
- if (rakeUpwards)
- {
- fout<<" -Raking upwards\n";
- }
- fout<<" # of Pins: "<<numberOfPins;
- fout<<"\n Rakes per combo: "<<timesToRake;
- fout<<"\n # of locks to test: "<<lockTrials;
- if (command=='R')
- {
- fout<<"\n Random Combos tried: "<<iterations;
- }
- else
- {
- fout<<"\n Total Combos tried: "<<iterations;
- }
- fout<<"\nResults:\n";
- for (int k=0;k<numTopCombos;k++)
- {
- if (bestPercentages[k]!=0)
- {
- fout<<(k+1)<<". "<<fastestCombo[k]<<" ["<<(int)((double)bestPercentages[k]*100/(double)lockTrials)<<"%] ["<<bestPercentages[k]<<"]\n";
- }
- }
- fout<<"-----------------";
- cout<<"Results saved to: "<<filename<<endl;
- break;
- }
- }
- fout.close();
- }
- else
- {
- cout<<"Proceeding without saving results\n";
- }
- delete bogusLock;
- }
- return 0;
- }
- void convertConvention()
- {
- int numberOfPins,timesToRake,i,j;
- int *temp;
- bool *converted;
- while (true)
- {
- cout<<"How many pins? ";
- cin>>numberOfPins;
- cout<<"How many rakes per combo? ";
- cin>>timesToRake;
- if (cin.fail())
- {
- cin.clear();
- cin.ignore(INT_MAX, '\n');
- cout << "\n\nAn input error occured - please try again.\n\n";
- continue;
- }
- else
- {
- break;
- }
- }
- temp=new int [timesToRake];
- converted=new bool [timesToRake];
- for(j=0;j<timesToRake;j++){
- converted[j]=false;
- }
- for ( i=0;i<timesToRake;i++)
- {
- cout<<"Position #"<<i+1<<" rake pin number:";
- cin>>temp[i];
- if (cin.fail())
- {
- cin.clear();
- cin.ignore(INT_MAX, '\n');
- cout << "\n\nAn input error occured - please try again.\n\n";
- i--;
- continue;
- }
- if (!(temp[i]<=numberOfPins&&temp[i]>0))
- {
- cout<<"Invalid pin number, try again.\n";
- i--;
- }
- }
- for( i=1;i<=numberOfPins;i++)
- {
- for( j=0;j<timesToRake;j++)
- {
- if(temp[j]==i&&!converted[j]){
- temp[j]=numberOfPins-i+1;
- converted[j]=true;
- }
- }
- }
- for(j=0;j<timesToRake;j++){
- if(j==timesToRake-1){
- cout<<temp[j];
- }
- else{
- cout<<temp[j]<<"-";
- }
- }
- delete [] temp;
- }
Advertisement
Add Comment
Please, Sign In to add comment