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 ;
Если вы следуете приведенному выше объяснению, вы сможете создать этот альфа-цифровой фрагмент :
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/