javascript - число - генерация случайной строки java




Генерировать случайные строки/символы в JavaScript (20)

Случайный строковый генератор (Alpha-Numeric | Alpha | Numeric)

/**
 * RANDOM STRING GENERATOR
 *
 * Info:      http://stackoverflow.com/a/27872144/383904
 * Use:       randomString(length [,"A"] [,"N"] );
 * Default:   return a random alpha-numeric string
 * Arguments: If you use the optional "A", "N" flags:
 *            "A" (Alpha flag)   return random a-Z string
 *            "N" (Numeric flag) return random 0-9 string
 */
function randomString(len, an){
    an = an&&an.toLowerCase();
    var str="", i=0, min=an=="a"?10:0, max=an=="n"?10:62;
    for(;i++<len;){
      var r = Math.random()*(max-min)+min <<0;
      str += String.fromCharCode(r+=r>9?r<36?55:61:48);
    }
    return str;
}
randomString(10);        // "4Z8iNQag9v"
randomString(10, "A");   // "aUkZuHNcWw"
randomString(10, "N");   // "9055739230"

Повеселись. jsBin demo

В то время как вышеперечисленное использует дополнительные проверки для желаемого (A / N, A, N) вывода, давайте разложим его на основные (только Alpha-Numeric) для лучшего понимания:

  • Создайте функцию, которая принимает аргумент (желаемая длина случайного результата String)
  • Создайте пустую строку, такую ​​как var str = ""; объединить случайные символы
  • Внутри цикла создайте индекс rand от 0 до 61 (0..9 + A..Z + a..z = 62)
  • Создайте условную логику для настройки / исправления rand (так как она равна 0..61), увеличивая ее на некоторое число (см. Примеры ниже), чтобы вернуть правильный номер CharCode и соответствующий символ.
  • Внутри цикла конкатенация str на String.fromCharCode( incremented rand )

Давайте посмотрим таблицу символов и их диапазоны :

_____0....9______A..........Z______a..........z___________  Character
     | 10 |      |    26    |      |    26    |             Tot = 62 characters
    48....57    65..........90    97..........122           CharCode ranges

Math.floor( Math.random * 62 ) дает диапазон от 0..61 (что нам нужно). Как исправить ( увеличить ) случайное, чтобы получить правильные диапазоны charCode ?

      |   rand   | charCode |  (0..61)rand += fix            = charCode ranges |
------+----------+----------+--------------------------------+-----------------+
0..9  |   0..9   |  48..57  |  rand += 48                    =     48..57      |
A..Z  |  10..35  |  65..90  |  rand += 55 /*  90-35 = 55 */  =     65..90      |
a..z  |  36..61  |  97..122 |  rand += 61 /* 122-61 = 61 */  =     97..122     |

Логика условной операции из приведенной выше таблицы:

   rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand +=  true  ? (  true   ? 55 else 61 ) else 48 ;

Если вы следуете приведенному выше объяснению, вы сможете создать этот альфа-цифровой фрагмент :

jsBin demo

function randomString( len ) {
  var str = "";                                         // String result
  for(var i=0; i<len; i++){                             // Loop `len` times
    var rand = Math.floor( Math.random() * 62 );        // random: 0..61
    var charCode = rand+= rand>9? (rand<36?55:61) : 48; // Get correct charCode
    str += String.fromCharCode( charCode );             // add Character to str
  }
  return str;       // After all loops are done, return the concatenated string
}

console.log( randomString(10) ); // "7GL9F0ne6t"

Или, если вы:

function randomString( n ) {
  var r="";
  while(n--)r+=String.fromCharCode((r=Math.random()*62|0,r+=r>9?(r<36?55:61):48));
  return r;
}

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

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


Короткие, легкие и надежные

Возвращает ровно 5 случайных символов, в отличие от некоторых из лучших ответов, найденных здесь.

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

Быстрый и улучшенный алгоритм. Не гарантирует единообразность (см. Комментарии).

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}

