Генерация случайной строки / символов в JavaScript - PullRequest
1470 голосов
/ 29 августа 2009

Мне нужна строка из 5 символов, состоящая из символов, выбранных случайным образом из набора [a-zA-Z0-9].

Какой лучший способ сделать это с помощью JavaScript?

Ответы [ 65 ]

6 голосов
/ 10 января 2013
function randomString (strLength, charSet) {
    var result = [];

    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    while (--strLength) {
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }

    return result.join('');
}

Это так чисто, как только можно. Это тоже быстро, http://jsperf.com/ay-random-string.

6 голосов
/ 06 февраля 2018

Я не нашел чистого решения для поддержки как строчных, так и прописных букв.

Поддержка только строчных букв:

Math.random().toString(36).substr(2, 5)

Опираясь на это решение для поддержки строчных и прописных букв:

Math.random().toString(36).substr(2, 5).split('').map(c => Math.random() < 0.5 ? c.toUpperCase() : c).join('');

Измените 5 в substr(2, 5), чтобы настроить нужную длину.

5 голосов
/ 03 декабря 2009

Это точно работает

<script language="javascript" type="text/javascript">
function randomString() {
 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var string_length = 8;
 var randomstring = '';
 for (var i=0; i<string_length; i++) {
  var rnum = Math.floor(Math.random() * chars.length);
  randomstring += chars.substring(rnum,rnum+1);
 }
 document.randform.randomfield.value = randomstring;
}
</script>
5 голосов
/ 03 сентября 2017

Проблема с ответами на «Мне нужны случайные строки» вопросов (на любом языке) - практически каждое решение использует некорректную первичную спецификацию длина строки . Сами вопросы редко показывают, зачем нужны случайные строки, но я бы сказал, что вам редко нужны случайные строки длиной, скажем, 8. Что вам обязательно нужно, так это, например, некоторое количество уникальных строк , чтобы использовать их как идентификаторы для некоторых целей.

Существует два основных способа получения строго уникальных строк: детерминистически (что не случайно) и сохранение / сравнение (что обременительно). Что мы делаем? Мы отдаем призрак. Вместо этого мы используем вероятностную уникальность . То есть мы признаем, что существует некоторый (хотя и небольшой) риск того, что наши строки не будут уникальными. Здесь полезно знать вероятность столкновения и энтропия .

Так что я перефразирую неизменную потребность как нужное количество строк с небольшим риском повторения. В качестве конкретного примера предположим, что вы хотите создать 5 миллионов идентификаторов. Вы не хотите хранить и сравнивать каждую новую строку, и вы хотите, чтобы они были случайными, поэтому вы принимаете некоторый риск повторения. Например, допустим, что риск повторения меньше 1 в триллионе. Так какая длина строки вам нужна? Ну, этот вопрос недостаточно конкретизирован, поскольку зависит от используемых символов. Но что более важно, это ошибочно. Вам нужно указать энтропию строк, а не их длину. Энтропия может быть напрямую связана с вероятностью повторения в некотором количестве строк. Длина строки не может.

И здесь может помочь библиотека типа EntropyString . Чтобы сгенерировать случайные идентификаторы с шансом повторения менее 1 на триллион в 5 миллионах строк, используйте entropy-string:

import {Random, Entropy} from 'entropy-string'

const random = new Random()
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"44hTNghjNHGGRHqH9"

entropy-string использует набор символов из 32 символов по умолчанию. Существуют и другие предопределенные наборы символов, и вы также можете указать свои собственные символы. Например, генерация идентификаторов с той же энтропией, что и выше, но с использованием шестнадцатеричных символов:

import {Random, Entropy, charSet16} from './entropy-string'

const random = new Random(charSet16)
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"27b33372ade513715481f"

Обратите внимание на разницу в длине строки из-за разницы в общем количестве символов в используемом наборе символов. Риск повторения в указанном количестве потенциальных строк одинаков. Длина строки не. И, что лучше всего, риск повторения и потенциальное количество строк явно. Больше не нужно гадать с длиной строки.

