JavaScript에서 임의의 문자열 / 문자 생성


1780

세트에서 무작위로 선택한 문자로 구성된 5 개의 문자열을 원합니다 [a-zA-Z0-9].

JavaScript로 이것을 수행하는 가장 좋은 방법은 무엇입니까?


48
경고 : true-random결과가 없습니다! 그들은 단지 pseudo-random있습니다. 보호 또는 보안을 위해 임의의 문자열을 사용할 때는 그중 아무 것도 사용하지 마십시오 !!! 이러한 API의 한 시도 random.org
Heijden 데르 론 반

48
Math.random (). toString (36) .replace (/ [^ az] + / g, '')
Muaz Khan

13
용액을 용액에 넣으십시오.
chryss

216
Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
Friedrich

12
참고 HTML5 webcrypto randomity API 는 실제 임의성을 제공합니다.
mikemaccana

답변:


2430

나는 이것이 당신에게 효과가 있다고 생각합니다.

function makeid(length) {
   var result           = '';
   var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
   var charactersLength = characters.length;
   for ( var i = 0; i < length; i++ ) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
   }
   return result;
}

console.log(makeid(5));


117
짧은 문자열에는 문제가 없지만 +=이와 같은 문자열을 사용 하면 O (n ^ 2) 동작이 발생합니다. 더 긴 문자열을 만들려면 개별 문자 배열을 만들고 끝에 결합해야합니다.
dan_waterworth

97
@dan_waterworth 거의 모든 경우에 중요하지 않습니다 : codinghorror.com/blog/2009/01/…
Alex Reece

7
@dan_waterworth, 사실, +=- 자주 빨리 심지어 루프 내부에 사용되는 몇 가지 이유입니다 jsperf.com/join-vs-concatenation
콘라드 보로프스키

18
@JonathanPaulson 숫자를 보여줘 . jsperf 링크 또는 jsperf.com/sad-tragedy-of-microoptimization 또는 sitepen.com/blog/2008/05/09/string-performance-an-analysis 등으로 이전 주석을 참조하십시오 . 또한이 질문에는 5 개의 연결 만 포함됩니다. .
Alex Reece

11
@codenamejames 암호 솔트에는 이것을 사용 하지 마십시오 . 안전하지 않은 의사 랜덤입니다. 노드를 사용한다고 가정하면 (클라이언트 측에서 소금을 칠 경우 어디서부터 시작 해야할지 모르겠습니다) crypto대신 사용하십시오.
수열

2330

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

참고 : 위 알고리즘에는 다음과 같은 약점이 있습니다.

  • 부동 소수점을 스트링화할 때 후행 0이 제거되므로 0에서 6 문자 사이에서 생성됩니다.
  • 부동 소수점 숫자를 문자열 화하는 데 사용되는 알고리즘에 크게 의존합니다. ( "부동 소수점 숫자를 정확하게 인쇄하는 방법" 종이 참조 )
  • Math.random()구현에 따라 예측 가능한 ( "임의의 외형"이지만 실제로는 무작위가 아닌) 출력을 생성 할 수 있습니다. 결과 문자열은 고유성 또는 예측 불가능 성을 보장해야 할 때 적합하지 않습니다.
  • 6 개의 균일하고 무작위로 예측할 수없는 문자를 생성하더라도 생일 역설 로 인해 약 50,000 개의 문자열 만 생성 한 후에 복제본을 볼 수 있습니다 . (sqrt (36 ^ 6) = 46656)

276
Math.random().toString(36).substr(2, 5)이므로 .substring(7)5자를 초과 하기 때문 입니다. 여전히 포인트!

81
@Scoop toString자바 스크립트에서 숫자 유형 의 메소드는 숫자를 주어진 밑으로 변환하기 위해 선택적 매개 변수를 사용합니다. 예를 들어 두 개를 전달하면 숫자가 이진수로 표시됩니다. 16 진수 (16 진수)와 유사하게, 밑줄 36은 문자를 사용하여 9 이상의 자릿수를 나타냅니다. 난수를 밑줄 36으로 변환하면 겉으로 보이는 임의의 문자와 숫자가 나타납니다.
Chris Baker

