So I'm working in javascript, and I need to generate a random number.
I know what you are saying:
"But rend, it is as simple as calling the date! It will be unique each millisecond!" To which I would respond...
"This simply is not random enough. I need something randomer."
So this is my problem. I need to randomly generate a unique number ALOT. The date would be fine, but sometimes I call this method more than once per millisecond, and so I need to figure out a way to generate something random, but unique, which is not based on what time it is.
The catch: Only javascript. No SSI, no nothing, nothing that JUST javascript couldn't run on a browser.
I'm looking for ideas, and so I thought I would address the lot of you for help.
Posts
?
What you need is better described as a GUID - globally unique identifier. It looks like javascript doesn't have a built in GUID function, but you can approximate the effect by concatenating a pseudorandom number and some string that is unique to the machine.
EDIT: Is (randomnumber)+(ip address) good enough?
var db = Math.Random();
while(db > rn)
{
db = Math.Random()
}
rn = rn/db;
If that's not random enough then you're using the wrong language.
we also talk about other random shit and clown upon each other
GUID is _exactly_ what i'm looking for. However...
How can i do that over the net? Like if you open a site with this javascript on it, how could I generate such a pseudorandom string with pure javascript, and not a whole lot of access?
That is what is stumping me. If I could figure a way to identify like that, I could just concatenate it onto the date, in milliseconds, and I'd be golden.
Yes, it would be. however, doesn't java lack the ability to find an IP address by itself, without the aid of SSI or somesuch?
This would indeed be random enough, but math.random() is seeded based on the time, so calling it twice in the same millisecond would result in the same number being generated twice in a row.
I assume that you've already ruled out doing it server-side?
Yes, I won't have access to anything but JS and client.
EDIT: That looks like a better link. I don't know what that weird commenty thing does, but I bet it does it server side.
If you really want, you can use the setTimeout function to specify a delay on the while loop, or what have you, and that will manually delay the other random calls.
But really, I don't think you need to, as Frylock clarified, just because it's using the same seed does NOT mean it's the same number.
we also talk about other random shit and clown upon each other
[EDIT] Otherwise I wouldn't even care- I could just seed a random number and append the date and it'd be way more than enough.
No, no activex, SSI, etc. Only pure javascript is allowable.
What are these "instances" of a Javascript program you're talking about?
First, this isn't Java, it's Javascript. Two totally different languages with unfortunately similar names (and syntax, sorta).
Second, you could use a running counter as a source of additional entropy, but the OP has failed to clarify exactly where and for what purpose these random numbers are being generated, and therefore it's unclear that they're even running in the same Javascript interpreter.
Okay, lemme elaborate on what I don't understand here:
You say you're generating lots and lots of random numbers, in Javascript, in a browser. However, you're only generating one random number per "instance of a program." Now as far as I know Javascript has no first-class concept of instances, so are you saying that you have lots of people on lots of different computers with lots of browsers all running your program at the same time? Are you saying you're opening 50 different iframes on a single browser and they're all executing Javascript simultaneously? Are you saying you're calling the same routine a bunch of different times in a single interpreter?
You're generating so many that you're worried about generating two in the same millisecond. Because each "instance of a program" has its own RNG, you're worried you'll seed two RNGs at the same millisecond and then generate the same random number. This is plausible but it depends on the exact scenario, which you haven't expressed clearly.
Is the goal to generate a random number without collisions? Because if you want to generate a random number with no collisions, that's different than just generating a random number (even with high entropy) because eventually you'll get a collision. A GUID isn't just a really random number, it's a particular form of nonce. Generating a GUID is very different from generating a (very) random number because GUIDs go out of their way to try to avoid collisions. RNGs don't do that.
Alright, sorry, let me try to be more clear about my purpose. The program is to generate one pseudorandom number per browser, per time the browser ups and loads the site. As long as it's unique, or almost unique, that's cool, the only problem is that due to the nature of the application, I'll be dealing with a high probability of several of the requests coming in at almost exactly the same time, some, in fact, at exactly the same time.
After testing, I do see doubles of some numbers (this number is being stored on file) because they came in the same millisecond. The problem is that it happens often, again, just due to the nature of the application. So I just need to cut the number of duplicates. For instance, I could use date(in milliseconds) + concatenate an IP address to achieve this process. Though I may very well achieve duplicates at some point, they would be rare enough not to be an issue.
So to be as clear as possible: Like a billion* people want to access the site, so they do. Each one is supposed to have a unique identifier, so I use the date. However, two people want to get this at the very same millisecond, which is understandable given the volume. Each browser runs the script on its own and then generates the UID to eventually be stored somewhere, so each browser seeds its own rng, so those two people, even if I rng'd a number to concatenate or multiply or use to take the nth derivative of, it would still be the same identifier. Such is why I need something unique (or at least close to it) to concatenate onto the date in order to make it unique.
2 caveats-
1. It doesn't have to be foolproof. Duplicates CAN occur, as long as they are sufficiently infrequent.
2. Another clever way of generating a random number not based on time is also acceptable.
*Total exaggeration.
ALSO! I am now going to look at Monolithic's solution, see if it's what I'm looking for.
A lot of these are accessible through various objects like the object. So there, you've got a number of entropy sources (some not available all the time, but that's OK) that can be used to increase the entropy of your nonces. You can either run them through something like a CRC32 (target space: about 4 billion) or MD5 (target space: > number of atoms in the known universe) to generate a number from these.
Yes, yes, this is precisely what I'm looking for. Considering I can only work in javascript (btw, monolithic: Thanks, but that one didn't work. It seems that java.inetaddress.etc etc is a java thing, and so it won't work with just jscript), what of those things would you personally recommend?
I'll go ahead and begin research on how exactly I can accomplish a couple of those (I really am not very good with javascript), but any more insight you or anyone else might have would be appreciated.
Here is a good reference for HTML's DOM (Dynamic Object Model).
In particular though, cursor position is a pain in the ass to figure out, since you access it through events. Basically, every time your mouse moves, an event is registered, and Javascript can pull the cursor location out of the event. And for Netscape-style browsers, events need to be captured too. Here's a sample showing how it's done.
I think everything else DrFrylock mentioned is accessible in the typical way through the document, window, screen, and navigator objects, though you might need to dig a bit.
EDIT:
What about a cookie? Stupid solution, but just give users a cookie the first time they access the site with a Math.random value in it, then just multiply that value with a fresh Math.random. Or better yet if possible, CRC both of them then XOR.