Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

High density random strings in Javascript

I'm currently generating UUIDs in Javascript with this function (Create GUID / UUID in JavaScript?):

lucid.uuid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
    });
}

I understand that all the randomness is only coming from Javascript's Math.random() function, and I don't care if it meets an RFC for a UUID. What I want is to pack as much randomness into as few bytes as possible in a Javascript string. The above function gives about 128 bits of randomness. How small of a string (as measured in UTF8 bytes sent over the wire in an HTTP POST) could I fit 128 bits into in Javascript? And how would I generate such a string?

Edit: This string will be part of a JSON object when sent to the server, so characters that need to be escaped in a string are not very helpful.

like image 428
Ben Dilts Avatar asked Aug 05 '11 22:08

Ben Dilts


1 Answers

Here is one potential function I came up with. The seed string is the set of unreserved URL characters (66 of them). I prefix the randomness with about a year's worth of 1-second-resolution timestamp data, which is helpful since the collision space for my particular application is only filled up reasonably slowly over time (only at MOST a few hundred of these generated per second in an extreme case).

uuidDense = function() {
    var seed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~';

    //Start the UUID with 4 digits of seed from the current date/time in seconds
    //(which is almost a year worth of second data).
    var seconds = Math.floor((new Date().getTime())/1000);

    var ret = seed[seconds % seed.length];
    ret += seed[Math.floor(seconds/=seed.length) % seed.length];
    ret += seed[Math.floor(seconds/=seed.length) % seed.length];
    ret += seed[Math.floor(seconds/=seed.length) % seed.length];

    for(var i = 0; i < 8; i++)
        ret += seed[Math.random()*seed.length|0];

    return ret;
}

Thoughts?

like image 75
Ben Dilts Avatar answered Nov 06 '22 22:11

Ben Dilts