• (nodebb)

    Awkwardly and inefficiently and with a high probability of collisions due to bad randomness

    I would argue that this is a good example of "doesn't work" (especially the "high probability of collisions" part), and yet the article says that it does work...

    But then again:

    1. Why did it take until 2021 for JS to sprout a random-UUID function?

    2. Why would we want to generate UUIDs in the browser rather than in the server code? (The WTF-ness of this question may explain why it took so long...)

  • Hanzito (unregistered)
    1. The probability of collisions is very low. The built-in random functions are really good enough.

    2. It's just a random id, nothing else. You can't send a 128 bit number in a url or json, so formatting it as a uuid is probably fine.

    3. Nobody cares about the meta data in uuid, unless you mix different types (and I can't think of a reason why you ever would, although there's probably someone here who knows an obscure use case), but this code even takes that into account.

  • (nodebb) in reply to Steve_The_Cynic

    "Why would we want to generate UUIDs in the browser rather than in the server code?"

    Some APIs require that the client generates the id of a newly created resource. It's bad, but at least someone else is to blame for it.

  • (nodebb) in reply to Steve_The_Cynic

    Why would we want to generate UUIDs in the browser rather than in the server code? (The WTF-ness of this question may explain why it took so long...)

    CQRS

    When you have strict query/command separation, you don't really have return value(s) with your write operations. So if you want to create a new resource, you have to provide a unique identifier to find you resource again.

  • Jim Jam (unregistered) in reply to Melissa U

    It is not bad at all when a UUID is used as an idempotency key, as to prevent creating duplicates on network hiccup.

  • Industrial Automation Engineer (unregistered)

    the "4" in the string is the type of the identifier.

  • (nodebb)

    The proper thing to do is check whether crypto.randomUUID exists and use this only as a fallback.

  • Mark L (unregistered)

    Many years ago, in the days of Java 4, I used Java's UUID generator as it was at the time to generate unique ID's for channel identifiers in a messaging system. If I remember correctly, the UUID was constructed from three elements: the current time/date in milliseconds, the NIC address, and the base address of the process. Of course time of day is not guaranteed to be unique, but every machine has its own unique network card and every process in the machine has a different base address.

    The server consisted of several machines, processing messages in assembly-line fashion. Multiple instances of the components ran in parallel.

    We upgraded the server to fast new machines. Each new physical machine ran two virtual machines for two instances of a given component. When powered on, the machine automatically loaded the components.

    But now, messages started going to the wrong components. Because two channels got the same identifier. Two virtual machines shared the real machine's NIC. Each virtual machine loaded its first program at the same base address as the other one. And the new machines were so fast, both instances of the component made the UUID call within the same millisecond.

  • (nodebb)

    I want to hate every aspect of this, but it's actually fine. Not great, and only usable if security of the generated UUID isn't a concern (if it was, you shouldn't be doing it client-side). But modern javascript engines use a very good RNG with enough state-space that it can generate any valid UUID with uniform probability, and usually gets seeded itself with the OS's crypto RNG (e.g. dev/urandom or CryptGenRandom), so that's OK for just generating a non-secure ID. Using Math.random() % 16 hurts my soul, because that's what people do when they don't know about modulo bias, but in this case 16 is a power of 2, so again, that's fine. It's fine. It works. It would be more efficient to use 4 RNG calls to draw 128 bits (4 32-bit numbers) and adjust some bits in one (if it's really necessary to correctly identify these as V4 UUIDs, but I like Hanzito's point), and then turn each one into a hex-string. But this is OK. Unless efficiency or security becomes an issue.

  • Officer Johnny Holzkopf (unregistered)

    The use of a "template string" that is then overwritten with the actual data in the corresponding places reminds me of BASIC's "PRINT USING" instruction where the format string looked more like the code presented than what we know from C's printf() and its descendants. But it's not that I haven't seen similar approaches in other languages for other purposes, but for UUIDs, and with regex, well, that's surely something...

  • (nodebb) in reply to prueg

    Using Math.random() % 16 hurts my soul, because that's what people do when they don't know about modulo bias, but in this case 16 is a power of 2, so again, that's fine.

    Except that here it's multiplying by 16, not taking the modulo, because presumably JS's Math.random() returns a floating point number in [0,1). (But it does avoid the "lower bits are less random" problem of most simple PRNGs.) Heaven help us if the result is in [0,1]...

  • (nodebb) in reply to Steve_The_Cynic

    Why would we want to generate UUIDs in the browser rather than in the server code?

    Because JavaScript can also be your server! (Node.js and Deno)

  • (nodebb) in reply to Industrial Automation Engineer

    Or this: https://m.xkcd.com/221/

  • Jimbob (unregistered)

    More proof that there is no problem that cannot be solved by regular expressions.

  • (nodebb) in reply to Steve_The_Cynic

    Ah, that is true. However, there is still usually a bias of the same nature when multiplying a random floating point number by your desired range. You are mapping a value from a set of 2^53 possible values onto a smaller set, which only works uniformly when the range is a power of 2. As it is here. So still no problem.

  • FTB (unregistered)

    "....there is still usually a bias...etc"

    Yes, but with this many digits? Not a real problem.

  • FTB (unregistered)

    The real WTF is that Javascript still has no easy way to replace a char in the middle of a string.

    (even if it has to create a new string, there's still no function for that...)

    Also: That str[0] = 'x' doesn't give an error, it just does nothing.

  • NotYourLocalJavaWizard (unregistered)

    No one is going to comment the fact that they're searching for both x and y in a string containing only x and 4?

  • NotYourLocalJavaWizard (unregistered) in reply to NotYourLocalJavaWizard

    :facepalm: Now I find the y.

  • Old Timer (unregistered)

    As another old timer (who's name I've forgot) put it: What do you expect, a KB article titled "GUIDs will kill you in your sleep"? That was in response to a question about the use of database UUIDs, which had been added to a MS database engine to support replication.

    Except that they had been exposed as text strings, which required {curly braces} in some places, but not in others, and GUID tags in some places, but not in others, and broke indexing in some places, but not in others, and ....

    They made the perfect Globally Unique Identifier for when you want your record Identifier to be broken and sometimes cause your queries or stored procedures to fail.

  • Anthonyram (unregistered)
    Comment held for moderation.

Leave a comment on “Uniquely Expressed”

Log In or post as a guest

Replying to comment #:

« Return to Article