Generate a lot of random strings
<p>I have a method that will generate 50,000 <em>random</em> strings, save them all to a file, and then run through the file, and delete all duplicates of the strings that occur. Out of those 50,000 random strings, after using <code>set()</code> to generate unique ones, on average 63 of them are left. </p>

<p>Function to generate the strings:</p>

<pre><code>def random_strings(size=8, chars=string.ascii_uppercase + string.digits + string.ascii_lowercase):
    return ''.join(random.choice(chars) for _ in xrange(size))
</code></pre>

<p>Delete duplicates:</p>

<pre><code>    with open("dicts/temp_dict.txt", "a+") as data:
        created = 0
        while created != 50000:
            string = random_strings()
            data.write(string + "\n")
            created += 1
            sys.stdout.write("\rCreating password: {} out of 50000".format(created))
            sys.stdout.flush()

        print "\nRemoving duplicates.."
        with open("dicts\\rainbow-dict.txt", "a+") as rewrite:
            rewrite.writelines(set(data))
</code></pre>

<p>Example of before and after:
<a href="https://gist.github.com/Ekultek/a760912b40cb32de5f5b3d2fc580b99f" rel="nofollow">https://gist.github.com/Ekultek/a760912b40cb32de5f5b3d2fc580b99f</a></p>

<p>How can I generate completely random unique strings without duplicates?</p>

<p>You could guarantee unique strings by generating unique numbers, starting with a random number is a range that is 1/50000<sup>th</sup> of the total number of possibilities (62<sup>8</sup>). Then generate more random numbers, each time determining the window in which the next number can be selected. This is not <em>perfectly</em> random, but I believe it's practically close enough.</p>

<p>Then these numbers can each be converted to strings by considering a representation of a 62-base number. Here is the code, and a test at the end to check that indeed all 50000 strings are unique:</p>

<pre><code>import string
import random

def random_strings(count, size=8, chars=string.ascii_uppercase + string.digits + string.ascii_lowercase):
    max = len(chars) ** size - 1
    start = 0
    choices = []
    for i in range(0,count):
        start = random.randint(start, start + (max-start) // (count-i))
        digits = []
        temp = start
        while len(digits) &lt; size:
            temp, i = divmod(temp, len(chars))
            digits.append(chars[i])
        choices.append(''.join(digits))
        start += 1
    return choices

choices = random_strings(50000)
# optional shuffle, since they are produced in order of `chars`
random.shuffle(choices)
# Test: output how many distinct values there are:
print (len(set(choices)))
</code></pre>

<p>See it run on <a href="https://repl.it/Dz1g/2" rel="nofollow">repl.it</a></p>

<p>This produces your strings in linear time. With the above parameters you'll have the answer within a second on the average PC.</p>

python string python-2.7 random