如何生成像“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_item1
, user134_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 = {};