javascript - vue - 前端生成uuid
在JavaScript中创建GUID/UUID? (20)
Web服务很有用。
快速谷歌发现: http://www.hoskinson.net/GuidGenerator/ : http://www.hoskinson.net/GuidGenerator/
无法担保此实现,但SOMEONE必须发布一个真正的GUID生成器。
使用这样的Web服务,您可以开发一个使用GUID Web服务的REST Web界面,并通过AJAX将其提供给浏览器中的javascript。
我正在尝试在JavaScript中创建全局唯一标识符。 我不确定所有浏览器上可用的例程,“随机”和内置随机数生成器的种子等等。
GUID / UUID应至少为32个字符,并应保持在ASCII范围内,以避免传递它们时出现问题。
broofa的答案非常光滑,确实 - 令人印象深刻的聪明,真的... rfc4122兼容,有点可读,紧凑。 真棒!
但是如果你正在查看那个正则表达式,那些很多replace()
回调, toString()
和Math.random()
函数调用(他只使用4位结果并浪费其余部分),你可以开始想知道表现。 实际上,joelpt甚至决定使用generateQuickGUID
将RFC转换为通用GUID速度。
但是,我们能否获得速度和 RFC合规性? 我说是! 我们能保持可读性吗? 嗯...不是真的,但是如果你跟着它就很容易。
但首先,我的结果,与broofa, guid
(接受的答案)和非rfc兼容的generateQuickGuid
:
Desktop Android
broofa: 1617ms 12869ms
e1: 636ms 5778ms
e2: 606ms 4754ms
e3: 364ms 3003ms
e4: 329ms 2015ms
e5: 147ms 1156ms
e6: 146ms 1035ms
e7: 105ms 726ms
guid: 962ms 10762ms
generateQuickGuid: 292ms 2961ms
- Note: 500k iterations, results will vary by browser/cpu.
因此,通过我的第6次优化迭代,我击败了最受欢迎的答案超过12 倍 ,接受的答案超过9 倍 ,而快速不符合要求的答案为2-3 倍 。 我仍然符合rfc4122标准。
对如何感兴趣? 我已将完整的资源放在http://jsfiddle.net/jcward/7hyaC/3/和http://jsperf.com/uuid-generator-opt/4
要解释一下,让我们从broofa的代码开始:
'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);
});
所以它用任意随机十六进制数字替换x
, y
用随机数据替换(除了根据RFC规范强制前2位到10
),并且正则表达式与-
或4
字符不匹配,因此他不必处理跟他们。 非常非常光滑。
首先要知道的是函数调用是很昂贵的,正则表达式也是如此(尽管他只使用1,它有32个回调,每个匹配一个,并且在32个回调中的每个回调中都调用Math.random()和v。的toString(16))。
性能的第一步是消除RegEx及其回调函数,而是使用简单的循环。 这意味着我们必须处理-
和4
字符,而broofa没有。 另外,请注意我们可以使用String Array索引来保持其光滑的String模板体系结构:
function e1() {
var u='',i=0;
while(i++<36) {
var c='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'[i-1],r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16)
}
return u;
}
基本上,相同的内部逻辑,除了我们检查-
或4
,并使用while循环(而不是replace()
回调)使我们几乎提高了3倍!
下一步是桌面上的一个小步骤,但在移动设备上有一个不错的区别。 让我们减少Math.random()调用并利用所有这些随机位,而不是使用随机缓冲区抛出87%的随机缓冲区,每次迭代都会移出它们。 让我们也将该模板定义移出循环,以防它有所帮助:
function e2() {
var u='',m='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=m[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16);rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
这节省了10-30%,具体取决于平台。 不错。 但是下一个重要的步骤完全消除了toString函数调用与优化经典 - 查找表。 一个简单的16元素查找表将在更短的时间内执行toString(16)的工作:
function e3() {
var h='0123456789abcdef';
var k='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
/* same as e4() below */
}
function e4() {
var h=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
var k=['x','x','x','x','x','x','x','x','-','x','x','x','x','-','4','x','x','x','-','y','x','x','x','-','x','x','x','x','x','x','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=k[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:h[v];rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
下一个优化是另一个经典。 由于我们在每次循环迭代中只处理4位输出,所以让我们将循环次数减半,每次迭代处理8位。 这很棘手,因为我们仍然需要处理符合RFC的位位置,但这并不难。 然后我们必须创建一个更大的查找表(16x16或256)来存储0x00 - 0xff,我们只在e5()函数之外构建它一次。
var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e5() {
var k=['x','x','x','x','-','x','x','-','4','x','-','y','x','-','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<20) {
var c=k[i-1],r=rb&0xff,v=c=='x'?r:(c=='y'?(r&0x3f|0x80):(r&0xf|0x40));
u+=(c=='-')?c:lut[v];rb=i%4==0?Math.random()*0xffffffff|0:rb>>8
}
return u
}
我尝试了一次处理16位的e6(),仍然使用256个元素的LUT,它显示了优化的收益递减。 尽管迭代次数较少,但内部逻辑由于处理增加而变得复杂,并且在桌面上执行相同,并且在移动设备上只有约10%的速度。
要应用的最终优化技术 - 展开循环。 由于我们循环固定次数,因此我们可以在技术上手动完成这一切。 我用一个随机变量r尝试了一次,我不断重新分配,并且性能下降了。 但是有四个变量预先分配随机数据,然后使用查找表,并应用适当的RFC位,这个版本将它们全部抽取:
var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e7()
{
var d0 = Math.random()*0xffffffff|0;
var d1 = Math.random()*0xffffffff|0;
var d2 = Math.random()*0xffffffff|0;
var d3 = Math.random()*0xffffffff|0;
return lut[d0&0xff]+lut[d0>>8&0xff]+lut[d0>>16&0xff]+lut[d0>>24&0xff]+'-'+
lut[d1&0xff]+lut[d1>>8&0xff]+'-'+lut[d1>>16&0x0f|0x40]+lut[d1>>24&0xff]+'-'+
lut[d2&0x3f|0x80]+lut[d2>>8&0xff]+'-'+lut[d2>>16&0xff]+lut[d2>>24&0xff]+
lut[d3&0xff]+lut[d3>>8&0xff]+lut[d3>>16&0xff]+lut[d3>>24&0xff];
}
Modualized: http://jcward.com/UUID.js : UUID.generate()
- UUID.generate()
有趣的是,生成16字节的随机数据很容易。 整个技巧是以符合RFC的字符串格式表达它,并且用16字节的随机数据,一个展开的循环和查找表来完成它。
我希望我的逻辑是正确的 - 在这种繁琐的工作中犯错误很容易。 但输出对我来说很好。 我希望你通过代码优化享受这种疯狂的旅程!
建议:我的主要目标是展示和教授潜在的优化策略。 其他答案涵盖了重要的主题,如冲突和真正的随机数,这对于生成良好的UUID非常重要。
以下是2011年10月9日用户jed在https://gist.github.com/982883发表评论的解决方案:
UUIDv4 = function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)}
这实现了与当前评分最高的答案相同的目标,但是通过利用强制,递归和指数表示法,可以减少50多个字节。 对于那些好奇的工作方式,这里是旧版本函数的注释形式:
UUIDv4 =
function b(
a // placeholder
){
return a // if the placeholder was passed, return
? ( // a random number from 0 to 15
a ^ // unless b is 8,
Math.random() // in which case
* 16 // a random number from
>> a/4 // 8 to 11
).toString(16) // in hexadecimal
: ( // or otherwise a concatenated string:
[1e7] + // 10000000 +
-1e3 + // -1000 +
-4e3 + // -4000 +
-8e3 + // -80000000 +
-1e11 // -100000000000,
).replace( // replacing
/[018]/g, // zeroes, ones, and eights with
b // random hex digits
)
}
以下是最高投票答案的组合,以及针对Chrome碰撞的解决方法:
generateGUID = (typeof(window.crypto) != 'undefined' &&
typeof(window.crypto.getRandomValues) != 'undefined') ?
function() {
// If we have a cryptographically secure PRNG, use that
// https://.com/questions/6906916/collisions-when-generating-uuids-in-javascript
var buf = new Uint16Array(8);
window.crypto.getRandomValues(buf);
var S4 = function(num) {
var ret = num.toString(16);
while(ret.length < 4){
ret = "0"+ret;
}
return ret;
};
return (S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));
}
:
function() {
// Otherwise, just use Math.random
// https://.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
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);
});
};
在jsbin上,如果你想测试它。
对于符合RFC4122版本4的解决方案,这种RFC4122 (ish)解决方案是我能想到的最紧凑的解决方案:
function uuidv4() {
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);
});
}
console.log(uuidv4())
更新,2015-06-02 :请注意,UUID唯一性在很大程度上依赖于底层随机数生成器(RNG)。 上面的解决方案使用Math.random()
来简洁,但Math.random()
不能保证是高质量的RNG。 有关详细信息,请参阅Adam Hyland 关于Math.random()的优秀文章 。 对于更强大的解决方案,请考虑类似uuid模块 [免责声明:我是作者],它使用更高质量的RNG API。
更新,2015-08-26 :作为附注,这个gist描述了如何确定在达到一定的碰撞概率之前可以生成多少个ID。 例如,对于3.26x10 15版本4 RFC4122 UUID,您有一个百万分之一的碰撞机会。
更新,2017-06-28 : Chrome开发人员在Chrome,Firefox和Safari中讨论Math.random PRNG质量状态的好文章 。 tl; dr - 截至2015年底,它“非常好”,但不是加密质量。 为了解决这个问题,这里是上述解决方案的更新版本,该解决方案使用ES6, crypto
API和一些JS向导,我不能相信 :
function uuidv4() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
)
}
console.log(uuidv4());
对于那些想要符合rfc4122版本4的解决方案而需要速度考虑的人(很少调用Math.random()):
function UUID() {
var nbr, randStr = "";
do {
randStr += (nbr = Math.random()).toString(16).substr(2);
} while (randStr.length < 30);
return [
randStr.substr(0, 8), "-",
randStr.substr(8, 4), "-4",
randStr.substr(12, 3), "-",
((nbr*4|0)+8).toString(16), // [89ab]
randStr.substr(15, 3), "-",
randStr.substr(18, 12)
].join("");
}
上述功能应该在速度和随机性之间保持适当的平衡。
我真的很喜欢Broofa的答案是多么干净,但不幸的是, Math.random
糟糕实现留下了碰撞的机会。
这是一个类似的ietf.org/rfc/rfc4122.txt版本4兼容解决方案,通过将前13个十六进制数字偏移时间戳的十六进制部分来解决该问题。 这样,即使Math.random
在同一个种子上,两个客户端都必须在完全相同的毫秒(或10,000多年后)生成UUID才能获得相同的UUID:
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();
if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
d += performance.now(); //use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
更好的方法:
function(
a,b // placeholders
){
for( // loop :)
b=a=''; // b - result , a - numeric variable
a++<36; //
b+=a*51&52 // if "a" is not 9 or 14 or 19 or 24
? // return a random number or 4
(
a^15 // if "a" is not 15
? // genetate a random number from 0 to 15
8^Math.random()*
(a^20?16:4) // unless "a" is 20, in which case a random number from 8 to 11
:
4 // otherwise 4
).toString(16)
:
'-' // in other cases (if "a" is 9,14,19,24) insert "-"
);
return b
}
最小化:
function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b}
来自sagi shkedy的技术博客 :
function generateGuid() {
var result, i, j;
result = '';
for(j=0; j<32; j++) {
if( j == 8 || j == 12|| j == 16|| j == 20)
result = result + '-';
i = Math.floor(Math.random()*16).toString(16).toUpperCase();
result = result + i;
}
return result;
}
还有其他方法涉及使用ActiveX控件,但远离这些!
编辑:我认为值得指出的是没有GUID生成器可以保证唯一键(查看维基百科文章 )。 始终存在碰撞的可能性。 GUID只提供足够大的键,以将碰撞的变化减少到几乎为零。
简单的JavaScript模块作为此线程中最佳答案的组合。
var crypto = window.crypto || window.msCrypto || null; // IE11 fix
var Guid = Guid || (function() {
var EMPTY = '00000000-0000-0000-0000-000000000000';
var _padLeft = function(paddingString, width, replacementChar) {
return paddingString.length >= width ? paddingString : _padLeft(replacementChar + paddingString, width, replacementChar || ' ');
};
var _s4 = function(number) {
var hexadecimalResult = number.toString(16);
return _padLeft(hexadecimalResult, 4, '0');
};
var _cryptoGuid = function() {
var buffer = new window.Uint16Array(8);
window.crypto.getRandomValues(buffer);
return [_s4(buffer[0]) + _s4(buffer[1]), _s4(buffer[2]), _s4(buffer[3]), _s4(buffer[4]), _s4(buffer[5]) + _s4(buffer[6]) + _s4(buffer[7])].join('-');
};
var _guid = function() {
var currentDateMilliseconds = new Date().getTime();
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(currentChar) {
var randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0;
currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16);
return (currentChar === 'x' ? randomChar : (randomChar & 0x7 | 0x8)).toString(16);
});
};
var create = function() {
var hasCrypto = crypto != 'undefined' && crypto !== null,
hasRandomValues = typeof(window.crypto.getRandomValues) != 'undefined';
return (hasCrypto && hasRandomValues) ? _cryptoGuid() : _guid();
};
return {
newGuid: create,
empty: EMPTY
};
})();
// DEMO: Create and show GUID
console.log(Guid.newGuid());
用法:
Guid.newGuid()
“c6c2d12f-d76b-5739-e551-07e6de5b0807”
Guid.empty
“00000000-0000-0000-0000-000000000000”
这只是一个简单的AJAX调用......
如果有人仍然感兴趣,这是我的解决方案。
在服务器端:
[WebMethod()]
public static string GenerateGuid()
{
return Guid.NewGuid().ToString();
}
在客户端:
var myNewGuid = null;
PageMethods.GenerateGuid(
function(result, userContext, methodName)
{
myNewGuid = result;
},
function()
{
alert("WebService call failed.");
}
);
这是一个完全不兼容但非常高性能的实现,用于生成类似于ASCII的GUID类唯一标识符。
function generateQuickGuid() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
生成26个[a-z0-9]字符,产生的UID比RFC兼容的GUID更短且更独特。 如果人类可读性很重要,可以简单地添加虚线。
以下是此功能的使用示例和时间以及此问题的其他几个答案。 计时在Chrome m25下进行,每次迭代1000万次。
>>> generateQuickGuid()
"nvcjf1hs7tf8yyk4lmlijqkuo9"
"yq6gipxqta4kui8z05tgh9qeel"
"36dh5sec7zdj90sk2rx7pjswi2"
runtime: 32.5s
>>> GUID() // John Millikin
"7a342ca2-e79f-528e-6302-8f901b0b6888"
runtime: 57.8s
>>> regexGuid() // broofa
"396e0c46-09e4-4b19-97db-bd423774a4b3"
runtime: 91.2s
>>> createUUID() // Kevin Hakanson
"403aa1ab-9f70-44ec-bc08-5d5ac56bd8a5"
runtime: 65.9s
>>> UUIDv4() // Jed Schmidt
"f4d7d31f-fa83-431a-b30c-3e6cc37cc6ee"
runtime: 282.4s
>>> Math.uuid() // broofa
"5BD52F55-E68F-40FC-93C2-90EE069CE545"
runtime: 225.8s
>>> Math.uuidFast() // broofa
"6CB97A68-23A2-473E-B75B-11263781BBE6"
runtime: 92.0s
>>> Math.uuidCompact() // broofa
"3d7b7a06-0a67-4b67-825c-e5c43ff8c1e8"
runtime: 229.0s
>>> bitwiseGUID() // jablko
"baeaa2f-7587-4ff1-af23-eeab3e92"
runtime: 79.6s
>>>> betterWayGUID() // Andrea Turri
"383585b0-9753-498d-99c3-416582e9662c"
runtime: 60.0s
>>>> UUID() // John Fowler
"855f997b-4369-4cdb-b7c9-7142ceaf39e8"
runtime: 62.2s
这是时间码。
var r;
console.time('t');
for (var i = 0; i < 10000000; i++) {
r = FuncToTest();
};
console.timeEnd('t');
GitHub上的JavaScript项目 - https://github.com/LiosK/UUID.js
UUID.js适用于JavaScript的符合RFC的UUID生成器。
请参阅RFC 4122 ietf.org/rfc/rfc4122.txt。
功能生成符合RFC 4122的UUID。
版本4 UUID(来自随机数的UUID)和版本1 UUID(基于时间的UUID)可用。
UUID对象允许对UUID的各种访问,包括对UUID字段的访问。
JavaScript的低时间戳分辨率由随机数补偿。
嗯,这已经有了很多答案,但不幸的是,这一堆中没有“真正的”随机。下面的版本是对broofa答案的改编,但更新后包含一个“真正的”随机函数,它在可用的情况下使用加密库,而Alea()函数作为后备函数。
Math.log2 = Math.log2 || function(n){ return Math.log(n) / Math.log(2); }
Math.trueRandom = (function() {
var crypt = window.crypto || window.msCrypto;
if (crypt && crypt.getRandomValues) {
// if we have a crypto library, use it
var random = function(min, max) {
var rval = 0;
var range = max - min;
if (range < 2) {
return min;
}
var bits_needed = Math.ceil(Math.log2(range));
if (bits_needed > 53) {
throw new Exception("We cannot generate numbers larger than 53 bits.");
}
var bytes_needed = Math.ceil(bits_needed / 8);
var mask = Math.pow(2, bits_needed) - 1;
// 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111
// Create byte array and fill with N random numbers
var byteArray = new Uint8Array(bytes_needed);
crypt.getRandomValues(byteArray);
var p = (bytes_needed - 1) * 8;
for(var i = 0; i < bytes_needed; i++ ) {
rval += byteArray[i] * Math.pow(2, p);
p -= 8;
}
// Use & to apply the mask and reduce the number of recursive lookups
rval = rval & mask;
if (rval >= range) {
// Integer out of acceptable range
return random(min, max);
}
// Return an integer that falls within the range
return min + rval;
}
return function() {
var r = random(0, 1000000000) / 1000000000;
return r;
};
} else {
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagøe <[email protected]>, 2010
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
mash.version = 'Mash 0.9';
return mash;
}
// From http://baagoe.com/en/RandomMusings/javascript/
function Alea() {
return (function(args) {
// Johannes Baagøe <[email protected]>, 2010
var s0 = 0;
var s1 = 0;
var s2 = 0;
var c = 1;
if (args.length == 0) {
args = [+new Date()];
}
var mash = Mash();
s0 = mash(' ');
s1 = mash(' ');
s2 = mash(' ');
for (var i = 0; i < args.length; i++) {
s0 -= mash(args[i]);
if (s0 < 0) {
s0 += 1;
}
s1 -= mash(args[i]);
if (s1 < 0) {
s1 += 1;
}
s2 -= mash(args[i]);
if (s2 < 0) {
s2 += 1;
}
}
mash = null;
var random = function() {
var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
s0 = s1;
s1 = s2;
return s2 = t - (c = t | 0);
};
random.uint32 = function() {
return random() * 0x100000000; // 2^32
};
random.fract53 = function() {
return random() +
(random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
};
random.version = 'Alea 0.9';
random.args = args;
return random;
}(Array.prototype.slice.call(arguments)));
};
return Alea();
}
}());
Math.guid = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.trueRandom() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
};
有一个jQuery插件可以很好地处理Guid的http://plugins.jquery.com/project/GUID_Helper
jQuery.Guid.Value()
返回内部Guid的值。如果未指定guid,则返回一个新值(然后在内部存储值)。
jQuery.Guid.New()
返回一个新的Guid并在内部设置它的值。
jQuery.Guid.Empty()
返回空Guid 00000000-0000-0000-0000-000000000000。
jQuery.Guid.IsEmpty()
返回布尔值。如果为空/未定义/空/空,则为真。
jQuery.Guid.IsValid()
返回布尔值。真正有效的guid,如果没有,则为false。
jQuery.Guid.Set()
Retrns Guid。将Guid设置为用户指定的Guid,如果无效,则返回空guid。
调整与一些额外的我自己的UUID / GUID发电机here。
我正在使用以下Kybos随机数生成器来加密声音。
下面是我的脚本,其中包含来自baagoe.com的Mash和Kybos方法。
//UUID/Guid Generator
// use: UUID.create() or UUID.createSequential()
// convenience: UUID.empty, UUID.tryParse(string)
(function(w){
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagøe <[email protected]>, 2010
//function Mash() {...};
// From http://baagoe.com/en/RandomMusings/javascript/
//function Kybos() {...};
var rnd = Kybos();
//UUID/GUID Implementation from http://frugalcoder.us/post/2012/01/13/javascript-guid-uuid-generator.aspx
var UUID = {
"empty": "00000000-0000-0000-0000-000000000000"
,"parse": function(input) {
var ret = input.toString().trim().toLowerCase().replace(/^[\s\r\n]+|[\{\}]|[\s\r\n]+$/g, "");
if ((/[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12}/).test(ret))
return ret;
else
throw new Error("Unable to parse UUID");
}
,"createSequential": function() {
var ret = new Date().valueOf().toString(16).replace("-","")
for (;ret.length < 12; ret = "0" + ret);
ret = ret.substr(ret.length-12,12); //only least significant part
for (;ret.length < 32;ret += Math.floor(rnd() * 0xffffffff).toString(16));
return [ret.substr(0,8), ret.substr(8,4), "4" + ret.substr(12,3), "89AB"[Math.floor(Math.random()*4)] + ret.substr(16,3), ret.substr(20,12)].join("-");
}
,"create": function() {
var ret = "";
for (;ret.length < 32;ret += Math.floor(rnd() * 0xffffffff).toString(16));
return [ret.substr(0,8), ret.substr(8,4), "4" + ret.substr(12,3), "89AB"[Math.floor(Math.random()*4)] + ret.substr(16,3), ret.substr(20,12)].join("-");
}
,"random": function() {
return rnd();
}
,"tryParse": function(input) {
try {
return UUID.parse(input);
} catch(ex) {
return UUID.empty;
}
}
};
UUID["new"] = UUID.create;
w.UUID = w.Guid = UUID;
}(window || this));
// RFC 4122
//
// A UUID is 128 bits long
//
// String representation is five fields of 4, 2, 2, 2, and 6 bytes.
// Fields represented as lowercase, zero-filled, hexadecimal strings, and
// are separated by dash characters
//
// A version 4 UUID is generated by setting all but six bits to randomly
// chosen values
var uuid = [
Math.random().toString(16).slice(2, 10),
Math.random().toString(16).slice(2, 6),
// Set the four most significant bits (bits 12 through 15) of the
// time_hi_and_version field to the 4-bit version number from Section
// 4.1.3
(Math.random() * .0625 /* 0x.1 */ + .25 /* 0x.4 */).toString(16).slice(2, 6),
// Set the two most significant bits (bits 6 and 7) of the
// clock_seq_hi_and_reserved to zero and one, respectively
(Math.random() * .25 /* 0x.4 */ + .5 /* 0x.8 */).toString(16).slice(2, 6),
Math.random().toString(16).slice(2, 14)].join('-');
var uniqueId = Math.random().toString(36).substring(2)
+ (new Date()).getTime().toString(36);
如果ID的生成间隔超过1毫秒,则它们是100%唯一的。
如果以较短的间隔生成两个ID,并且假设随机方法是真正随机的,那么这将产生99.99999999999999%可能是全局唯一的ID(在10 ^ 15中的1中发生冲突)
您可以通过添加更多数字来增加此数字,但要生成100%唯一ID,您需要使用全局计数器。
document.getElementById("unique").innerHTML =
Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
<div id="unique">
</div>