Javascript 中的高密度随机字符串
我目前正在使用此函数在 Javascript 中生成 UUID(创建 GUID / UUID在 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);
});
}
我知道所有随机性仅来自 Javascript 的 Math.random() 函数,并且我不关心它是否符合 UUID 的 RFC。我想要的是将尽可能多的随机性打包到 Javascript 字符串中尽可能少的字节中。上面的函数给出了大约 128 位的随机性。在 Javascript 中,多小的字符串(以 HTTP POST 中通过线路发送的 UTF8 字节来测量)可以容纳 128 位?我将如何生成这样的字符串?
编辑:当发送到服务器时,该字符串将成为 JSON 对象的一部分,因此需要在字符串中转义的字符并不是很有帮助。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是我想出的一个潜在功能。种子字符串是一组未保留的 URL 字符(共 66 个)。我在随机性前添加了大约一年的 1 秒分辨率时间戳数据,这很有用,因为我的特定应用程序的冲突空间只会随着时间的推移而相当缓慢地填充(最多每秒生成几百个)一个极端的例子)。
想法?
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).
Thoughts?
128 位 = 16 字节 -> base64 ->; 16*3/2 = 将为您提供 24 个字符的字符串(而不是您拥有的 36 个字符)
您也可以使用 base85 以获得更好的密度,但这将需要 URL 编码,因此您可能会得到比您现在更糟糕的结果。
128 bits = 16 bytes -> base64 -> 16*3/2 = will give you string of 24 characters (versus 36 chars that you have)
You also can use base85 for better density but that will require URL encode so you may get even worse results than you have.
你的问题有点矛盾。 Javascript 字符串使用 UCS-2(固定 16 位字符)作为其内部表示。然而,UTF-8 是可变宽度的,但出于编码目的,我相信最紧凑的形式是使用 1 字节 UTF8 字符,这只需要最高有效位为零。即您可以将 128 位打包为 128 * 8/7 = 147 位。
转换为字节并向上舍入,您可以在 19 个字符内完成此操作。
Your question is somewhat contradictory. Javascript strings use UCS-2 (fixed 16-bit characters) for their internal representation. However UTF-8 is variable width, but for encoding purposes I believe the most compact form would be to use 1-byte UTF8 characters, which only require the most significant bit be zero. I.e. you could pack 128 bits into 128 * 8/7 = 147 bits.
Converting to bytes and rounding up, you could do this in 19 characters.