如何生成像“aX4j9Z”(在JS中)

对于我的web应用程序(在JavaScript中)我想生成简短的GUID(对于不同的对象 – 实际上是不同的types – string和string数组)

我想为我的uids(guids)这样的“aX4j9Z”。

所以这些用户界面应该足够轻量级,用于网页传输和jsstring处理,而且对于不是一个巨大的结构(不超过10k个元素)来说是相当独特的。 通过说“非常独特”,我的意思是,在uid的产生之后,我可以检查这个uid是否已经存在于结构中,如果是的话就重新生成。

我会appriciate任何意见。

请参阅@ Mohamed针对预包装解决scheme( shortid包 ) 的答案 。 如果您没有特殊要求,请select此页面上的任何其他解决scheme。


一个6字符的字母数字序列足以随机索引一个10k集合(36 6 = 22亿和36 3 = 46656)。

 function generateUID() { // I generate the UID from two parts here // to ensure the random number provide enough bits. var firstPart = (Math.random() * 46656) | 0; var secondPart = (Math.random() * 46656) | 0; firstPart = ("000" + firstPart.toString(36)).slice(-3); secondPart = ("000" + secondPart.toString(36)).slice(-3); return firstPart + secondPart; } 

在生成〜√N号码(生日悖论)后,随机生成的UID将会发生冲突,因此无需检查就可以安全生成6位数字(旧版本只生成4位数字,如果不检查,则会在1300个ID之后发生碰撞) 。

如果进行碰撞检查,则可以减less3位或4位的数字,但是请注意,当您生成越来越多的UID时,性能将会线性下降。

 var _generatedUIDs = {}; function generateUIDWithCollisionChecking() { while (true) { var uid = ("0000" + ((Math.random() * Math.pow(36, 4)) | 0).toString(36)).slice(-4); if (!_generatedUIDs.hasOwnProperty(uid)) { _generatedUIDs[uid] = true; return uid; } } } 

如果您需要唯一性而不是不可预测性,请考虑使用顺序生成器(例如user134_item1user134_item2 ,…)。 你可以“哈希”顺序生成的string来恢复不可预测性。

使用Math.random生成的UID不安全(无论如何您都不应该信任客户端)。 不要依赖任务关键任务中的独特性或不可预测性。

还有一个很简单的npm包: shortid

令人惊讶的是非简单的url友好的唯一ID生成器。

ShortId创build了非常短的非序列url友好唯一ID。 适用于url缩写,MongoDB和Redis ID以及其他ID用户可能会看到的内容。

  • 默认情况下为7-14个友好的字符:AZ,az,0-9,_-
  • 非顺序,所以他们不可预测。
  • 支持群集(自动),自定义种子,自定义字母表。
  • 可以生成任何数量的ID不重复,甚至每天几百万。
  • 完美的游戏,尤其是如果你担心作弊,所以你不想要一个容易猜测的ID。
  • 应用程序可以重新启动任何次数,而不必重复一个id。
  • Mongo ID / Mongoose ID的stream行替代品。
  • 在Node,io.js和Web浏览器中工作。
  • 包含摩卡testing。

用法

 var shortid = require('shortid'); console.log(shortid.generate()); //PPBqWA9 

以下产生62 ^ 3(238,328)三个字符的唯一值,只要大小写敏感性是唯一的,并且数字在所有位置都是允许的。 如果不区分大小写,则从string中删除大写或小写字符,它将生成35 ^ 3(42975)个唯一值。

可以很容易地适应,使第一个字符总是一个字母,或所有的字母。

没有,但它可以被优化,也可以拒绝返回一个id时,达到极限。

 var nextId = (function() { var nextIndex = [0,0,0]; var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); var num = chars.length; return function() { var a = nextIndex[0]; var b = nextIndex[1]; var c = nextIndex[2]; var id = chars[a] + chars[b] + chars[c]; a = ++a % num; if (!a) { b = ++b % num; if (!b) { c = ++c % num; } } nextIndex = [a, b, c]; return id; } }()); 

这将生成一系列唯一的值。 当所有的值已经被排除时,它通过增加string长度来改进RobG的答案。

 var IdGenerator = (function () { var defaultCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-+=[]{};:?/.>,<|".split(""); var IdGenerator = function IdGenerator(charset) { this._charset = (typeof charset === "undefined") ? defaultCharset : charset; this.reset(); }; IdGenerator.prototype._str = function () { var str = "", perm = this._perm, chars = this._charset, len = perm.length, i; for (i = 0; i < len; i++) { str += chars[perm[i]]; } return str; }; IdGenerator.prototype._inc = function () { var perm = this._perm, max = this._charset.length - 1, i; for (i = 0; true; i++) { if (i > perm.length - 1) { perm.push(0); return; } else { perm[i]++; if (perm[i] > max) { perm[i] = 0; } else { return; } } } }; IdGenerator.prototype.reset = function () { this._perm = []; }; IdGenerator.prototype.current = function () { return this._str(); }; IdGenerator.prototype.next = function () { this._inc(); return this._str(); }; return IdGenerator; }).call(null); 

用法:

 var g = new IdGenerator(), i; for (i = 0; i < 100; i++) { console.log(g.next()); } 

这个要点包含上面的实现和一个recursion的版本。

 var letters = 'abcdefghijklmnopqrstuvwxyz'; var numbers = '1234567890'; var charset = letters + letters.toUpperCase() + numbers; function randomElement(array) { with (Math) return array[floor(random()*array.length)]; } function randomString(length) { var R = ''; for(var i=0; i<length; i++) R += randomElement(charset); return R; } 

您可以将GUID缩短为20个可打印的ASCII字符,而不会丢失GUID的信息或唯一性。

杰夫·阿特伍德(Jeff Atwood)在那年前的博客上写道
装备我们的ASCII装甲

只是随机生成一些string:

 function getUID(len){ var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', out = ''; for(var i=0, clen=chars.length; i<len; i++){ out += chars.substr(0|Math.random() * clen, 1); } // ensure that the uid is unique for this page return getUID.uids[out] ? getUID(len) : (getUID.uids[out] = out); } getUID.uids = {};