'script for selecting a string from random letters
My code allows you to guess the hidden string from the letters and numbers it consists of. But my code is not very efficient as it can generate the same strings. If I do a search for a string from the letters of the entire alphabet, then it will search for me a string until the morning. How can you foresee this moment?
import random
from datetime import datetime
import time
startTime = datetime.now()
password = 'qwerty'
letters = 'werqty'
searchPassword = ''
counter = 0
while searchPassword != password:
searchPassword = ''
for i in range(6):
searchPassword += letters[random.randint(0, 5)]
print(searchPassword)
counter += 1
print(counter)
print(datetime.now() - startTime)
Here are examples of three script runs:
#1
counter = 33895
time = 0:00:10.278330
#2
counter = 2214
time = 0:00:00.218893
#3
counter = 46308
time = 0:00:11.910321
In general, it all depends on the random.
The script can find the string both in 1 second and in 1 minute.
Any ideas how to make the algorithm faster?
Solution 1:[1]
I believe you want to implement a variation of Monte-Carlo method on this task. The simplest way using Python is to use random.sample:
import random
from datetime import datetime
startTime = datetime.now()
password = 'qwerty'
letters = 'werqty'
searchPassword = ''
counter = 0
while searchPassword != password:
searchPassword = ''.join(random.sample(letters, 6))
counter += 1
print(counter)
print(datetime.now() - startTime)
I'd tested its performance. On my laptop I've got ~7.3s for 1000 launches. Code for testing:
import random
from datetime import datetime
password = 'qwerty'
letters = 'werqty'
searchPassword = ''
counter = 0
total_time = 0
for run in range(1000):
startTime = datetime.now()
while searchPassword != password:
searchPassword = ''.join(random.sample(letters, 6))
counter += 1
searchPassword = ''
total_time += (datetime.now() - startTime).total_seconds()
print(f"{total_time}")
My output:
7.202784999999992
Solution 2:[2]
Random guess is not the best practice, if you don't have a dictionary to iterate through, brute forcing through all combinations in a random order is your best option.
import random
from datetime import datetime
import time
from itertools import product
startTime = datetime.now()
password = 'qwerty'
letters = 'werqty'
searchPassword = ''
counter = 0
comb_list = list(product(letters, repeat=6))
random.shuffle(comb_list)
guess = ''
for comb in comb_list:
guess = ''.join(comb)
if(guess == password):
print("Found: ", guess)
break;
counter+=1;
print(counter)
print(datetime.now() - startTime)
Execute time
0:00:00.059003
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Yevgeniy Kosmak |
| Solution 2 |