76
아름답게 보이지만 경우에 따라 빈 문자열이 생성됩니다! random이 0, 0.5, 0.25, 0.125 ...를 반환하면 빈 문자열이나 짧은 문자열이됩니다.
gertas

67
@gertas 이것은 피할 수 있습니다(Math.random() + 1).toString(36).substring(7);
George Reith

84
가이, 이것은 사실상 쓸모가 없습니다. 1000000 번만 실행하면 일반적으로 약 110000 회 반복 발생합니다. var values ​​= {}, i = 0, duplicateCount = 0, val; while (i <1000000) {val = Math.random (). toString (36) .substring (7); if (values ​​[val]) {duplicateCount ++; } 값 [val] = 1; i ++; } console.log ( "TOTAL DUPLICATES", duplicateCount);
hacklikecrack

463

Math.random 은 이런 종류의 일에 좋지 않습니다.

옵션 1

서버 쪽 을 수행 할 수 있다면 암호화 모듈을 사용하십시오.

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

// "bb5dc8842ca31d4603d6aa11448d1654"

결과 문자열은 생성하는 임의 바이트의 두 배입니다. 16 진으로 인코딩 된 각 바이트는 2 자입니다. 20 바이트는 16 진수 40 자입니다.


옵션 2

클라이언트 측 을 수행 해야하는 경우 uuid 모듈을 사용해보십시오-

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

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

옵션 3

클라이언트 측을 수행해야하고 이전 브라우저를 지원할 필요가없는 경우 종속성없이 수행 할 수 있습니다.

// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
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"


자세한 내용은 crypto.getRandomValues-

crypto.getRandomValues()방법을 사용하면 암호화 적으로 강력한 임의 값을 얻을 수 있습니다. 매개 변수로 제공된 배열은 난수 (암호화 의미에서 임의)로 채워집니다.

다음은 약간의 콘솔 예입니다.

> var arr = new Uint8Array(4) # make array of 4 bytes (values 0-255)
> arr
Uint8Array(4) [ 0, 0, 0, 0 ]

> window.crypto
Crypto { subtle: SubtleCrypto }

> window.crypto.getRandomValues()
TypeError: Crypto.getRandomValues requires at least 1 argument, but only 0 were passed

> window.crypto.getRandomValues(arr)
Uint8Array(4) [ 235, 229, 94, 228 ]

IE11 지원을 위해 다음을 사용할 수 있습니다.

(window.crypto || window.msCrypto).getRandomValues(arr)

브라우저 적용 범위는 https://caniuse.com/#feat=getrandomvalues를 참조 하십시오.


4
바로 그거죠. UUID가 사물에 ID를 할당하는 데는 좋지만, 임의의 문자열로 ID를 사용하는 것은이 (그리고 아마도 다른) 이유로 좋은 생각이 아닙니다.
wmassingham

2
.map()옵션 3에서는 필요가 없습니다 . Array.from(arr, dec2hex).join('')=== Array.from(arr).map(dec2hex).join(''). :-) 이러한 기능에 나를 소개 주셔서 감사합니다
프레드 Gandt

6
대답 2에서 옵션 2도 작동하려면 node.js가 필요하다는 것을 언급해야합니다. 순수한 자바 스크립트는 아닙니다.
Esko

5
더 암호 적으로 안전하지만 0-9, az, AZ가 아닌 0-9 및 af (16 진수) 만 출력하기 때문에 실제로 질문의 요구 사항을 충족시키지 못합니다.
qJake

1
하지 않 require모듈이 사용되는 서버 쪽이 될 만 할 수?
aJetHorn

173

짧고 쉽고 안정적 ​​임

여기에있는 최고 등급의 답변과 달리 정확히 5 개의 임의의 문자를 반환합니다.

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

9
Math.random().toString(36)5 자 미만의 숫자를 반환하면 어떻게 됩니까?
Michael Litvin

3
글쎄, 그것은 @ Aperçu의 흥미로운 기소입니다. 나는 솔루션을 발명했다고 말하는 것이 아니라 몇 년 동안 내 프로젝트에서 사용해 왔습니다. 그리고 그것은 당신이 언급 한 의견과 관련이 없습니다. 그리고 SO에서 중요한 것은 올바른 장소에서 가장 유용한 정보이며 다른 곳에서도 이미 존재한다고해도 확실합니다. 운 좋게도 최소한 51 명이이 답변이 유용하다고 생각합니다. 천만에요!
Silver Ringvee

