Подтвердить что ты не робот

Как генерировать короткий uid как "aX4j9Z" (в JS)

Для моего веб-приложения (в JavaScript) я хочу генерировать короткие лиги (для разных объектов - на самом деле разные типы - строки и массивы строк)

Я хочу что-то вроде "aX4j9Z" для моих uids (guids).

Таким образом, эти uids должны быть достаточно легкими для веб-трансфайлов и обработки строк js и совершенно уникальны для не огромной структуры (не более, чем 10k элементов). Говоря "совершенно уникальный", я имею в виду, что после генерации uid я мог проверить, существует ли этот uid в структуре и регенерировать его, если он это делает.

Я бы посоветовал любые советы.

4b9b3361

Ответ 1

См. @Mohamed answer для предварительно упакованного решения (shortid package). Предположите, что вместо любых других решений на этой странице, если у вас нет особых требований.


6-значная буквенно-цифровая последовательность достаточно проста, чтобы случайным образом индексировать коллекцию 10k (36 6= 2,2 миллиарда и 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, сгенерированные случайным образом, будут иметь столкновение после генерации чисел ~ & radic; N (парадокс дня рождения), поэтому 6 цифр необходимы для безопасного создания без проверки (старая версия генерирует только 4 цифры, которые будут иметь столкновение после 1300 идентификаторов, если вы проверьте).

Если вы выполняете проверку на столкновение, количество цифр может быть уменьшено на 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,...), если вам нужна уникальность, а не непредсказуемость. Вы можете "Хешировать" последовательно генерируемую строку для восстановления непредсказуемости.

UID, сгенерированные с помощью Math.random, не являются безопасными (и вы не должны доверять клиенту в любом случае). Не полагайтесь на свою уникальность или непредсказуемость в критически важных задачах.

Ответ 2

Для этого также существует awsome пакет npm: shortid

Удивительно короткий несегментный уникальный уникальный генератор id.

ShortId создает удивительно короткие несегментные уникальные идентификаторы URL. Идеально подходит для сокращений url, идентификаторов MongoDB и Redis и любых других пользователей, которые могут видеть.

  • По умолчанию 7-14 URL-символов: A-Z, a-z, 0-9, _-
  • Непоследовательно, поэтому они не предсказуемы.
  • Поддерживает кластер (автоматически), пользовательские семплы, пользовательский алфавит.
  • Может генерировать любое количество идентификаторов без дубликатов, даже миллионов в день.
  • Идеально подходит для игр, особенно если вас беспокоит обман, поэтому вы не хотите легко угадать id.
  • Приложения могут быть перезапущены любое количество раз без повторения идентификатора.
  • Популярная замена для идентификатора Mongo ID/Mongoose.
  • Работает в Node, io.js и веб-браузерах.
  • Включает тесты Mocha.

Использование

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

Ответ 3

Ниже генерируется 62 ^ 3 (238,328) уникальных значений из 3 символов, если чувствительность к регистру уникальна, а цифры разрешены во всех положениях. Если требуется нечувствительность к регистру, удалите символы верхнего или нижнего регистра из строки символов и создайте уникальные значения 35 ^ 3 (42 875).

Может быть легко адаптирована так, чтобы первый char всегда был буквой или всеми буквами.

Нет, но он может быть оптимизирован и также может отказаться возвращать идентификатор, когда предел достигнут.

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;
  }
}());

Ответ 4

Это создаст последовательность уникальных значений. Он улучшает ответ RobG, увеличивая длину строки, когда все значения были исключены.

var IdGenerator = (function () {

    var defaultCharset = "[email protected]#$%^&*()_-+=[]{};:?/.>,<|".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());
}

Этот метод содержит приведенную выше реализацию и рекурсивную версию.

Ответ 5

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;
}

Ответ 6

Вы можете сократить GUID до 20 печатных символов ASCII без потери информации или уникальности GUID.

Джефф Этвуд писал об этом много лет назад:
Оснащение нашей брони ASCII

Ответ 7

просто произвольно генерирует несколько строк:

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 = {};