javascript-如何生成像“ aX4j9Z”这样的简短uid(在JS中)

对于我的Web应用程序(使用JavaScript),我想生成简短的指导(针对不同的对象-实际上是不同的类型-字符串和字符串数组)

我的uid(向导)需要类似“ aX4j9Z”的名称。

因此,这些uid应该足够轻巧,可以进行Web传输和js字符串处理,并且对于不大的结构(不超过10k个元素)来说应该是非常独特的。 说“非常独特”是指在生成uid之后,我可以检查该uid是否已经存在于结构中,如果存在则重新生成。

WHITECOLOR asked 2019-11-16T00:47:59Z
7个解决方案
105 votes

有关预打包的解决方案(Math.random软件包),请参见@Mohamed的答案。 如果您没有特殊要求,则最好不要使用此页面上的任何其他解决方案。


一个6个字符的字母数字序列足以随机索引10k集合(366 = 22亿,363 = 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;
        }
    }
}

如果您需要唯一性而不是不可预测性,请考虑使用顺序生成器(例如Math.randomuser134_item2等)。 您可以“哈希”顺序生成的字符串以恢复不可预测性。

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

kennytm answered 2019-11-16T00:48:51Z
14 votes

还有一个可怕的npm软件包:shortid

简短的非顺序url友好型唯一ID生成器。

ShortId创建令人惊讶的短非连续url友好的唯一ID。 非常适合网址缩短器,MongoDB和Redis ID,以及其他用户可能会看到的ID。

  • 默认情况下,包含7-14个网址友好字符:A-Z,a-z,0-9,_-
  • 非顺序的,因此它们是不可预测的。
  • 支持群集(自动),自定义种子,自定义字母。
  • 可以生成任意数量的ID(无重复),甚至每天数百万。
  • 非常适合游戏,特别是如果您担心作弊,因此您不希望有容易猜到的ID。
  • 应用程序可以重新启动任何次数,而无需重复ID。
  • Mongo ID / Mongoose ID的流行替代品。
  • 可在Node,io.js和Web浏览器中使用。
  • 包括摩卡咖啡测试。

用法

var shortid = require('shortid');
console.log(shortid.generate()); //PPBqWA9
Mohamed Ramrami answered 2019-11-16T00:50:28Z
5 votes

如果区分大小写并且所有位置均允许数字,则以下代码将生成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;
  }
}());
RobG answered 2019-11-16T00:51:05Z
2 votes

这将生成一系列唯一值。 当所有值都用尽时,它可以通过增加字符串长度来改善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());
}

要点包含上述实现和递归版本。

Ilia Choly answered 2019-11-16T00:51:38Z
1 votes
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;
}
ninjagecko answered 2019-11-16T00:51:55Z
1 votes

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

Jeff Atwood在几年前写了博客:
装备我们的ASCII装甲

Christian Specht answered 2019-11-16T00:52:32Z
0 votes

只是随机生成一些字符串:

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 = {};
Mark Kahn answered 2019-11-16T00:52:56Z
translate from https://stackoverflow.com:/questions/6248666/how-to-generate-short-uid-like-ax4j9z-in-js