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.