В случае, если кто-то интересуется однострочным (хотя и не отформатированным как таковое для вашего удобства), который выделяет память сразу (но обратите внимание, что для небольших строк это действительно не имеет значения) вот как это сделать:

Array.apply(0, Array(5)).map(function() {
    return (function(charset){
        return charset.charAt(Math.floor(Math.random() * charset.length))
    }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
}).join('')

Вы можете заменить 5 на длину нужной строки. Благодаря @AriyaHidayat в этом сообщении для решения функции map не работающей с разреженным массивом, созданным Array(5) .


Вот несколько простых лайнеров. Измените new Array(5) чтобы задать длину.

В том числе 0-9a-z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})

В том числе 0-9a-zA-Z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});

Вот тестовый скрипт для ответа # 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');

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

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

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

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

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

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


Вы можете прокручивать массив элементов и рекурсивно добавлять их к строковой переменной, например, если вы хотите случайную последовательность ДНК:

function randomDNA(len) {
  len = len || 100
  var nuc = new Array("A", "T", "C", "G")
  var i = 0
  var n = 0
  s = ''
  while (i <= len - 1) {
    n = Math.floor(Math.random() * 4)
    s += nuc[n]
    i++
  }
  return s
}

console.log(randomDNA(5));


Если вы используете Lodash или Underscore , то это так просто:

var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');

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


Предполагая, что вы используете Underscore , можно элегантно генерировать случайную строку только в двух строках:

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var random = _.sample(possible, 5).join('');

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

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

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

И EntropyString может помочь библиотека, подобная 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"

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


Самый простой способ:

(new Date%9e6).toString(36)

Это генерирует случайные строки из 5 символов в зависимости от текущего времени. Пример вывода: 4mtxj или 4mv90 или 4mwp1

Проблема в том, что если вы вызовете это два раза за ту же секунду, он будет генерировать ту же строку.

Более безопасный способ:

(0|Math.random()*9e6).toString(36)

Это создаст случайную строку из 4 или 5 символов, всегда отличающуюся. Пример вывода аналогичен 30jzm или 1r591 или 4su1a

В обоих случаях первая часть генерирует случайное число. Часть .toString(36) присваивает номер базовому (буквенно-цифровому) представлению.


Сгенерируйте строку длиной 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;
}

Это верно

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

Я думаю, это сработает для вас:

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

console.log(makeid());


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

Поддержка только нижнего регистра:

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) чтобы отрегулировать нужную длину.


Math.random плохо для такого рода вещей

Опция 1

Если вы можете сделать это на стороне сервера , просто используйте криптовый модуль

var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

// "bb5dc8842ca31d4603d6aa11448d1654"

Полученная строка будет в два раза длиннее создаваемых вами случайных байтов; каждый байт, закодированный в шестнадцатеричный, равен 2 символам. 20 байтов будут содержать 40 символов в шестнадцатеричном формате.

Вариант 2

Если вам нужно сделать это на стороне клиента , возможно, попробуйте модуль uuid

var uuid = require("uuid");
var id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

Вариант 3

Если вам нужно сделать это на стороне клиента, и вам не нужно поддерживать старые браузеры, вы можете сделать это без зависимостей

// dec2hex :: Integer -> String
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2)
}

// generateId :: Integer -> String
function generateId (len) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"

console.log(generateId(20))
// "c1a050a4cd1556948d41"


let r = Math.random().toString(36).substring(7);
console.log("random", r);


Расширяясь на элегантном примере Doubletap, отвечая на вопросы, поднятые Гертасом и Драконом. Просто добавьте цикл while для проверки тех редких нулевых обстоятельств и ограничьте символы до пяти.

function rndStr() {
    x=Math.random().toString(36).substring(7).substr(0,5);
    while (x.length!=5){
        x=Math.random().toString(36).substring(7).substr(0,5);
    }
    return x;
}

Вот jsfiddle, предупреждающий вас с результатом: http://jsfiddle.net/pLJJ7/





random