Me and a friend want to create a script that gives us every possible combination of a six digit code, comprised of 36 alphanumeric characters (0-9, and a-z), in alphabetical order, then be able to see them in a .txt file.
And I want it to use all of the CPU and RAM it can, so that it takes less time to complete the task.
So far, this is the code:
import random
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
links = []
file = open("codes.txt", "a")
for g in range(0, 36**6):
key = ""
base = ""
print(str(g))
for i in range(0, 6):
char = random.choice(charset)
key = char
base = key
file.write(base "\n")
file.close()
This code randomly generates the combinations and immediately writes them in a .txt file, while printing the amount of codes it has already created but, it isn't in alphabetical order (have to do it afterwards), and it takes too long.
How can the code be improved to give the desired outcome?
CodePudding user response:
Random Can be very inefficient. You can try :
from itertools import permutations
from pandas import Series
charset = list("0123456789abcdefghijklmnopqrstuvwxyz")
links = []
file = open("codes.txt", "a")
comb = permutations(charset,6)
comb = list(comb)
comb = list(map(lambda x:return ''.join(x),comb))
mySeries = Series(comb)
mySeries = mySeries.sort_values()
base = ""
for k in mySeries:
base = k
file.write(base "\n")
file.close()
CodePudding user response:
You could use itertools.permutaions
from the default itertools
library. You can also specify the number of characters in the combination.
from itertools import permutations
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
c = permutations(charset, 6)
with open('code.txt', 'w') as f:
for i in c:
f.write("".join(i) '\n')
Runs on my computer in about 200 milliseconds for creating the list of permutations, then spends a lot of time writing to the file
CodePudding user response:
This is a combination problem where you are trying to get combinations of length 6 from the character set of length 36. This will produce an output of size 36!/(30!*6!) . You can refer the itertools for solving a combination problem like below. You can refer the Combination function in itertools Documentation. It is recommended not to perform such a performance intensive computation using Python.
CodePudding user response:
For permutations, this would do the trick:
from itertools import permutations
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
links = []
with open("codes.txt", "w") as f:
for permutation in permutations(charset, 6):
f.write(''.join(permutation) '\n')
FYI, it would create a 7.8 GigaByte file
For combinations, this would do the trick:
from itertools import combinations
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
links = []
with open("codes.txt", "w") as f:
for comb in combinations(charset, 6):
f.write(''.join(comb) '\n')
FYI, it would create a 10.8 megabyte file
CodePudding user response:
First thing; There is better ways to do this but I want to write something clear and understandable.
Pseudo Code:
base = "";
for(x1=0; x1<charset.length(); x1 )
for(x2=0; x2<charset.length(); x2 )
for(x3=0; x3<charset.length(); x3 )
.
.
.
{ base = charset[x1] charset[x2] charset[x3] ..... charset[x6];
file.write(base "\n")
}
CodePudding user response:
the fastest way I can think of is using pypy3 https://www.pypy.org/ with this code:
import functools
import time
@functools.lru_cache(maxsize=128)
def a():
cs, cl = "0123456789abcdefghijklmnopqrstuvwxyz", []
for letter in cs:
cl.append(letter)
ct = tuple(cl)
with open("codes.txt", "w") as file:
for p1 in ct:
for p2 in ct:
for p3 in ct:
for p4 in ct:
for p5 in ct:
for p6 in ct:
file.write(f"{p1}{p2}{p3}{p4}{p5}{p6}\n")
file.close()
start = time.time()
a()
print(f"Done! \nTook {start - time.time()} seconds!")
It writes at around 10-15MB/s The total file is around 15GB I belive so it would take like 990-1500 seconds to generate. The results are on a vm of unraid with 1 3.4 ghz core of server cpu, with a sata3 old sdd, you will probably get better results with an NVME drive and a faster single core CPU.