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

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

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

Ответы [ 65 ]

1 голос
/ 31 мая 2019
const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = Array.from({length:5}, _ => c[Math.floor(Math.random()*c.length)]).join('')
1 голос
/ 28 июля 2017

Случайное числовое значение (до 16 цифр)

/**
 * Random numeric value (up to 16 digits)
 * @returns {String}
 */
function randomUid () {
  return String(Math.floor(Math.random() * 9e15))
}

// randomUid() -> "3676724552601324"
1 голос
/ 20 ноября 2018

Это слегка улучшенная версия doubletap 's answer . Он учитывает комментарий gertas о случае, когда Math.random() возвращает 0, 0,5, 0,25, 0,125 и т. Д.

((Math.random()+3*Number.MIN_VALUE)/Math.PI).toString(36).slice(-5)
  1. Это предотвращает передачу нуля в toString мое добавление наименьшего числа с плавающей точкой к Math.random().
  2. Он гарантирует, что число, переданное в toString, будет иметь достаточно цифр путем деления на почти иррациональное число.
1 голос
/ 01 июня 2018

Случайная строка в Юникоде

Этот метод возвращает случайную строку с любым из поддерживаемых символов Юникода, что не на 100% соответствует тому, что запрашивает OP, а то, что я искал:

function randomUnicodeString(length){
    return Array.from({length: length}, ()=>{
        return String.fromCharCode(Math.floor(Math.random() * (65536)))
    }).join('')
}

Обоснование

Это лучший результат Google при поиске «случайного строкового JavaScript», но OP запрашивает только a-zA-Z0-9.

1 голос
/ 03 октября 2017

Научите человека ловить рыбу:

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

То, что вы хотите, это строка символов, и символы представлены байтами. И мы можем представить байт в JavaScript, используя число. Итак, мы должны сгенерировать список этих чисел и привести их в виде строк. Вам не нужны дата или base64; Math.random () получит вам число, а String.fromCharCode () превратит его в строку. Легко.

Но какое число соответствует какому символу? UTF-8 - это основной стандарт, используемый в Интернете для интерпретации байтов как символов (хотя JavaScript использует UTF-16 внутри, они перекрываются). Способ решения этой проблемы для программиста - изучить документацию.

UTF-8 перечисляет все клавиши на клавиатуре в цифрах от 0 до 128. Некоторые из них не для печати. Просто выберите нужные символы в ваших случайных строках и найдите их, используя случайно сгенерированные числа.

Сильфон - это функция, которая принимает практически бесконечную длину, генерирует случайное число в цикле и ищет все печатные символы в младших 128 кодах UTF-8. Энтропия присуща, поскольку не все случайные числа будут попадаться каждый раз (непечатные символы, пробелы и т. Д.). Он также будет работать быстрее, если вы добавите больше символов.

Я включил большинство оптимизаций, обсуждаемых в теме:

  • Двойная тильда быстрее, чем Math.floor
  • операторы if быстрее, чем регулярные выражения
  • отправка в массив быстрее, чем конкатенация строк

function randomID(len) {
  var char;
  var arr = [];
  var len = len || 5;

  do {
    char = ~~(Math.random() * 128);

    if ((
        (char > 47 && char < 58) || // 0-9
        (char > 64 && char < 91) || // A-Z
        (char > 96 && char < 123) // a-z

        // || (char > 32 && char < 48) // !"#$%&,()*+'-./
        // || (char > 59 && char < 65) // <=>?@
        // || (char > 90 && char < 97) // [\]^_`
        // || (char > 123 && char < 127) // {|}~
      )
      //security conscious removals: " ' \ ` 
      //&& (char != 34 && char != 39 && char != 92 && char != 96) 

    ) { arr.push(String.fromCharCode(char)) }

  } while (arr.length < len);

  return arr.join('')
}

var input = document.getElementById('length');

input.onfocus = function() { input.value = ''; }