4 голосов
/ 11 января 2013

Создать строку длиной 10 символов. Длина задается параметром (по умолчанию 10).

function random_string_generator(len) {
var len = len || 10;
var str = '';
var i = 0;

for(i=0; i<len; i++) {
    switch(Math.floor(Math.random()*3+1)) {
        case 1: // digit
            str += (Math.floor(Math.random()*9)).toString();
        break;

        case 2: // small letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 97); //'a'.charCodeAt(0));
        break;

        case 3: // big letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 65); //'A'.charCodeAt(0));
        break;

        default:
        break;
    }
}
return str;
}
4 голосов
/ 08 августа 2013

Как насчет этого компактного трюка?

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var stringLength = 5;

function pickRandom() {
    return possible[Math.floor(Math.random() * possible.length)];
}

var randomString = Array.apply(null, Array(stringLength)).map(pickRandom).join('');

Вам нужно Array.apply, чтобы обманным путем заставить пустой массив стать неопределенным.

Если вы пишете код для ES2015, то создание массива немного проще:

var randomString = Array.from({ length: stringLength }, pickRandom).join('');
4 голосов
/ 16 ноября 2017

Как насчет этого: Date.now().toString(36) Не очень случайный, но короткий и совершенно уникальный каждый раз, когда вы его называете.

4 голосов
/ 09 января 2017

Вы можете использовать coderain . Это библиотека для генерации случайных кодов по заданному шаблону. Используйте # в качестве заполнителя для прописных и строчных букв, а также цифр:

var cr = new CodeRain("#####");
console.log(cr.next());

Существуют и другие заполнители, такие как A для заглавных букв или 9 для цифр.

Что может быть полезно, так это то, что вызов .next() всегда даст вам уникальный результат, поэтому вам не придется беспокоиться о дубликатах.

Вот демонстрационное приложение, которое генерирует список уникальных случайных кодов .

Полное раскрытие: я автор Coderain.

3 голосов
/ 23 сентября 2018

Буквенно-цифровые символы без учета регистра:

function randStr(len) {
  let s = '';
  while (s.length < len) s += Math.random().toString(36).substr(2, len - s.length);
  return s;
}

// usage
console.log(randStr(50));

Преимущество этой функции заключается в том, что вы можете получить произвольную строку различной длины, и она обеспечивает длину строки.

Чувствительный к регистру все символы:

function randStr(len) {
  let s = '';
  while (len--) s += String.fromCodePoint(Math.floor(Math.random() * (126 - 33) + 33));
  return s;
}

// usage
console.log(randStr(50));

Пользовательские символы

function randStr(len, chars='abc123') {
  let s = '';
  while (len--) s += chars[Math.floor(Math.random() * chars.length)];
  return s;
}

// usage
console.log(randStr(50));
console.log(randStr(50, 'abc'));
console.log(randStr(50, 'aab')); // more a than b
3 голосов
/ 07 августа 2014

Вот тестовый скрипт для ответа № 1 (спасибо @ csharptest.net)

скрипт выполняется makeid() 1 million раз, и, как вы можете видеть, 5 не является уникальным. запускать его с длиной символа 10 довольно надежно. Я запускал его около 50 раз и еще не видел дубликатов :-)

примечание: ограничение размера стека узла превышает около 4 миллионов, поэтому вы не можете выполнить эти 5 миллионов раз, когда оно не закончится.

function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

ids ={}
count = 0
for (var i = 0; i < 1000000; i++) {
    tempId = makeid();
    if (typeof ids[tempId] !== 'undefined') {
        ids[tempId]++;
        if (ids[tempId] === 2) {
            count ++;
        }
        count++;
    }else{
        ids[tempId] = 1;
    }
}
console.log("there are "+count+ ' duplicate ids');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...