3
Math.random ()이 0을 반환하는 경우 빈 문자열이 표시되는 것을 피하기 위해 다음을 사용할 수 있습니다.function getRandomString() { var result = ''; while (!result) result = Math.random().toString(36).substring(2); return result; };
mikep

5
@rinogo Math.random ()은 0을 반환하지만 1 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…를
mikep

6
나는이 코드를 1,000,000,000 번 실행했지만 여전히 빈 문자열을 얻지 못했습니다 : jsfiddle.net/mtp5730r 빈 문자열을 얻는 것이 안전하다고 말할 것입니다.
MacroMan

157

다음은 doubletap의 우수 답변 개선 사항입니다 . 원본에는 다음과 같은 두 가지 단점이 있습니다.

첫째, 다른 사람들이 언급했듯이 짧은 문자열이나 빈 문자열 (임의의 숫자가 0 인 경우)을 생성 할 가능성이 적으므로 응용 프로그램이 중단 될 수 있습니다. 해결책은 다음과 같습니다.

(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

둘째, 위의 원본과 솔루션은 문자열 크기 N을 16 자로 제한합니다. 다음은 N에 대해 크기가 N 인 문자열을 반환합니다 (그러나 N> 16을 사용하더라도 임의성이 증가하거나 충돌 가능성이 감소하지는 않습니다).

Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

설명:

  1. [0,1) 범위에서 0 (포함)과 1 (제외) 사이의 난수를 선택하십시오.
  2. 숫자를 밑이 36 인 문자열로 변환하십시오 (예 : 문자 0-9 및 az 사용).
  3. 0으로 채워진 패드 (첫 번째 문제 해결).
  4. 선행 '0'을 잘라냅니다. 접두사 및 추가 패딩 0.
  5. 빈 문자열을 구분 기호로 사용되는 임의의 짧은 임의 문자열로 결합하여 N 자 이상이되도록 문자열을 충분히 반복하십시오.
  6. 문자열에서 정확히 N자를 자릅니다.

추가 생각 :

  • 이 솔루션은 대문자를 사용하지 않지만, 거의 모든 경우 (말장난 의도가 없음)는 중요하지 않습니다.
  • 원래 답변에서 N = 16의 최대 문자열 길이는 Chrome에서 측정됩니다. Firefox의 경우 N = 11입니다. 그러나 설명 된 것처럼 두 번째 솔루션은 임의성을 추가하는 것이 아니라 요청 된 문자열 길이를 지원하는 것이므로 큰 차이가 없습니다.
  • 반환 된 모든 문자열은 적어도 Math.random ()에 의해 반환 된 결과가 균등하게 분배되는 한 반환 확률이 동일합니다 (어쨌든 암호 강도 난수가 아님).
  • 크기가 N 인 모든 가능한 문자열이 리턴되는 것은 아닙니다. 두 번째 솔루션에서는 이것이 분명합니다 (작은 문자열이 단순히 복제되기 때문에). 그러나 원래의 대답에서는 base-36으로 변환 할 때 마지막 몇 비트가 원래 임의 비트의 일부가 아닐 수 있기 때문에 이것은 사실입니다. 특히 Math.random (). toString (36)의 결과를 보면 마지막 문자가 고르게 분포되지 않은 것을 알 수 있습니다. 다시 말하지만, 거의 모든 경우에 중요하지 않지만 무작위 문자열의 끝이 아니라 처음부터 마지막 ​​문자열을 슬라이스하여 짧은 문자열 (예 : N = 1)이 영향을받지 않도록합니다.

최신 정보:

여기에 내가 생각해 낸 몇 가지 다른 기능 스타일 원 라이너가 있습니다. 그것들은 위의 해결책과 다릅니다.

  • 그들은 명백한 임의의 알파벳을 사용합니다 (보다 일반적이며 대문자와 소문자 모두를 요구 한 원래 질문에 적합 함).
  • 길이가 N 인 모든 문자열은 리턴 될 확률이 같습니다 (즉, 문자열에 반복이 포함되지 않음).
  • toString (36) 트릭이 아닌 맵 함수를 기반으로하므로보다 간단하고 이해하기 쉽습니다.

그래서, 당신이 선택한 알파벳이

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

그런 다음이 두 가지는 서로 동일하므로 더 직관적 인 것을 선택할 수 있습니다.

Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

편집하다:

내가 좋아하는 것 같다 qubyte마티 드 Milliano은 어떻게 든 놓친 후자의 유사 (명성!) 솔루션을 함께했다. 그들은 한 눈에 짧게 보이지 않기 때문에 누군가가 실제로 하나의 라이너를 원할 경우를 대비하여 여기에 남겨 두겠습니다. :-)