document.getElementById('button').onclick = function() {
  var view = document.getElementById('string');
  var is_number = str => ! Number.isNaN( parseInt(str));
    
  if ( is_number(input.value))
    view.innerText = randomID(input.value);
  else
    view.innerText = 'Enter a number';
}
#length {
  width: 3em;
  color: #484848;
}

#string {
  color: #E83838;
  font-family: 'sans-serif';
  word-wrap: break-word;
}
<input id="length" type="text" value='#'/>
<input id="button" type="button" value="Generate" />
<p id="string"></p>

Почему это так утомительно? Потому что ты можешь. Вы программист. Вы можете заставить компьютер делать что угодно! Кроме того, что, если вам нужна строка символов иврита? Это не трудно. Найдите эти символы в стандарте UTF-8 и найдите их. Освободите себя от таких методов Макдональда, как toString (36).

Иногда опускание до более низкого уровня абстракции - это то, что необходимо для создания реального решения. Понимание основных принципов под рукой может позволить вам настроить свой код так, как вам хочется. Может быть, вы хотите, чтобы бесконечно сгенерированная строка заполняла круговой буфер? Может быть, вы хотите, чтобы все ваши сгенерированные строки были палиндромами? Зачем сдерживаться?

1 голос
/ 19 сентября 2018

Для строки с прописными и строчными буквами и цифрами (0-9a-zA-Z), это может быть версия, которая минимизирует лучше всего:

function makeId(length) {
  var id = '';
  var rdm62;
  while (length--) {
   // Generate random integer between 0 and 61, 0|x works for Math.floor(x) in this case 
   rdm62 = 0 | Math.random() * 62; 
   // Map to ascii codes: 0-9 to 48-57 (0-9), 10-35 to 65-90 (A-Z), 36-61 to 97-122 (a-z)
   id += String.fromCharCode(rdm62 + (rdm62 < 10 ? 48 : rdm62 < 36 ? 55 : 61)) 
  }
  return id;
}

Содержимое этой функции уменьшается до 97 байт, тогда как для верхнего ответа требуется 149 байт (из-за списка символов).

1 голос
/ 13 сентября 2017

Вот другой подход с фиксированной длиной по базе, без замены замены RegExp (на основе ответа @ bendytree);

function rand(base) {
    // default base 10
    base = (base >= 2 && base <= 36) ? base : 10;
    for (var i = 0, ret = []; i < base; i++) {
        ret[i] = ((Math.random() * base) | 0).toString(base)
            // include 0-9a-zA-Z?
            // [Math.random() < .5 ? 'toString' : 'toUpperCase']();
    }
    return ret.join('');
}
0 голосов
/ 01 июля 2016

Вот версия Coffeescript, одна строка кода

genRandomString = (length,set) -> [0...length].map( -> set.charAt Math.floor(Math.random() * set.length)).join('')

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

genRandomString 5, 'ABCDEFTGHIJKLMNOPQRSTUVWXYZ'

Выход:

'FHOOV' # random string of length 5 in possible set A~Z
0 голосов
/ 31 октября 2014

Вот пример в CoffeeScript:

String::add_Random_Letters   = (size )->
                                         charSet = 'abcdefghijklmnopqrstuvwxyz'
                                         @ + (charSet[Math.floor(Math.random() * charSet.length)]  for i in [1..size]).join('')

который можно использовать

value = "abc_"
value_with_exta_5_random_letters = value.add_Random_Letters(5)
0 голосов
/ 17 августа 2018

рекурсивное решение:

function generateRamdomId (seedStr) {
const len = seedStr.length
console.log('possibleStr', seedStr , ' len ', len)
if(len <= 1){
    return seedStr
}
const randomValidIndex  = Math.floor(Math.random() * len)
const randomChar = seedStr[randomValidIndex]
const chunk1 = seedStr.slice(0, randomValidIndex)
const chunk2 = seedStr.slice(randomValidIndex +1)
const possibleStrWithoutRandomChar = chunk1.concat(chunk2)

return randomChar + generateRamdomId(possibleStrWithoutRandomChar)

}

вы можете использовать с нужным вам семенем, не повторяйте символы, если вы не читаете. Пример

generateRandomId("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...