对于我的Web应用程序(使用JavaScript),我想生成简短的指导(针对不同的对象-实际上是不同的类型-字符串和字符串数组)
我的uid(向导)需要类似“ aX4j9Z”的名称。
因此,这些uid应该足够轻便,可以进行Web传输和js字符串处理,并且对于不大的结构(不超过10k个元素)来说应该是非常独特的。说“非常独特”是指在生成uid之后,我可以检查该uid是否已经存在于结构中,如果存在则重新生成。
对于我的Web应用程序(使用JavaScript),我想生成简短的指导(针对不同的对象-实际上是不同的类型-字符串和字符串数组)
我的uid(向导)需要类似“ aX4j9Z”的名称。
因此,这些uid应该足够轻便,可以进行Web传输和js字符串处理,并且对于不大的结构(不超过10k个元素)来说应该是非常独特的。说“非常独特”是指在生成uid之后,我可以检查该uid是否已经存在于结构中,如果存在则重新生成。
Answers:
请参阅@Mohamed的答案以获取预打包的解决方案(shortid
package)。如果您没有特殊要求,请优先使用此页面上的其他解决方案。
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;
}
随机生成的UID在生成〜√N个数字后会发生冲突(生日悖论),因此需要6位数字才能安全生成而不进行检查(旧版本仅生成4位数字,如果不进行检查,则在1300个ID之后会发生冲突) 。
如果进行冲突检查,位数可以减少3或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
…)。您可以“哈希”顺序生成的字符串以恢复不可预测性。
使用生成的UIDMath.random
是不安全的(无论如何,您都不应该信任客户端)。难道不是依靠其在关键任务工作的独特性或不可预测性。
+ "1000"
这么做?
shortid
已被弃用,以支持更小更快的nanoid:
- 小。108个字节(缩小并压缩)。没有依赖关系。大小限制控制大小。
- 快。它比UUID快40%。
- 安全。它使用具有加密功能的随机API。可以在集群中使用。
- 紧凑。它使用的字母比UUID(A-Za-z0-9_-)大。因此,ID大小从36个符号减少到21个。
- 随身携带。Nano ID已移植到14种编程语言。
import { nanoid } from 'nanoid'
// 21 characters (default)
// ~149 billion years needed, in order to have a 1% probability of at least one collision.
console.log(nanoid()) //=> "V1StGXR8_Z5jdHi6B-myT"
// 11 characters
// ~139 years needed, in order to have a 1% probability of at least one collision.
console.log(nanoid(11)) //=> "bdkjNOkq9PO"
更多信息在这里:https : //zelark.github.io/nano-id-cc/
还有一个很棒的npm软件包:shortid
简短的非顺序url友好型唯一ID生成器。
ShortId创建惊人的短的非顺序url友好的唯一ID。非常适合网址缩短器,MongoDB和Redis ID,以及其他用户可能会看到的ID。
- 预设为7-14个网址友好字元:AZ,az,0-9,_-
- 非顺序的,因此它们是不可预测的。
- 支持群集(自动),自定义种子,自定义字母。
- 可以生成任意数量的ID(无重复),甚至每天数百万。
- 非常适合游戏,尤其是如果您担心作弊,因此您不希望有容易猜到的ID。
- 应用程序可以重新启动任何次数,而无需重复ID。
- Mongo ID / Mongoose ID的流行替代品。
- 可在Node,io.js和Web浏览器中使用。
- 包括摩卡咖啡测试。
var shortid = require('shortid');
console.log(shortid.generate()); //PPBqWA9
replace(/[-]/g, '')
,这下到的32的长度
如果区分大小写并且所有位置均允许数字,则以下代码将生成3个字符的62 ^ 3(238,328)个唯一值。如果不要求区分大小写,请从字符字符串中删除大写或小写字符,它将生成35 ^ 3(42,875)个唯一值。
可以很容易地进行修改,以便第一个字符始终是一个字母或所有字母。
不容置疑,但可以对其进行优化,并且在达到限制时也可以拒绝返回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;
}
}());
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;
}
with(Math)
邪恶再给一个:)
with
在非性能代码中可能会毫无问题地使用它,并且“ with
is EVIL”很容易被极端化。=)性能既不是因素(如果只是不使用它),也不是创建或破坏变量的问题(不进行赋值),也不是与全局变量混淆的问题。我宁愿对性能造成小的影响,也不必在全局范围内重新定义整个Math模块。
with (Math)
人定义一个变量,var max = ...
那么它将覆盖Math.max
.........好了,不再使用with
了
floor
并random
实际引用的事实
这将生成一系列唯一值。当所有值都用尽时,它可以通过增加字符串长度来改善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());
}
该要点包含上述实现和递归版本。
您可以将GUID缩短为20个可打印ASCII字符,而不会丢失信息或GUID的唯一性。
杰夫·阿特伍德(Jeff Atwood)在那年前写了博客:
装备我们的ASCII装甲
只是随机生成一些字符串:
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 = {};
您可以使用md5算法生成随机字符串。md5是节点包
var randomChars = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 2);
var shortUrl = md5(originalUrl + randomChars + new Date()).substring(0, 5).toString();
console.log(shortUrl);
每次都会生成唯一的字符串。