또한 모든 솔루션에서 'new Array'를 'Array'로 바꾸어 몇 바이트를 더 줄였습니다.


왜 1을 추가하지 않습니까? (Math.random()+1).toString(36).substring(7);
emix

1을 추가해도 여기서 논의 된 두 가지 문제 중 하나가 해결되지 않기 때문입니다. 예를 들어 (1) .toString (36) .substring (7)은 빈 문자열을 생성합니다.
amichair

를 사용 Math.random().toString(36).substring(2,7)하면 다음과 같은 예상 결과를 얻을 수 있습니다..substring(2, n+2)
Joseph Rex

Array.apply(null, {length: 5}).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('')
Muhammad Umer

이것은 훌륭하지만 N = 16 인 Firefox에서 실행될 때 마지막 ~ 6 자리 숫자는 0이됩니다 ... (하지만 5 개의 임의의 문자에 대한 OP의 요구를 충족시킵니다.)
Edward Newell

127

보다 컴팩트 한 솔루션 slice은보다 짧습니다 substring. 문자열의 끝에서 빼면 random함수에 의해 생성 된 부동 소수점 기호를 피할 수 있습니다.

Math.random().toString(36).slice(-5);

또는

(+new Date).toString(36).slice(-5);

업데이트 : 방법을 사용 btoa하는 또 다른 접근법이 추가되었습니다 .

btoa(Math.random()).slice(0, 5);
btoa(+new Date).slice(-7, -2);
btoa(+new Date).substr(-7, 5);

// Using Math.random and Base 36:
console.log(Math.random().toString(36).slice(-5));

// Using new Date and Base 36:
console.log((+new Date).toString(36).slice(-5));

// Using Math.random and Base 64 (btoa):
console.log(btoa(Math.random()).slice(0, 5));

// Using new Date and Base 64 (btoa):
console.log(btoa(+new Date).slice(-7, -2));
console.log(btoa(+new Date).substr(-7, 5));


Math.random().toString(36).slice(-5);- 만약에 Math.random()반환 0.0?
엑스레이

@ x 선, 당신은 얻을 것이다 "0";)
Valentin Podkamennyi

2
바로 그거죠. ;) 그리고 Math.random()반환 0.5하면 결과는 "0.i"입니다. 다른 경우가 있는지 확실하지 않습니다. 이 질문에 대한 정답이 아니라는 점을 지적하고 싶었습니다 ([a-zA-Z0-9]의 5 자).
x-ray

2
@ x-ray, 나는 이것이 정답이라고 말하지 않을 것이며, 이것은 위의 @doubletap 답의 컴팩트 버전이라고 말하고 있습니다. 개인적 (+new Date + Math.random())으로이 경우를 방지하기 위해 사용 합니다. 어쨌든, 메모 주셔서 감사합니다.
Valentin Podkamennyi

1
이. 다른 답변에 많은 코드가 필요한 이유를 모르겠습니다.
john ktejik

100

이런 식으로 작동해야합니다

function randomString(len, charSet) {
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var randomString = '';
    for (var i = 0; i < len; i++) {
        var randomPoz = Math.floor(Math.random() * charSet.length);
        randomString += charSet.substring(randomPoz,randomPoz+1);
    }
    return randomString;
}

기본 문자셋 [a-zA-Z0-9]로 전화하거나 직접 보내십시오.

var randomValue = randomString(5);

var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');


1
루프 len에서 직접 감소 할 수도 있습니다while
drzaus

덕분에, 난 그냥이 예제의 커피 스크립트 변화 아래에 게시 : stackoverflow.com/a/26682781/262379를
디 니스 크루즈를

