The new forums will be named Coin Return (based on the most recent vote)! You can check on the status and timeline of the transition to the new forums here.
The Guiding Principles and New Rules document is now in effect.

Javascript: Help me make my numbers even randomer!

RendRend Registered User regular
edited August 2008 in Help / Advice Forum
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.

Rend on

Posts

  • Monolithic_DomeMonolithic_Dome Registered User regular
    edited July 2008
    Have you tried calling Math.random()

    ?

    Monolithic_Dome on
    [SIGPIC][/SIGPIC]
  • RendRend Registered User regular
    edited July 2008
    Doesn't the seed for math.random() rely on the time? In which case the random numbers from the two instances which take place on the same millisecond would be the same, and thus result in the same number?

    Rend on
  • Monolithic_DomeMonolithic_Dome Registered User regular
    edited July 2008
    Oh, so it needs to be random and unique across instances?

    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?

    Monolithic_Dome on
    [SIGPIC][/SIGPIC]
  • JasconiusJasconius sword criminal mad onlineRegistered User regular
    edited July 2008
    var rn = Math.Random() * Math.Random()

    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.

    Jasconius on
    this is a discord of mostly PA people interested in fighting games: https://discord.gg/DZWa97d5rz

    we also talk about other random shit and clown upon each other
  • RendRend Registered User regular
    edited July 2008
    Oh, so it needs to be random and unique across instances?

    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.

    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.

    Rend on
  • RendRend Registered User regular
    edited July 2008
    Oh, so it needs to be random and unique across instances?

    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?

    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?

    Rend on
  • RendRend Registered User regular
    edited July 2008
    Jasconius wrote: »
    var rn = Math.Random() * Math.Random()

    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.

    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.

    Rend on
  • Monolithic_DomeMonolithic_Dome Registered User regular
    edited July 2008
    Jasc, besides the fact that your code could infinite loop, Two instances of Math.random() that are seeded at the same time will produce the same results.

    Monolithic_Dome on
    [SIGPIC][/SIGPIC]
  • Monolithic_DomeMonolithic_Dome Registered User regular
    edited July 2008
    Rend wrote: »
    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?

    I assume that you've already ruled out doing it server-side?

    Monolithic_Dome on
    [SIGPIC][/SIGPIC]
  • RendRend Registered User regular
    edited July 2008
    Rend wrote: »
    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?

    I assume that you've already ruled out doing it server-side?

    Yes, I won't have access to anything but JS and client.

    Rend on
  • Monolithic_DomeMonolithic_Dome Registered User regular
    edited July 2008
    Also, I don't really know whether this is cross-platform, but looks like you can get what you need by javascript alone

    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.

    Monolithic_Dome on
    [SIGPIC][/SIGPIC]
  • wasted pixelswasted pixels Registered User regular
    edited August 2008
    Is ActiveX an option here? Something like guid = new ActiveXObject("Scriptlet.TypeLib").guid.substring(0, 38); would do the job, but that's kind of old-school.

    wasted pixels on
  • DrFrylockDrFrylock Registered User regular
    edited August 2008
    I'm not sure about the Javascript implementation, but I think you misunderstand what a random seed is. It's a SEED. The RNG is seeded ONCE from the current time, and then each subsequent call to Random() will give you a random value. In general, two random number generators created from the same seed will generate the same sequence of random numbers. But I'm pretty sure you're not correct that it simply takes a function of the current time every time it's called.

    DrFrylock on
  • JasconiusJasconius sword criminal mad onlineRegistered User regular
    edited August 2008
    It is highly unlikely it will generate the same number twice, and if it does it's not because it was called in the same millisecond.


    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.

    Jasconius on
    this is a discord of mostly PA people interested in fighting games: https://discord.gg/DZWa97d5rz

    we also talk about other random shit and clown upon each other
  • RendRend Registered User regular
    edited August 2008
    t. Frylock and Jasconius, the random number will only generate once in each instance of the program. That's why two times in the same millisecond will achieve the same result-- because each random number has to have its own seed.

    [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.

    Rend on
  • RendRend Registered User regular
    edited August 2008
    Is ActiveX an option here? Something like guid = new ActiveXObject("Scriptlet.TypeLib").guid.substring(0, 38); would do the job, but that's kind of old-school.

    No, no activex, SSI, etc. Only pure javascript is allowable.

    Rend on
  • DrFrylockDrFrylock Registered User regular
    edited August 2008
    Rend wrote: »
    t. Frylock and Jasconius, the random number will only generate once in each instance of the program. That's why two times in the same millisecond will achieve the same result-- because each random number has to have its own seed.

    What are these "instances" of a Javascript program you're talking about?

    DrFrylock on
  • GdiguyGdiguy San Diego, CARegistered User regular
    edited August 2008
    can you not seed it with the time plus some running counter variable in java? (warning: i know zero java)

    Gdiguy on
  • DrFrylockDrFrylock Registered User regular
    edited August 2008
    can you not seed it with the time plus some running counter variable in java? (warning: i know zero java)

    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.

    DrFrylock on
  • RendRend Registered User regular
    edited August 2008
    Frylock:

    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.

    Rend on
  • DrFrylockDrFrylock Registered User regular
    edited August 2008
    That makes a lot more sense. What you want to generate is something like a cryptographic nonce, not just a random number. To do this, you need more sources of entropy. Sources at your disposal include:
    • The current time
    • The IP address of the machine (maybe available)
    • The position or movement of the mouse cursor
    • The size or location of the browser Window
    • The browser's user-agent string
    • MIME types supported by the browser (NS/FF only)
    • List of plugins installed in the browser (NS/FF only)

    A lot of these are accessible through various objects like the
    navigator
    
    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.

    DrFrylock on
  • RendRend Registered User regular
    edited August 2008
    DrFrylock wrote: »
    That makes a lot more sense. What you want to generate is something like a cryptographic nonce, not just a random number. To do this, you need more sources of entropy. Sources at your disposal include:
    • The current time
    • The IP address of the machine (maybe available)
    • The position or movement of the mouse cursor
    • The size or location of the browser Window
    • The browser's user-agent string
    • MIME types supported by the browser (NS/FF only)
    • List of plugins installed in the browser (NS/FF only)

    A lot of these are accessible through various objects like the
    navigator
    
    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.

    Rend on
  • Monolithic_DomeMonolithic_Dome Registered User regular
    edited August 2008
    That's why I hate looking for answers on web programming stuff. Every time you look for an answer "how do I do X using language Y" the answer is always "use Z" as if I could (or wanted to) just wave my magic wand and have Z installed on the server, clients, and whatever else.

    Monolithic_Dome on
    [SIGPIC][/SIGPIC]
  • hippofanthippofant ティンク Registered User regular
    edited August 2008
    Rend wrote: »
    DrFrylock wrote: »
    That makes a lot more sense. What you want to generate is something like a cryptographic nonce, not just a random number. To do this, you need more sources of entropy. Sources at your disposal include:
    • The current time
    • The IP address of the machine (maybe available)
    • The position or movement of the mouse cursor
    • The size or location of the browser Window
    • The browser's user-agent string
    • MIME types supported by the browser (NS/FF only)
    • List of plugins installed in the browser (NS/FF only)

    A lot of these are accessible through various objects like the
    navigator
    
    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.

    hippofant on
  • LegionnairedLegionnaired Registered User regular
    edited August 2008
    Out of curiosity, if JS is a client-side-only language, why would it matter if two users have the same GUID assigned to them? It seems like a problem easily solved by just having whatever server generate the GUID?

    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.

    Legionnaired on
Sign In or Register to comment.