1

Can any one please suggest me a unique random string generator in python.
I have used uuid.uuid1() before which is not good since it is showing some irregularities in different operating systems. You need to import uuid ahead of all the packages in a project for issue-less working which is not a good practice.
I have also heard about os.urandom(n) which uses /dev/random. Is its entropy good enough ?? I am not sure about that.
I can't afford a collision of strings in my process.
Is there any other method can help me in this ?

5
  • 4
    even if you achieved true randomness, it wouldn't prevent collisions. Commented Jun 6, 2013 at 12:57
  • is there any solution which has least chances of collisions ?? Commented Jun 6, 2013 at 12:59
  • 1
    if you use a random generator, collisions are unlikely, but not impossible, so you have to take care of it. If you want truely unique numbers, then you may use a timestamp based number. Commented Jun 6, 2013 at 13:01
  • Dats what i am planning to do now... postpending timestamp with os.urandom(n) coz i read somewhere that in urandom after 4 billion iteration there is a chance of collision of 1 in 8 billion. Dats good enough for me. Commented Jun 6, 2013 at 13:15
  • What you read there about urandom is incomplete without the information how long the sample drawn out of urandom is. urandom delivers an endless stream of bytes. If your sample is just one byte long, then the chance to have a collision reaches 1 already at the 257th sample. Commented Feb 14, 2014 at 11:00

1 Answer 1

7

What about the random and string modules?

>>> import string
>>> import random
>>> ''.join(random.sample(string.letters*5,5))
'QcQxx'

Explanation:

>>> string.letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

I multiply it by 5 so it can be even more random. The higher the number, the more duplicates you are more likely to obtain.

random.sample(k, n) returns n random elements from string.letters, but returns it as a list.

''.join() is called to join the list into a simple string.

Sign up to request clarification or add additional context in comments.

4 Comments

I made an error upvoting, sorry. This solution won't repeat letters, and as such is not really random.
I've used ''.join(random.choice(string.letters) for i in range(DESIRED_LENGTH)), which addresses @Agos's concern. Still no guarantees against duplicates, but a sufficiently long string should be sufficient for use around the house.
You can also use itertools.combinations_with_replacement() and then use the random.choice() to select from that. Or if you want to guarantee that a string never occurs twice (but at the cost of a bit of memory), you can do convert the generator from combinations_with_replacement() to a list, then use random.shuffle() to randomize the sequence and pop() off the strings one by one.
The solution in the answer does not scale. Consider the case you want a 1GB long random letter string. You'd create a 52GB long string for that first. Also, by using random.sample in this way, the first letters influence the following. For a combination of two letters, the chance for a double (two equal letters) should be ¹/₅₂; using this technique it is only ¹/₁₀₃.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.