이것들이 공개적으로 사용된다면, 모음을 제거해야 할 것입니다. 엔트로피는 적지 만 사람들을 화나게 할 수있는 단어를 생성 할 수 없으므로 훨씬 안전합니다. 내 문자열을 보낼 수 있기 때문에 내가 이것을 좋아하는 이유입니다. 잘 했어.
네이트 버니

예쁜 하드 코어, 나를 위해 일했다, 고마워!
Zaki Mohammed

73

es6 스프레드 연산자가 있는 최신 버전 :

[...Array(30)].map(() => Math.random().toString(36)[2]).join('')

  • 30임의의 수, 당신은 당신이 원하는 어떤 토큰 길이를 선택할 수있다
  • 36당신이 통과 할 수있는 최대 기수 번호 numeric.toString () 의미, 모든 숫자와 알파벳 순으로 소문자 문자
  • 2다음과 같습니다 임의의 문자열에서 제 3 회 인덱스를 선택하는 데 사용됩니다 "0.mfbiohx64i", 우리는 이후에 어떤 인덱스를 취할 수0.

설명해 주시겠습니까? 특히 36을 toString ()에 전달하고 왜 세 번째 요소를 선택합니까?
vuza

5
이것이 가장 좋은 해결책입니다
극복 자

훌륭하지만이 솔루션에는 요청한대로 [AZ] 문자가 포함되어 있지 않으며 [a-z0-9]
Nahuel Greco

71

function randomstring(L) {
  var s = '';
  var randomchar = function() {
    var n = Math.floor(Math.random() * 62);
    if (n < 10) return n; //1-10
    if (n < 36) return String.fromCharCode(n + 55); //A-Z
    return String.fromCharCode(n + 61); //a-z
  }
  while (s.length < L) s += randomchar();
  return s;
}
console.log(randomstring(5));


나는 이것을 가장 좋아한다. 추가 매개 변수를 승인하고 숫자, 하한값 또는 상한값 만 리턴하도록 쉽게 수정할 수 있습니다. 나는 매우 압축 된 스타일이 필요하다고 생각하지 않습니다while(s.length< L) s+= randomchar();
mastaBlasta

3
또한 while(L--)그것을 할 것입니다
vsync

1
'A'.charCodeAt(0)매직 넘버보다 더 강력한 것을 사용하는 것이 좋습니다 55(그리고 마찬가지로 61). 특히, 내 플랫폼에서 어쨌든 반환되는 매직 넘버는입니다 65. 이 코드는 자체 문서화가 더 좋습니다.
Grumdrig

구현의 축소 최적화 (46 바이트 작음) 변형을 여기
만들었

@Waruyama를 디버깅하는 행운을 빕니다. 그게 웹팩입니다!
Dylan Watson

61

랜덤 문자열 생성기 (알파 숫자-알파 | 숫자)

