JavaScript中的高密度随机字符串

7

我目前使用这个函数(Create GUID / UUID in JavaScript?)在Javascript中生成UUID:

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);
    });
}

我知道所有的随机性都只来自于Javascript的Math.random()函数,而且我不在乎它是否符合UUID的RFC。我想要的是在Javascript字符串中尽可能地压缩尽量多的随机性。上述函数提供了大约128位的随机性。在Javascript中,我可以将128位随机性压缩到多小的字符串(以UTF8字节形式发送到HTTP POST)?如何生成这样的字符串?
编辑:当发送到服务器时,该字符串将是JSON对象的一部分,因此在字符串中需要转义的字符并不是很有用。
3个回答

2
这里是我想到的一个潜在函数。种子字符串是未保留的URL字符集(共66个)。我用大约一年的1秒分辨率时间戳数据作为随机数的前缀,这对我的特定应用程序很有帮助,因为碰撞空间随时间只会逐渐填满(极端情况下每秒最多只生成几百个)。
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;
}

你的想法是什么?

0

你的问题有些矛盾。Javascript字符串使用UCS-2(固定16位字符)作为其内部表示。但是UTF-8是可变宽度的,但是为了编码目的,我认为最紧凑的形式是使用1字节UTF8字符,这只需要最高有效位为零。也就是说,你可以将128位打包成128 * 8/7 = 147位。

转换为字节并向上取整,你可以用19个字符来表示。


0

128位 = 16字节 -> base64 -> 16 * 3/2 = 将给您一个24个字符的字符串(相对于您现有的36个字符)

您也可以使用base85以获得更好的密度,但这将需要URL编码,因此您可能会得到比您现有的结果更差的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接