Как генерировать короткий uid как "aX4j9Z" (в JS)
Для моего веб-приложения (в JavaScript) я хочу генерировать короткие лиги (для разных объектов - на самом деле разные типы - строки и массивы строк)
Я хочу что-то вроде "aX4j9Z" для моих uids (guids).
Таким образом, эти uids должны быть достаточно легкими для веб-трансфайлов и обработки строк js и совершенно уникальны для не огромной структуры (не более, чем 10k элементов). Говоря "совершенно уникальный", я имею в виду, что после генерации uid я мог проверить, существует ли этот uid в структуре и регенерировать его, если он это делает.
Я бы посоветовал любые советы.
Ответы
Ответ 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 = {};