/**
 * Pseudo-random string generator
 * http://stackoverflow.com/a/27872144/383904
 * Default: return a random alpha-numeric string
 * 
 * @param {Integer} len Desired length
 * @param {String} an Optional (alphanumeric), "a" (alpha), "n" (numeric)
 * @return {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;
}

console.log(randomString(10));      // i.e: "4Z8iNQag9v"
console.log(randomString(10, "a")); // i.e: "aUkZuHNcWw"
console.log(randomString(10, "n")); // i.e: "9055739230"


위의 내용은 원하는 A / N, A, N 출력에 대한 추가 검사를 사용하지만 더 나은 이해를 위해 필수 (알파 숫자)로 나누겠습니다.

  • 인수 (임의의 String 결과의 원하는 길이)를 허용하는 함수를 작성하십시오.
  • var str = "";임의의 문자를 연결하는 것처럼 빈 문자열을 만듭니다.
  • 루프 안에서 0에서 61 까지 인덱스 번호만듭니다rand (0..9 + A..Z + a..z = 62)
  • 올바른 숫자와 관련 문자를 다시 얻기 위해 일부 숫자 (아래 예 참조) 씩 증가 / 조정 (0..61이므로) 하기 위한 조건부 논리 를 만듭니다 .randCharCode
  • 에 루프 CONCATENATE 내부strString.fromCharCode( incremented rand )

ASCII 문자 테이블 범위를 그려 봅시다 .

_____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)); // i.e: "7GL9F0ne6t"

또는 당신이 원한다면 :

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

console.log(randomString(10))


33

가장 간단한 방법은 다음과 같습니다.

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

현재 시간을 기준으로 5 자의 임의 문자열을 생성합니다. 출력 예이다 4mtxj하거나 4mv90또는4mwp1

이것의 문제점은 같은 초에 두 번 호출하면 동일한 문자열을 생성한다는 것입니다.

더 안전한 방법은 다음과 같습니다.

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

이것은 항상 다른 4 또는 5 문자의 임의의 문자열을 생성합니다. 예제 출력은 추천 30jzm하거나 1r591또는4su1a

두 가지 방법으로 첫 번째 부분은 난수를 생성합니다. .toString(36)부분은 그것의 base36 (alphadecimal) 표현으로 숫자를 캐스팅.


이것이 어떻게 질문에 대답하는지 잘 모르겠습니다. 이것은 이미 많은 유효한 답변을 가진 7 살짜리 질문입니다. 새로운 답변을 제공하기로 선택한 경우, 귀하의 답변이 잘 설명되고 문서화되도록 각별히주의해야합니다.
Claies

1
Date를 사용하는 경우 다음과 같이 사용하십시오.(+new Date).toString(36)
seniorpreacher

나는 임의의 숫자 솔루션을 좋아하지만 9e6은 5 자리 (36 ^ 5)의 60.4 백만보다 9 백만 개의 가능성을 제공하므로 그것을 대체하기 위해 그것을 대체 할 수 (0|Math.random()*6.04e7).toString(36)있습니다.
르 드로이드

1
암호로 놀랄 필요가없는 가능한 짧은 루틴 (코드 데모의 경우)이있는 길고 임의의 문자열을 원했습니다. 나는이 답변이 가장 좋습니다 (두 번째 답변), 감사합니다. 내 두 센트 : 한 번의 키 입력으로 짧게하기 위해 이길 수 있으며 일반적으로 마침표없이 13 개의 임의의 문자를 생성 (Math.random()*1e20).toString(36)합니다.
Andrew Willems

이 답변에 대한 한 가지 질문은 원래 질문에있는 [AZ]를 사용하지 않는다는 것입니다.
user.friendly

22

다음은 쉬운 라이너 하나입니다. 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"]();});

20

나는 모든 사람들이 이미 올바르게 알고 있다는 것을 알고 있지만 가능한 가장 가벼운 방법 (CPU가 아닌 코드에 빛) 으로이 것을 좋아한다고 느꼈습니다.

function rand(length, current) {
  current = current ? current : '';
  return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current;
}

console.log(rand(5));

머리를 감싸는 데 약간의 시간이 걸리지 만 실제로는 자바 스크립트의 구문이 얼마나 멋진지를 보여줍니다.


20
코드를 짧게 유지하려는 경우 왜 쓸 수 current = current ? current : '';있을 때 쓰십시오 current = current || ''.
CaffGeek

9
우리가 여기서 마이크로 최적화를 이야기하고 있기 때문에 실제로 필요하지 않은 경우 변수 할당을 완전히 건너 뛸 것을 제안합니다.current || (current = '');
Thomas Heymann

"좋은"리소스를 사용하는 동안 미세 최적화를 시도하지만 재귀 알고리즘을 낭비하는 것은 의미가 없습니다. :-) for 루프는 여전히 자바 스크립트에서 최고이며 재귀 시간을 능가합니다.
Mörre

17

당신이 사용하는 경우 Lodash 또는 밑줄을 , 그것은 너무 간단 :

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

6
Lodash 사용_.sampleSize('asdfgh',5).join('')
marlo

2
문서 마다 각 문자가 고유 색인에서 왔기 때문에 이것은 실제로 좋은 해결책이 아닙니다 . 그것은 어떤 문자도 반복 할 수 없기 때문에 실제로 무작위가 아님을 의미합니다.
random_user_name 21시 44 분

16

요구 사항 [a-zA-Z0-9] 및 길이 = 5를 충족하려면

btoa(Math.random()).substr(5, 5);

소문자, 대문자 및 숫자가 발생합니다.


1
Math.random ()은 너무 적은 문자로 base64 문자열로 이어질 수 있습니다.
Leif

14

누구나 한 번에 메모리를 할당하는 단일 라이너 (편의를 위해 형식화되지는 않았지만)에 관심이있는 경우 (작은 문자열의 경우 실제로 중요하지 않음) 여기에 수행 방법이 있습니다.

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


13
모든 자바 스크립트 프로그램은 같은 포맷 경우 '한 줄'입니다
hacklikecrack

13

내가 만든 방법은 다음과 같습니다.
대문자와 소문자를 모두 포함하는 문자열을 만듭니다.
또한 영숫자 문자열을 만드는 함수도 포함 시켰습니다.

실례 :
http://jsfiddle.net/greatbigmassive/vhsxs/ (알파 만)
http://jsfiddle.net/greatbigmassive/PJwg8/ (알파벳)

function randString(x){
    var s = "";
    while(s.length<x&&x>0){
        var r = Math.random();
        s+= String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65));
    }
    return s;
}

2015 년 7 월 업그레이드
동일한 기능을 수행하지만 더 이해하기 쉽고 모든 문자를 포함합니다.

var s = "";
while(s.length<x&&x>0){
    v = Math.random()<0.5?32:0;
    s += String.fromCharCode(Math.round(Math.random()*((122-v)-(97-v))+(97-v)));
}

이 기능을 사용하면 'M'보다 큰 대문자 나 'n'보다 작은 소문자를 얻을 수 없습니다.
erkanyildiz

정말? 아! 아마 더 많이 테스트 할 것입니다. 흠, 그러나 그것은 임의의 문자열이기 때문에 우리는 문자가 어떤 문자인지 (무작위 인 한) 상관하지 않지만 여전히 우리가 원하는 것을 수행합니다. 업그레이드 감사합니다.
Adam

12

밑줄 을 사용한다고 가정하면 단 두 줄로 무작위 문자열을 우아하게 생성 할 수 있습니다.

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

6
이렇게하면 반환 값에 모든 고유 문자가 있습니다. 또한 문자열의 길이는 가능한 var의 길이로 제한됩니다.
Yefu


10

빠르고 개선 된 알고리즘. 균일 성을 보장하지는 않습니다 (주석 참조).

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

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    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);
        }
    }

    let result = '';

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

    return result;
}

2
큰 대답이지만 확률은 일정하지 않습니다. 62 개의 가능한 문자가 있으며 crypto.getRandomValues256 개의 고유 한 값 중 하나를 반환합니다. 256은 62로 나뉘 지 않기 때문에 문자 AH를 얻을 확률이 약간 높습니다. 가장 좋은 해결책은 YouTube가 한 일 을하고 문자 세트 에 2 개의 문자 ( -및 가능 _)를 추가하는 것입니다. 어쨌든, 위대한 작품-이 답변은 훨씬 더 많은 사랑이 필요합니다 :)
TeWu

추가 - 그리고 _ 것은 당신에게 전체 URL 보안 base64 세트를 얻을 것이기 때문에 좋은 생각입니다
cowbert

8

"임의의 문자열이 필요합니다" 질문에 대한 응답의 문제 (언어가 무엇이든)는 실제로 모든 솔루션에 결함이있는 기본 길이 인 기본 문자열을 사용한다는 것 입니다. 임의의 문자열이 필요한 이유를 질문 자체가 거의 공개하지 않습니다,하지만 난 당신이 변함없이 필요가 몇 개의 무엇 8. 말, 당신은 거의 길이의 임의의 문자열을 필요로하지 도전 할 고유의 문자열이 어떤 목적을위한 식별자로 사용, 예를 들어,.

엄격하게 고유 한 문자열 을 얻는 두 가지 주요 방법이 있습니다 : 결정적 (임의가 아님)과 저장 / 비교 (거대한). 우리는 무엇을해야합니까? 우리는 유령을 포기합니다. 우리는 함께 갈 확률 고유성 대신. 즉, 우리는 우리의 끈이 독특하지 않을 위험이 있음을 인정합니다. 충돌 확률엔트로피를 이해하는 것이 도움이됩니다.

따라서 반복의 위험이 적은 몇 개의 문자열이 필요하다고 변하지 않는 필요성을 다시 말하겠습니다. 구체적인 예로, 5 백만 개의 잠재적 인 ID를 생성하려고한다고 가정하겠습니다. 각각의 새 문자열을 저장하고 비교하고 싶지 않으며 임의의 문자열을 원하므로 반복 위험이 있습니다. 예를 들어, 1 조 회 반복 가능성이 1 미만인 위험을 가정 해 봅시다. 그래서 어떤 길이의 문자열이 필요합니까? 글쎄, 그 질문은 사용 된 문자에 따라 다르므로 지정되지 않았습니다. 그러나 더 중요한 것은 잘못 인도 된 것입니다. 필요한 것은 길이가 아닌 문자열의 엔트로피 사양입니다. 엔트로피는 몇 개의 문자열에서 반복 확률과 직접 관련 될 수 있습니다. 문자열 길이는 할 수 없습니다.

EntropyString 과 같은 라이브러리 가 도움이 될 수 있습니다. 다음을 사용하여 5 백만 개의 문자열에서 1 조 건의 반복 확률로 1 미만의 임의 ID를 생성하려면 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 자 문자 세트를 사용합니다. 사전 정의 된 다른 문자 세트가 있으며 고유 한 문자도 지정할 수 있습니다. 예를 들어, 위와 동일하지만 16 진 문자를 사용하여 ID를 생성합니다.

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

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

const string = random.string(bits)

"27b33372ade513715481f"

사용 된 문자 세트의 총 문자 수 차이로 인해 문자열 길이의 차이에 유의하십시오. 지정된 수의 잠재적 인 문자열에서 반복 위험은 동일합니다. 문자열 길이는 다릅니다. 그리고 무엇보다도 반복의 위험과 잠재적 인 문자열 수는 명백합니다. 더 이상 문자열 길이를 추측하지 않아도됩니다.


7
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 도 빠릅니다 .


나를 위해이 항상 함께 임의의 문자열을 생성 strLength - 1/ - :
xanderiel

3
에서 전환하여 나를 --strLength위해 strLength--수정했습니다.
xanderiel

7

예를 들어 임의의 DNA 서열을 원할 경우 항목 배열을 반복하여 문자열 변수에 반복적으로 추가 할 수 있습니다.

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


6

소문자와 대문자를 모두 지원하는 깨끗한 솔루션을 찾지 못했습니다.

소문자 만 지원 :

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)필요한 길이로 조정합니다.


6

짧막 한 농담:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil

더 짧은 Array(15)값으로 만들려면 인수를 더 작은 값으로 변경하십시오. 예 : Array(4).
앤드류

나는이 솔루션을 간단하고 명확하게 좋아합니다. 0에서 1 사이의 15 개의 난수를 생성하고 16 진수를 생성 한 다음 처음 두 문자를 제거합니다. 마지막으로 모두 함께 병합합니다.
시시 아

5

이것은 확실히 작동합니다

<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

다음과 같은 방법은 어떻습니까? Date.now().toString(36) 매우 무작위는 아니지만 호출 할 때마다 짧고 독특합니다.


1
불행히도 이것은 Date.now()밀리 초 해상도 만 가지므로 독특하지 않습니다 . 예를 들어 간단한 루프에서 실행하면 많은 중복이 발생합니다. for (let i = 0; i < 10; ++i) { console.log(Date.now().toString(36)); }.
Nate

5

대소 문자를 구분하지 않는 영숫자 문자 :

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


이 답변은 내 유스 케이스에 더 적합합니다. var possible수락 된 답변에 좋아요를 추가 할 수 있으면 멋지 므로 함수의 결과를보다 구성 할 수 있습니다.
Denis. Sabolotni

4

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

coderain 을 사용할 수 있습니다 . 주어진 패턴에 따라 임의의 코드를 생성하는 라이브러리입니다. #숫자와 대문자 및 소문자의 자리 표시 자로 사용하십시오 .

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

A대문자 나 9숫자 와 같은 다른 자리 표시자가 있습니다 .

유용한 것은 호출 .next()은 항상 고유 한 결과를 제공하므로 중복에 대해 걱정할 필요가 없다는 것입니다.

다음은 고유 한 임의 코드 목록생성 하는 데모 애플리케이션입니다 .

전체 공개 : 저는 coderain의 저자입니다.


아니오 아니오 아니오-고유 메소드를 사용하십시오.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.