I did some testing on this, and I think the main problem is that you're writing in text mode.
Binary mode is faster, and you're only dealing with ASCII, so you might as well just spit out bytes rather than strings.
Here's my code:
import itertools
import time
def CreateTable(name,ASCIIList,size):
f = open(name + '.txt','w')
combo = itertools.product(ASCIIList, repeat = size)
for x in combo:
passwords = ''.join(x)
f.write(str(passwords) + '\n')
f.close()
def CreateTableBinary(name,ASCIIList,size):
f = open(name + '.txt', 'wb')
combo = itertools.product(ASCIIList, repeat = size)
for x in combo:
passwords = bytes(x)
f.write(passwords)
f.write(b'\n')
f.close()
def CreateTableBinaryFast(name,first,last,size):
f = open(name + '.txt', 'wb')
x = bytearray(chr(first) * size, 'ASCII')
while True:
f.write(x)
f.write(b'\n')
i = size - 1
while (x[i] == last) and (i > 0):
x[i] = first
i -= 1
if i == 0 and x[i] == last:
break
x[i] += 1
f.close()
def CreateTableTheoreticalMax(name,ASCIIList,size):
f = open(name + '.txt', 'wb')
combo = range(0, len(ASCIIList)**size)
passwords = b'A' * size
for x in combo:
f.write(passwords)
f.write(b'\n')
f.close()
print("writing real file in text mode")
start = time.time()
chars = [chr(x) for x in range(32, 126)]
CreateTable("c:/temp/output", chars, 4)
print("that took ", time.time() - start, "seconds.")
print("writing real file in binary mode")
start = time.time()
chars = bytes(range(32, 126))
CreateTableBinary("c:/temp/output", chars, 4)
print("that took ", time.time() - start, "seconds.")
print("writing real file in fast binary mode")
start = time.time()
CreateTableBinaryFast("c:/temp/output", 32, 125, size)
print("that took ", time.time() - start, "seconds.")
print("writing fake file at max speed")
start = time.time()
chars = [chr(x) for x in range(32, 126)]
CreateTableTheoreticalMax("c:/temp/output", chars, 4)
print("that took ", time.time() - start, "seconds.")
Output:
writing real file in text mode
that took 101.5869083404541 seconds.
writing real file in binary mode
that took 40.960529804229736 seconds.
writing real file in fast binary mode
that took 35.54869604110718 seconds.
writing fake file at max speed
that took 26.43029284477234 seconds.
So you can see a pretty big improvement just by switching to binary mode.
Also, there still seems to be some slack to take up, since omitting the itertools.product
and writing hard-coded bytes is even faster. Maybe you could write your own version of product
that directly output bytes-like objects. Not sure about that.
Edit: I had a go at a manual itertools.product
working directly on a bytearray. It's a bit faster - see "fast binary mode" in the code.