tags:

views:

59

answers:

5

I want to generate unique random, N-valued key. This key can contain numbers and latin characters, i.e. A-Za-z0-9.

The only solution I am thinking about is something like this (pseudocode):

key = "";
smb = "ABC…abc…0123456789"; // allowed symbols
for (i = 0; i < N; i++) {
    key += smb[rnd(0, smb.length() - 1)]; // select symbol at random position
}

Is there any better solution? What can you suggest?

+3  A: 

I would look into GUIDs. From the Wikipedia entry, "the primary purpose of the GUID is to have a totally unique number," which sounds exactly like what you are looking for. There are several implementations out there that generate GUIDs, so it's likely you will not have to reinvent the wheel.

fbrereto
Thanks! GUID looks very elegant.
Bar
A: 

You could do a base64 encoding of some random data and remove the +, /, and = characters from the result? I don't know if this would make a predictable distribution. Also, it seems like more work that what you're doing now, which is a fine solution.

uosɐſ
+1  A: 

Keeping in mind that the whole field of cryptography relies on, amongst other things, making random numbers. Therefore the NSA, the CIA, and some of the best mathematicians in the world are working on this so I guarantee you that there are better ideas.

Me? I'd just do what fbrereto suggests, and just get a guid. Or look into cryptographic key generators, or y'know, some lava lamps and a camera.

Oh, and as to the code you have; depending on the language, you may need to seed the RNG, or it'll generate the same key every time.

Spike
Thanks. Sure, I do assign seed, but in elementary (and, maybe, poor) way. Something like **seed = currentSeconds + currentMilliseconds**. But I have some doubt about how bad/ok is this.
Bar
A lot of people use time() as the seed , since you never get the same value twice. If "currentSeconds" is "seconds since the epoch" then that'll do. Doesn't really matter if you use a guid anyway. Guid generators use the current time as part of their seed too.
Spike
A: 

Assuming you're using a language/library without an utterly pathetic random number generator, what you've got looks pretty good. N symbols uniformly distributed over a reasonable alphabet works for me, and no amount of applying fancier code is likely to make it more random (just slower).

(For the record, pathetic would include ditching the high-order bits of the underlying random numbers when choosing a value from the given range. While ideally all RNGs would make every bit equally random, in practice that's not so; the higher-order bits tend to be more random. This means that the modulus operator is totally the wrong thing to use when clamping to a restricted range.)

Donal Fellows
Really good randomness is surprisingly hard to make. Here's where windows got it wrong http://eprint.iacr.org/2007/419, SSL got it wrong http://www.drdobbs.com/windows/184409807 and where Linux got it wrong http://eprint.iacr.org/2006/086.pdf. I forget the details but I think the US warned Gorbachov of the 1991 Soviet coup d'état attempt, because of a less than completely random RNG in a Russian cryptosystem.
Spike
Bet the questioner doesn't need that level of security, not for what looks like a simple password generator. But then the important thing there is to not let any attacker have free rein to try to crack the passwords, and not to apply particularly fancy rules to generating the passwords in the first place; the amount of effort spent on security should be proportionate to the threat being protected against. Always.
Donal Fellows
+1  A: 

Whatever you do, if you wind up generating a key that uses all numbers and all letters, and if a person is ever going to see that key (which is likely if you are using numbers and letters), omit the characters l, I, 1, O, and 0. People get them confused.

Nothing in your post addresses the question of uniqueness. You're going to have to have some way of not generating the same key twice. Usually, when I need a unique key, I have some unique information to start with. I usually take a one-way hash like MD5, then there are ways to convert that to a key with varying degrees of readability:

  • Convert to hex
  • Base64 encode it
  • Use bits of of the key to index into a list of words.

Example: the unique string computed by hashing the part of this answer above the horizontal line is

abduction's brogue's melted bragger's

Norman Ramsey
Thanks for significant remark!
Bar