랜덤 비밀번호 생성기


40

도메인 서버에는 모든 직원이 다음 규칙을 준수하는 강력하고 임의의 암호가 있어야합니다.

  • 정확히 15 자 길이입니다.
  • 키보드 유형 문자 만 (아래 코드 유형으로 표시) ALT + NUMPAD 코드를 사용하도록 판매를 가르치는 것은 허용되지 않습니다.
  • 소문자 1 자 이상 : abcdefghijklmnopqrstuvwxyz
  • 대문자 1 자 이상 : ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • 1 자리 이상의 숫자 : 0123456789
  • 1 개 이상의 기호 : `~!@#$%^&*()_+-={}|[]\:";'<>?,./

이를 위해 IT는 모든 직원에게 랜덤 비밀번호 생성기를 시운전하고 배포 할 것입니다. 모든 직원은 Random Password Generator를 사용해야합니다. 임의 비밀번호 생성기의 요구 사항은 위의 비밀번호 제한 외에도 다음과 같습니다.

  • 허용되는 모든 문자의 모든 순열을 생성 할 수 있어야합니다.
  • 화면에 생성 된 비밀번호를 표시해야합니다.
  • 코드는 가능한 한 작아야합니다 (바이트).

다음 주 내에 제안 된 솔루션을 제출하십시오.


10
또한 허용 된 모든 암호가 동일한 확률로 표시되도록 요구해야합니다 (그렇지 않으면 허용되는 문자로 30 자 길이의 목록을 작성하고
— 섞어서

@ 무스, 동의했다. 새로운 규칙을 추가했습니다.
— Hand-E-Food

22
IT 직원은 해고 당하거나 교육을 잘 받아야합니다. 암호를 무작위로 생성하는 경우 허용되는 암호 세트를 각 범주의 문자를 하나 이상 포함하는 암호로 제한하면 암호가 약해 집니다. 허용되는 세트 확인하지 않아도되면 프로그램이 훨씬 쉬워 질 것입니다 ... 많은 제출물이 도착한 후 컨테스트를 수정하지 마십시오. 도전으로 괜찮습니다.
— MvG


1
모든 비밀번호를 생성 할 수 있어야하므로 @moose에 대한 답변이 없습니다. 그들은 같은 확률로 나타나야합니다.
— Ethan Bolker

답변:


29

매스 매 티카 (18)

조금만 속이자

= 15char ASCII pwd
&(^F7yP8k:*1P<t

PS 안전하지 않음 :)


6
코드는 어디에 있습니까?
— DavidC

11
각 문자 클래스 요구 사항 중 하나 이상 을 충족하도록 보장 됩니까?
— Hand-E-Food

3
@ Hand-E-Food 예, 그렇습니다! 해석을 보면 암호 길이 15, 소문자 필요, 대문자 필요, 숫자 필요, 특수 문자 필요합니다.
— ybeltukov

6
+1 영리하지만 교활합니다.
— DavidC

10
나는 티카 모든 것을하는 기능을 가지고 있음을 알았지 만, 이 ?
— Konrad Borowski

13

루비, 74 69 바이트

모든 문자 클래스가 나타날 때까지 33-126의 ASCII 범위에서 무작위로 샘플링하십시오.

$_=[*?!..?~].sample(15)*''until~/\d/&&~/[a-z]/&&~/[A-Z]/&&~/\W|_/
p$_

루비, 39 바이트

무스의 영리한 발견 사용 :

p"0123abcdABCD-+/<".chars.sample(15)*''

군중을 만족 시키도록 편집하십시오.

처음 게시 한 후에 규칙이 변경되었습니다 . 당시 이전의 두 항목이 모두 규칙에 적용되었습니다. 또한 규칙이 여전히 잘 정의되어 있지 않다고 지적하고 싶습니다.

(..) 허용되는 모든 문자의 모든 순열

"순열". 허용 가능한 문자 세트의 순열은 허용 가능한 문자 세트의 길이만큼 길기 때문에 (암호 길이는 15 자 여야 함) 나머지 규칙을 따르는 허용 가능한 문자의 순열 은 없습니다 . 그리고 순열에는 반복이 없습니다. 그러나 내 첫 번째 항목은 여전히 ​​여기에 다른 많은 찬사를받은 답변보다 "무작위"입니다.

그럼에도 불구하고 여기 있습니다. 문자와 밑줄을 반복 할 수 있습니다.

루비, 77 바이트

$_=([*?!..?~]*15).sample(15)*''until~/\d/&&~/[a-z]/&&~/[A-Z]/&&~/\W|_/
puts$_

"따옴표"로 묶인 문자열을 인쇄하고 일부 문자는 백 슬래시로 이스케이프 처리 하기 때문에이 puts대신 대신 사용 했습니다 .pp

루비, 70 바이트

Ventero가 지적했듯이 정규 ~표현식 앞에서 건너 뛸 수 있으며 print바꿀 수 있습니다 puts$_. 그러나 추악한 출력으로 인해 거부 된 모든 암호를 인쇄하여 한 줄짜리로 압착 할 수 있습니다.

puts$_=([*?!..?~]*15).sample(15)*''until/\d/&&/[a-z]/&&/[A-Z]/&&/\W|_/

설명

요청대로. $_입력에서 읽은 마지막 줄을 포함하는 반 마법의 변수입니다 - 당신은 항상 같이 저장할 필요가 없습니다 이 . 그러나 여기서 우리는, 즉 것을 때문에 다른 재산을 사용 ~사업자, 그것은 직접 내가 처음으로 배운 트릭 정규식을 적용 역대을 . 의 사용법을 바꾸 all었지만 나머지를 얻는다면 이해하기가 쉬워야합니다 ( docs 참조 ).


2
코드를 조금 설명해 주시겠습니까? 무엇을 .all?{|r|~r}합니까? 무엇을 $_=합니까?
— Martin Thoma

3
샘플 행은 영리하고 모든 것이지만 "허용되는 모든 문자의 모든 순열을 생성 할 수 있어야합니다." 문자에 관한 한 비밀번호에만 광고가 포함될 수는 없습니다. z가 허용되는 문자이면 z가 암호에있는> 0 일 가능성이 있습니다.
— nitro2k01

1
합니까 \W루비는 밑줄을 포함 _? 대부분의 정규식 방언에서는 그렇지 않습니다. 단일 코드가 _영숫자가 아닌 유일한 기호 인 경우 암호를 생성 할 수없는 경우 하나의 요구 사항을 위반하게됩니다. 두 번째 접근 방식은 분명히 그 요구 사항을 위반하지만 그 당시에는 올바르게 표현되지 않았다고 생각합니다.
— MvG

1
@MvG : 맞습니다. \WPerl 호환 RegEx ( source ) 에는 밑줄이 없습니다 .
— Martin Thoma

1
또한 귀하의 솔루션은 @moose와 동일한 문제에 영향을 미치며 Python에서와 같은 문제가 있습니다. sample요소를 반복하지 않으므로 반복 요소가있는 암호를 코드로 생성 할 수 없습니다.이 두 가지 문제를 해결하여 질문에 대한 답변을 질문에 맞출 수 있습니까? Wolfram Alpha를 제외하고 자신의 솔루션이 어떻게 최고의 솔루션인지 살펴보면 리드를 준수하고 유지할 수 있는지 여부를 확인하는 것이 좋습니다. 너무 힘들어서는 안될 것 같아요.
— MvG

12

자바 (8) - (354) 329 319 275 267 자

Java 8과 함께 람다를 사용하면 재미를 얻을 수 있습니다. 가능한 모든 출력은 같은 확률로 찾을 수 있습니다.

허용되는 문자에는 33에서 126까지의 연속 ASCII 코드가 있다는 사실을 사용합니다.

class A {
    //flags for, respectively, small caps, large caps, digits, punctuation
    static int a, A, d, p;

    public static void main(String[] x) {
        String s;
        do {
            //Using special String constructor that takes an int[]
            s = new String(new java.util.Random().ints(15, 33, 127)
                                .toArray(),
                           0, 15);
            a = A = d = p = 0;
            s.chars()
                .map(c ->
                      c > 96 & c < 123 ? a = 1
                    : c > 64 & c < 90  ? A = 1
                    : c > 47 & c < 58  ? d = 1
                    : (p = 1))
                .min();
        } while (a + A + d + p < 4);
        System.out.println(s);
    }
}

샘플 출력 :

.*;Tm?svthiEK`3  
o.dzMgtW5|Q?ATo  
FUmVsu<4JF4eB]1

압축 프로그램 :

class A{static int a,A,d,p;public static void main(String[]x){String s;do{s=new String(new java.util.Random().ints(15,33,127).toArray(),0,15);a=A=d=p=0;s.chars().map(c->c>96&c<123?a=1:c>64&c<90?A=1:c>47&c<58?d=1:(p=1)).min();}while(a+A+d+p<4);System.out.println(s);}}


대신 에 while(a+A+d+p<4)함께 어떻습니까? 또는 루프 조건으로 비트 마스크 (예 : through 와 같은 것) 를 사용하십시오 . 올바르게 계산하면 13자를 절약 할 수 있습니다. a|=1a++a|=1a|=8a<15
— MvG

@ MvG 좋은 지적-비슷한 것을해서 몇 가지 추가 문자를 절약했습니다.
— assylias

@MvG 그리고를 사용 new String(int[],int,int)하면 또 다른 40 홀짜리 문자가 저장됩니다!
— assylias

8

Python 2.X + 3.X (229 자) : 생성 및 바꾸기

생각

  1. 먼저 15 개의 허용 된 기호로 목록을 만드십시오.
  2. r임의의 자리를 임의의 숫자로 교체
  3. 임의의 위치를 교체 s하여, s != r대문자 문자로,
  4. 소문자와 기호는 2와 3에서와 동일합니다.

암호

from random import randint as r, shuffle as s
a=list(range(15))
p=a[:]
for i in range(15):
    a[i]=chr(r(32,126))
s(p)
a[p.pop()]=chr(r(48,57))
a[p.pop()]=chr(r(65,90))
a[p.pop()]=chr(r(97,122))
a[p.pop()]=chr(r(33,47))
print(a)

Python 2.X + 3.X (194 자) : 생성 및 확인

import random
from re import search as s
p=''
while not all([s("\d",p),s("[a-z]",p),s("[A-Z]",p),s("[\W_]",p)]):
 p=str(map(chr,[random.choice(list(range(33,127))) for i in range(15)]))
print(p)
  • 덕분에 MVG는 누가 말해 줬어 \u및 \l파이썬 정규식에 존재하지 않습니다.
  • 교체가 필요 없다고 말한 grc 덕분에 random.sample교체 가능한 샘플링이 가능한 모든 가능한 암호를 얻으십시오.

문제 설명에 결함 사용

현재 문제 설명에서는 모든 기호 / 숫자가 동일한 확률로 표시되도록 요구하지 않습니다. 다음 솔루션을 사용하면 단일 기호 및 / 또는 위치에 대한 가정을 할 수 없습니다. 그러나 여러 가지로 할 수 있습니다.

Python 2.X + 3.X (62 자)

from random import sample
print(sample("0123abcdABCD-+/<",15))

샘플을 사용하는 아이디어에 대한 daniero에게 감사드립니다.


결함을 발견하는 매우 부드러운! 나는 그것을 연결했지만 그것을 식별하기위한 보너스 포인트. :-)
— Hand-E-Food

당신의 gen & check는 나의 접근법과 비슷합니다. 호기심에서 : \l파이썬 정규 표현식의 문서화는 어디에 있습니까? 에서 볼하지 마십시오 참조 . 내 파이썬 3.3.3도 받아들이지 않습니다 "\u". 은 str(…)3.3.3 또는 2.7.6 중 하나의 문자에 가입하지 않습니다. 최적화에 대한 한 가지 제안 : all(s("\\"+i,p)for i in "dluW").
— MvG

random.sample대체하지 않고 요소를 선택하므로 모든 암호가 가능한 것은 아닙니다.
— grc

@MvG : 감사합니다. 난 그냥 것을 본 적이 \u과 \l정력 전용입니다.
— Martin Thoma

7

배쉬 온 * 닉스 (109)

while ! grep -Pq [A-Z].*[a-z].*[0-9].*[\\W_]<<<$a$a$a$a
do a=`tr -dc !-~</dev/urandom|head -c15`
done
echo $a

올바르게 작동하려면 $a유효하지만 임의의 암호가 아닌 암호를 미리 설정해야합니다. 포함 a=하고 줄 바꿈을 시작하려면 세 문자가 더 있지만 반복해서 실행할 수 있습니다. 분명히 모든 줄 바꿈을 바꿀 수 ;있으므로 한 줄짜리 라이너를 사용하면 자주 쓸 수 있습니다.

또한에는 설정해야 LC_ALL=C로케일 특정 환경 변수를 설정 (또는하지 LANG와 LC_CTYPE문자 범위가 배열 순서는 아스키 순서 이상임에 의존하기 때문에, 특히).

/dev/urandom임의 바이트의 소스입니다. !-~질문에 지정된 모든 허용 가능한 문자의 범위입니다. 다음 인수에 나열 되지 않은tr -dc 모든 문자를 제거합니다 . 나머지 문자 15 개를 가져옵니다. 필요한 각 종류가 한 번 이상 발생하는지 확인합니다. 입력은 4 개의 후보 사본으로 구성되므로 기호 순서는 중요하지 않으므로 가능한 모든 암호를 선택할 수 있습니다. 는 억압 grep을 출력한다.headgrep-q

알 수없는 이유로 나이 /dev/random가 /dev/urandom걸립니다. 엔트로피가 꽤 빨리 소진 된 것 같습니다. 에 cd들어가면 /dev더 많은 바이트를 피할 수 있지만 바람을 피우는 것처럼 느껴집니다.

파이썬 2 (138)

import re,random
a=''
while not re.search('[A-Z].*[a-z].*[0-9].*[\W_]',a*4):
 a=''.join(random.sample(map(chr,range(33,127))*15,15))
print a

코드를 읽을 수 있도록 루프 뒤에 줄 바꿈과 들여 쓰기를 추가하여 필요하지 않고 계산하지 않았습니다.

이것은 기본적으로 bash 버전과 동일합니다. 여기서 임의의 소스는 random.sample입니다. 요소는 반복되지 않습니다. 이 사실을 방지하기 위해 허용되는 문자 목록 15 부를 사용합니다. 이렇게하면 반복되는 문자를 가진 문자가 덜 자주 발생하지만 모든 조합이 여전히 발생할 수 있습니다. 그러나 문제가 모든 순열에 대해 동일한 확률을 요구하지는 않았기 때문에 버그가 아닌이 기능을 버그로 간주하기로 결정했습니다.

파이썬 3 (145)

import re,random
a=''
while not re.search('[A-Z].*[a-z].*[0-9].*[\W_]',a*4):
 a=''.join(random.sample(list(map(chr,range(33,127)))*15,15))
print(a)

한 줄 바꿈과 들여 쓰기는 다시 계산되지 않습니다. 파이썬 3 고유의 구문 오버 헤드 외에도 Python 2와 동일한 솔루션입니다.

자바 스크립트 (161)

a=[];for(i=33;i<127;)a.push(s=String.fromCharCode(i++));
while(!/[A-Z].*[a-z].*[0-9].*[\W_]/.test(s+s+s+s))
for(i=0,s="";i<15;++i)s+=a[Math.random()*94|0];alert(s)

가독성을 위해 줄 바꿈을 추가했지만 계산하지는 않았습니다.

R (114)

s<-""
while(!grepl("[A-Z].*[a-z].*[0-9].*(\\W|_)",paste(rep(s,4),collapse="")))
 s<-intToUtf8(sample(33:126,15,T))
s

루프 내부의 줄 바꿈 및 들여 쓰기가 추가되었지만 계산되지 않았습니다. 기분이 ;좋으면 다시 한 줄로 분리 할 수 있습니다 .


하아! greplR 코드에서 사용할 수 있다고 지적했습니다 . 테스트 암호를 네 번 반복하여 모든 검사를 한 번에 수행 할 수 있다고 생각한 경우. 내가 생각했던 경우에만 그리고 당신은 알고 sample및 intToUtf8. 그러나 가능한 모든 암호를 얻으려면 샘플 메소드 replace=TRUE에을 추가해야합니다 (또는 더 간결하게 추가해야합니다 ,T) .
— AmeliaBR

@ AmeliaBR : 당신이 맞아, 그 replace=T실수를 고쳐 주셔서 감사합니다. intToUtf8탭 완성으로 이름을 추측하여 찾는 데 꽤 오랜 시간이 걸렸습니다. 나는 그러한 기능이 존재한다는 것을 알고 있었지만 더 일반적인 이름 chr등은 사용되지 않았습니다.
— MvG

@ MvG : 파이썬 코드가 왜 끝나는 지 이해가되지 않습니다. 왜 그런가요 *4? 정규 표현식이 모든 문자열, 첫 번째 대문자, 그다음에 하나의 소문자 등의 문자열과 일치한다고 생각했습니다 ... 무엇이 잘못 되었습니까?
— Martin Thoma

@ moose : 이미 알고 있듯이 내 정규 표현식은 특정 순서로 필요한 범주를 확인합니다. 그러나 현재 후보자의 사본 4 개를 연결하여 순서가 더 이상 중요하지 않게 할 수 있습니다. 비밀번호가 기호 다음에 숫자와 소문자, 대문자가 있어도 여전히 일치합니다. 검색이 실패 할 수있는 유일한 방법은 카테고리가 모두 누락 된 경우입니다. 또한 내가하지 re.search않으므로 re.match정규 표현식이 후보 비밀번호의 어느 곳에서나 일치 할 수 있습니다. 이것이 결국 종료되는 이유를 설명합니까?
— MvG

아, 나는 당신이 re.search대신 사용한다는 것을 알지 못했습니다 re.match. 그것은 그것을 설명합니다. 하지만 난 여전히 당신이 필요하지 않습니다 생각합니다 *4. 설명 주셔서 감사합니다 (+1)
— Martin Thoma

7

C 번호 ( 123-139 103-127 문자 압축) :

다음에서 완벽하게 적합한 프레임 워크 방법 사용 System.Web.dll:

class P
{
    static void Main()
    {
        Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15, 1));
    }
}

꽉 찬:

class P{static void Main()
{Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15,1));}}

예:

b+m2ae0K:{dz7:A

또는 int numberOfNonAlphanumericCharacters명령 행에서 두 번째 매개 변수 ( ) 의 값을 가져 오십시오.

class P
{
    static void Main(string[] a)
    {
        Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15, int.Parse(a[0])));
    }
}

3
GeneratePassword질문에 지정된 전체 기호 세트를 지원하지 않습니다. 각 문자 범주의 최소 발생 횟수에 대한 보증도 찾지 못했습니다.
— MvG

2
당신은 사용하여 더 압축 할 수 class P및 string[] a.
— d3dave

@ MvG, 흥미 롭습니다. 프랑스어와 같은 언어로 악센트 문자를 쓰는 데 일반적으로 사용되는 기호는 제외 된 것 같습니다. 아마 현명한 움직임. 키보드 언어를 변경하면 암호를 채울 수 있습니다.
— Hand-E-Food

5

R (301 322 자)

수정 은 숫자를 확인하는 것을 잊었습니다.

a='abcdefghijklmnopqrstuvwxyz';
f=as.factor(strsplit(paste(a,toupper(a),
    sep="0123456789`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./"),"")[[1]]);
g=gsub("(.):","\\1",levels(q:q:q:q:q:q:q:q:q:q:q:q:q:q:q));
repeat{p=g[runif(1)*length(g)]; 
    if(grepl("[A-Z]",p)&&grepl("[a-z]",p)&&grepl("[0-9]",p)&&grepl("[^A-Za-z0-9]",p))break;};
print(p);

명확성을 위해 공백이 추가되었습니다.

94 자의 가능한 15 자 순열을 모두 생성합니다. 그런 다음 기준과 일치 할 때까지 무작위로 하나를 선택합니다.

마술은 q:q작업 중이며, 첫 번째 q목록 의 모든 요인과 두 번째 목록 의 모든 요인 이 상호 작용 하는 새로운 요인 데이터 유형을 생성 하며이 두 목록의 가능한 모든 조합은 " 그 요인의 수준 ". 허용되는 문자 목록의 15 개 사본을 상호 작용하면 가능한 수준이 (94 ^ 15) 있습니다.

집에서 시도하지 마십시오. 코드는 세 글자 순열을 모두 알아내는 데 몇 초가 걸립니다. 컴퓨터의 메모리가 부족하지 않은 경우 15 자 순열을 모두 알아내는 데 시간이 얼마나 걸릴지 상상할 수 없습니다. 그 동안에. 완성 된 (3 문자 암호) 스크립트를 실행하여 확인했을 때 가장 먼저 뱉어 낸 암호는 "oO ="였습니다.이 코드에 대한 반응을 요약합니다.


@MvG는 훨씬 더 실용적이고 훨씬 짧은 R 스크립트를 가지고 있습니다 : codegolf.stackexchange.com/a/17700/12413
— AmeliaBR

그럼에도 불구하고 나는 당신의 아이디어를 좋아합니다. 내가 본 많은 코드 골프 스 니펫은 언어의 특정 기능이 열심히 일하도록했습니다. 그리고 당신의 코드는 분명히 R과 상호 작용을 통해 그렇게합니다.
— MvG

4

매스 매 티카 170

r=RandomSample;f[i_]:=(FromCharacterCode/@Range@@i);
{t,A,a,n}=f/@{{33,126},{65,90},{97,122},{48,57}};
s=Complement[t,A,a,n];
""<>r[Join[RandomChoice/@{A,a,n,s},r[t,11]],15]

예

"<]} Pg3 / e? 3 + Z ~ Oz"
"X / 8jWe @ f (_x5P : ="
"2wz2VQhtJC? * R7 ^"


4

파이썬 2.7 (182)

import random as r,string as s
z=r.sample
j=list(z(s.ascii_lowercase,12)+z(s.ascii_uppercase,1)+z(s.digits,1)+z('`~!@#$%^&*()_+-={}|[]\\:";\'<>?,./',1))
r.shuffle(j)
print ''.join(j)

문제점 설명에 필요하지 않은 결합을 제거하면 9 자리를 줄일 수 있습니다. 공백을 제거하여 다른 2 개를 줄입니다.
— Martin Thoma

@moose 나는 당신이 논평하기 직전에 공백을 가져 왔습니다 :-) 나는 join거기에 있어야한다고 생각합니다 : 사용자는 출력에서 ​​파이썬 목록 구문을 이해해야합니다 : ['q', 'u', ...]?
— Jonathon Reinhart

1
나는 인쇄를 전혀 제거하려고 생각했습니다. 바이트 단위의 크기가 중요한 경우 펀치 카드 시간에 살 수 있습니다. 그렇게하면 메모리를 보면 그냥 읽을 수있을 것입니다. 또는 "실제 프로그래머"입니다. xkcd.com/378
— Martin Thoma

1
코드를 올바르게 읽으면 모든 순열을 충족시키지 못합니다. 요구 사항을 항상 12 개의 소문자를 사용하므로 다른 그룹 중 하나 이상 (예 aA$bc1111111111:) 이있는 비밀번호는 불가능합니다.
— IQAndreas

1
Johnathon의 방어에서, 나는 순열 규칙이 그의 게시물 5 분 후에 추가되었다고 생각합니다.
— Hand-E-Food

4

골프 스크립트 (60)

obl 이후. golfscript가 누락되었으며 멍청한 놈으로서 연습이 필요합니다 :)

[48 10{rand}:r~+65 26r+97 26r+33 15r+11,{;32 96r+}%~]{r}$''+

4 개의 필수 + 11 개의 임의의 문자로 배열을 빌드하고 임의의 순서로 정렬합니다.


일에 대한 {r}$. 그것은 목록을 뒤섞는 아주 더러운 방법입니다. 마음에 듭니다! ;-)
— Ilmari Karonen

...하지만, 이것이 예를 들어 출력 할 수 있다고 생각하지 않습니다 0Aa~~~~~~~~~~~~. :-(
— Ilmari Karonen

3

자바 스크립트 (258) (240) 233 225

R=Math.random;a=b=>b[b.length*R()|0];for(x=[a(l="abcdefghijklmnopqrstuvwxyz"),a(u=l.toUpperCase()),a(n="0123456789"),a(s="`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./")];15>x.length;x.push(a(l+u+n+s)));alert(x.sort(y=>.5-R()).join(""))

다음과 같은 규칙 사용 :

function(x){return x*x}로 다시 쓸 수 있습니다 function(x)x*x. 값을 반환하는 함수에서만 작동하는 것 같습니다.

다음 반복을 감소, x.sort(function().5-R())에x.sort(y=>.5-R())

다음 반복은 뚱뚱한 화살표 표기법으로 더 줄어 들었으며 슬프게도 Firefox 22 이상에서만 작동합니다.


좋은 압축! : D
— IQAndreas

2

자바 스크립트 (269 자 압축)

명확성을 위해 다음은 JS-Fiddle을 압축 하기 전에 작성한 코드 입니다 .

var lowerLetters = "abcdefghijklmnopqrstuvwxyz";
var upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numbers = "0123456789";
var symbols = "`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./";
var allCharacters = lowerLetters + upperLetters + numbers + symbols;

String.prototype.randomChar = function() {
    return this[Math.floor(this.length * Math.random())];
}

var minLength = 15;
var result = [];

// Start off by picking one random character from each group
result.push(lowerLetters.randomChar());
result.push(upperLetters.randomChar());
result.push(numbers.randomChar());
result.push(symbols.randomChar());
// Next, pick a random character from all groups until the desired length is met
while(result.length < minLength) {
    result.push(allCharacters.randomChar());
}
result.shuffle(); // Finally, shuffle the items (custom function; doesn't actually exist in JavaScript, but is very easy to add) -> http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
result.join("");

여기에 269 자로 압축되어 있습니다 ( JS-Fiddle of ) :

l="abcdefghijklmnopqrstuvwxyz";
u=l.toUpperCase();
n="0123456789";
s="`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./";
R=Math.random;

function r(t){
    return t[~~(t.length*R())]
}

for(x=[r(l),r(u),r(n),r(s)];x.length<15;x.push(r(l+u+n+s)));
x.sort(function(){return .5-R()});
alert(x.join(""));

세미콜론으로 줄을 끝내기 때문에 모든 이동식 공백 문자는 문자 수로 무시되었지만 명확성을 위해 남겨졌습니다.
— IQAndreas

shuffle()"사용자 정의 기능" 이라는 것은 무엇을 의미합니까? 직접 작성해야하는 JavaScript 또는 코드의 일부입니까?
— Hand-E-Food

@ Hand-E-Food 필자는 JavaScript에 내장되어 있지 않다는 것을 의미했으며 여기의 모든 개발자가 배열을 섞는 방법을 알아야하므로 코드에 함수를 포함시키는 것이 불필요하다고 느꼈습니다. JS-Fiddle 에서 사용할 수 있습니다 (16 행).
— IQAndreas

1
내 요점은 바이트 수에 포함된다는 것입니다. 그러나 이제 압축 버전으로 구현 했으므로 무시하십시오. :-)
— Hand-E-Food

2

클로저 (63) :

(->> (map char (range 33 127)) (shuffle) (take 15) (apply str))

그러나 각 범주에서 하나 이상의 문자 (위, 아래, 숫자, 기호)를 포함하도록 개선해야합니다.


2

sql-server에서

declare @a nvarchar(28)
set @a='abcdefghijklmnopqrstuvwxyz'
declare @b nvarchar(max)
set @b='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
declare @c nvarchar(max)
set @c='0123456789'
declare @d nvarchar(max)
set @d='~!@#$%^&*()_+-={}|[]\:";<>?,./'

select left(substring(@a,cast(rand()*10 as int),3)+substring(@b,cast(rand()*10 as int),6)+substring(@c,cast(rand()*10 as int),3)+substring(@d,cast(rand()*10 as int),5),15)

행동 -1에서보십시오

행동 -2에서보십시오


1
마지막 줄을 따르는 데 문제가 있지만 코드가 모든 순열 요구 사항 을 충족하지 못하는 것 같습니다 .
— IQAndreas

귀하의 코드는으로 시작 ~0Aa하는 비밀번호 나 b뒤에 오는 비밀번호를 생성하지 않습니다 a.
— Heinzi

@ Heinzi : 예 나는 단지 15 개의 길이를 표시하지 않고 필요한 모든 순열에 동의합니다. 길이는 15에서 표시됩니다. ..
— vhadalgi

2

SAS (191)

%macro c(p);compress(p,,"&p")ne''%mend;data x;length p$15;do x=1by 1;do t=1to 15;substr(p,t,1)=byte(ranuni(7)*94+33);end;if %c(kd)and %c(kl)and %c(ku)and %c(ad)then do;put p;stop;end;end;run;

*TQP,(f=h10*)S=

주석 / 들여 쓰기 :

%macro c(p); /*compress removes or keeps certain classes of characters*/
  compress(p,,"&p")ne''
%mend;
data x;
length p$15;
do x=1by 1;
    do t=1to 15;
        substr(p,t,1)=byte(ranuni(7)*94+33); /*give it a 33-126, byte discards the noninteger portion rounding down*/
    end;
    if %c(kd)and %c(kl)and %c(ku)and %c(ad)then do; /*k=keep d=digit l/u=lower/upper ad=remove digits and alphas*/
        put p;
        stop;  /*met our requirement, head home*/
    end;
end;
run;

2

PowerShell : 119

고플 코드

for(;!($x-cmatch'.*(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!-/:-@[-`{-~]).*')){$x='';1..15|%{$x+=[char](33..126|random)}}$x

언 골프 및 댓글 달기

# Start for loop definition.
for(
    # Skip variable initialization, start definition of run condition.
    ;
    # Loop runs if $x does not meet complexity requirements.
    # Length requirement is not tested here because it is enforced by the generator later.
    # Much thanks to @VasiliSyrakis for the RegEx help.
    !($x-cmatch'.*(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!-/:-@[-`{-~]).*')
)
{
    # Reset $x in case the script block has already run.
    $x='';
    # Use ForEach-Object, via the % alias, to run a loop 15 times.
    1..15|%{
        # Append a random ASCII character from 33-126 to $x.
        # Note: Use get-random instead of random for faster performance.
        $x+=[char](33..126|random)
    }
}
# Display $x.
$x
# Variable cleanup - not included in golfed code.
rv x

나는이 정규 표현식이 그것을 조금 더 짧게 만들 수 있다고 생각합니다 : ^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$, 이것과 하나의 일치를 수행 할 수 있습니다.
— Vasili Syrakis

@VasiliSyrakis Ok, 당신은 저를 조금 걸어야 할 수도 있습니다. 잠시 시간이 걸릴 것이라고 생각되면 대화방을 시작하십시오. 내가 혼란스러워하는 몇 가지 사항 : 1.) 나는 거기에 숫자 15가 포함되어 있음을 봅니다. 문자열이 정확히 15 자인지 확인하는 것입니까? 이 경우 스크립트는 자연스럽게 15 자 문자열 만 생성 하므로 생략 할 수 있습니다 . 2.) "상위, 하한, 숫자, 기호가 하나 일 때만 일치합니다"라는 것은 무엇을 의미합니까? 가있는 경우에만 일치 그게 무슨 뜻 정확히 각 중 하나, 또는 적어도 각 중 하나를? 전자는 일을 망칠 것입니다.
— Iszi

또한 RegEx는 문자 순서를 무시합니까? 예를 들어, 4 자 문자열과 일치하도록 조정 된 경우 1aZ%와 (p3R일치합니까? 온라인에서 방법을 찾는 데 어려움이있었습니다.
— Iszi

현재 스크립트의 출력에 대해 새 RegEx를 테스트했습니다. 그것은 믿을만한 것 같지 않습니다. 코드 : $x-cmatch'^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$'좋은 경기 : C>suD1?hTwbDx(z j%4O]HyeG|u[U$5 O/rGeD0$hJk=GO/실패한 경기 : 3evthX3_X^nBrR` .nA ~ uYzrR4YV-r.`u-IjZE48ntQ;HxV
— Iszi

대화방을 열려면 어떻게합니까?
— Vasili Syrakis

1

파이썬 2.7 (149)

from random import*
''.join(map(lambda x:chr(randint(*(x[1]or(32,126)))),sorted(map(None,sample(range(15),15),((48,57),(65,90),(97,122),(33,47))))))

더 읽기 쉽고 실행 가능한 방식으로 작성되었습니다.

from random import *
''.join(                                          # Concatenate characters to string
  map(                                            # Map all characters using below lambda
    lambda x:chr(randint(*(x[1] or (32, 126)))),  # Map a single range to a random character
                                                  # within a specific range if supplied,
                                                  # otherwise the default "all" range.
    sorted(                                       # After distributing ranges, sort
      map(None,                                   # zip_longest alternative, distributes the
                                                  # required ranges over 4 random positions
        sample(range(15), 15),                    # 0-14 in random order
        ((48, 57), (65, 90), (97, 122), (33, 47)) # The 4 required ranges
      )
    )
  )
)

"직접 실패시 생성, 재시도"버전보다 상당히 간단하고 놀랍지 않습니다.


이 경우 실제로 다음을 포함하여 모든 적합한 비밀번호를 생성 할 수 0Aa~~~~~~~~~~~~있습니까? (즉, 참고 '~' == chr(126).)
— Ilmari 카로 넨에게

1

PSQL (189)

PSQL이 약간 장황한 것 같습니다 ... :)

SELECT ARRAY_TO_STRING(ARRAY_AGG(CHR((TRUNC((b-a)*RANDOM()+a))::int)ORDER BY RANDOM()),'')FROM(SELECT 32 a,127 b FROM generate_series(1,11)UNION ALL VALUES(48,58),(65,91),(97,123),(33,48))a

SQLfiddle 데모 .


1

PHP, 235 225

이 스크립트는 문자를 뒤섞은 다음 RegEx를 통해 확인하여 암호가 강력한 지 또는 다시 생성되는지 확인합니다.

<?php
while(!preg_match('/^(?=.*[A-Z])(?=.*[^A-Za-z])(?=.*[0-9])(?=.*[a-z]).{15}$/',$p)){ $p = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()_+-={}|[]\:";\'<>?,./'),0,15); }
echo $p;

1
영리하지만 중복 문자는 허용하지 않습니다.
— Hand-E-Food

1
대신 while(true) ... if (condition) break사용할 수 있습니다while (!condition)
— exussum

1

자바 스크립트 (209)

r=Math.random;function t(x,y){return String.fromCharCode(Math.floor(y*r()+x))};x=[t(33,14),t(48,10),t(65,26),t(97,26)];for(i=0;i<11;i++)x.push(t(32,95));console.log(x.sort(function(){return r()-0.5}).join(''))

반 굴곡;

// Return a character in the range [x,x+y)
function t(x,y) { return String.fromCharCode(Math.floor(y*Math.random()+x)) }
// Prefill required ranges
x=[ t(33,14), t(48,10), t(65,26), t(97,26)]
// Push 11 totally random (valid) characters
for(i=0; i<11; i++)
  x.push(t(32,95))
// Shuffle and output as string
console.log(x.sort(function(){return Math.random()-0.5})
             .join(''))

1

펄, 92

루비 답변만큼 간결하지는 않지만 펄 마법사가 이것을 더 짧게 만들 수 있다고 확신합니다 ... m//결국 모든 것에 만족하지는 않지만 작동하는 것처럼 보이고 결국에는 조건을 충족시켜야합니다. 모든 순열.

do{$_=join"",map{(map{chr}33..127)[rand 94]}0..14}while!(/[A-Z]/&/[a-z]/&/\d/&/[\W_]/);print

샘플 사용법 :

perl -e 'do{$_=join"",map{(map{chr}33..127)[rand 94]}0..14}while!(/[A-Z]/&/[a-z]/&/\d/&/[\W_]/);print'

유효성 검사를 수정하고 MvG 주석 이후로 변경 [[:punct:]]하도록 편집되었습니다 [\W_].


1
생성 부분은 훌륭하지만 루프 조건에서 선택 기준이 잘못되었습니다. 예를 들어 암호 aaaaaaaaaaaaaa는 루프를 종료시킵니다. 임의의 암호가 아닌 기준으로 테스트하여 원하는대로 수행하는지 확인해야합니다.
— MvG

실제로, 당신은 정확합니다, 나는 이것을 고치고 약간의 바이트를 절약했습니다! 감사!
— Dom Hastings

1
이것에 대해 확신 [[:punct:]]합니까? '[\ W_] , which is shorter and of which I'm even more sure that it is correct, at least combined with your 33..127` 범위를 선호 합니다.
— MvG

좋은 점은 \W포함하지 않는 것이 걱정 스럽지만 gist.github.com/anonymous/8301237_ 은 꼭 필요한 것은 아닙니다 . 감사합니다!
— Dom Hastings

1

자바 7 ( 270 234 자)

전제는 java 8과 함께 @assylias에서 사용한 것과 동일합니다 (유효한 비밀번호까지 임의의 비밀번호 생성). 그러나 람다를 사용하는 대신 char 배열을 반복하여 암호를 생성하고 정규식과 일치시켜 유효성을 검사합니다.

class A {
  public static void main(String [] a) {
    byte[] b = new byte[15];
    String s;
    do {
      new java.util.Random().nextBytes(b);
      s = new String(b);
    } while(!s.matches("(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[!-/:-@\\[-`]).*"));
    System.out.println(s);
  }
}

축소 된 코드 :

class A {public static void main(String[] a){byte[] b=new byte[15];String s;do{new java.util.Random().nextBytes(b);s=new String(b);}while(!s.matches("(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[!-/:-@\\[-`]).*"));System.out.println(s);}}

1

파워 쉘


하나의 라이너 버전 (143 바이트)

sal g random;1..11|%{$P+=[char](33..126|g)};(65..90|g),(97..122|g),(48..57|g),(33..47+58..64+123..126|g)|%{$P=$P.insert((1..11|g),[char]$_)};$P

미니 버전 (146 바이트)

sal g random
1..11|%{$P+=[char](33..126|g)}
(65..90|g),(97..122|g),(48..57|g),(33..47+58..64+123..126|g)|%{$P=$P.insert((1..11|g),[char]$_)}
$P

읽을 수있는 버전 (860 바이트)

function pwgen {

    # Fulfill Upper,Lower,Digit,Symbol requirement by predefining ASCII ranges for each
    # These will be added into the string beginning at line 24

    [array[]]$symbolrange = (33..47),(58..64),(123..126)

    [char]$upper = (get-random (65..90))
    [char]$lower = (get-random (97..122))
    [char]$digit = (get-random (48..57))
    [char]$symbol = $symbolrange | get-random

    [char[]]$requirement = $upper + $lower + $digit + $symbol

    # Create the first 11 characters using any ASCII character between 32 - 126

    foreach ($number in (1..11)) {
        [string]$pass += [char](get-random (33..126))
    }

    # Insert each requirement character at a random position in the string

    foreach ($char in $requirement) {
        [string]$pass = $pass.insert((Get-Random (1..11)),$char)
    }

    return $pass
}

코드 단축을위한 다양한 팁에 대해 Iszi에게 감사드립니다.


1
모든 순열을 다루지는 않습니다. 예를 들어, 적어도 하나의 기호가 ASCII 33과 47 사이 여야 abcd1234ABCD{|}~하므로 절대로 나타나지 않습니다.$symbol
— Hand-E-Food

단깃! 내 게으름을 지적해야합니까!? 농담이야 ... 지금 편집 했어. 또한 각 "요구 사항"문자를 동일한 인덱스에서 4 개를 함께 묶지 않고 문자열 내에서 별도의 인덱스로 이동했습니다. 지금 만 이것을 줄일 수 있다면 ...
— Vasili Syrakis

당신이 $SR아마 짧아서 더 많은 캐릭터를 면도 할 수없는 이유가 $Q있습니까?
— Iszi

당신은 또한 같은 컷 물건을 할 수 있어야 (g(65..90))에 이르기 65..90|g'. And change the 까지 foreach` 문 foreach-object은 Using 루프 %별칭을. 예 : foreach($N in (1..11)){... }같은 해 드리겠습니다해야한다 1..11|%{... }. 가능한 다른 최적화가 있다고 확신하지만 나중에 시도 할 계획이라는 완전히 다른 구현을 생각했습니다.
— Iszi

좋은 팁 :) 캐리지 리턴을 꺼내 세미콜론으로 바꾸면 213 바이트로 줄였습니다.
— Vasili Syrakis가

1

196 자

MvG 및 무스와 동일한 알고리즘입니다. 가장 짧지는 않지만 질문의 모든 (현재) 기준을 충족해야합니다.

USING: io kernel math pcre random sequences sequences.repeating ;
[ 15 94 random-integers [ 33 + ] "" map-as dup 60 cycle
"[A-Z].*[a-z].*[0-9].*[\\W_]" findall { } = not ] [ drop ] until print

정규식을 잘못 해석했을 수도 있지만 정규식 ~{}|1234abcdABCD이 실패하는 것 같습니다 .
— Hand-E-Food

1
작동하지 않습니다 :"~{}|1234abcdABCD" 60 cycle "[A-Z].*[a-z].*[0-9].*[\\W_]" findall empty? not => t
— Björn Lindqvist

나는 당신의 말을 받아 들일 것입니다. :-)
— Hand-E-Food

1

C-154 자

char p[16],c,f,w;main(){srand(time());while(f^15){c=p[15]=f=0;while(c^15){w=33+rand()%94;f|=w
>96&&w<123?1:w>47&&w<59?2:w>64&&w<91?4:8;p[c++]=w;}}puts(p);}

내가 어떻게 싫어 srand()? 길을 세어 보자.


1

하스켈, 192

import System.Random
main=getStdGen>>= \g->(print.(take 15))$until((\x->all(any(`elem`x))[['a'..'z'],['A'..'Z'],['0'..'9'],['!'..'/']++":;<=>?@[\\]^_`{|}~"]).(take 15))tail$randomRs('"','~')g

인쇄 된 문자열은 따옴표로 묶고 백 슬래시와 따옴표 문자를 이스케이프 처리합니다. 허용되지 않는 경우 3 바이트를 더할 print수 있습니다 putStrLn. 더 읽기 쉬운 버전은 다음과 같습니다.

import System.Random

main = do
    g <- getStdGen
    let chars = randomRs ('"', '~') g
    let password = take 15 $ until (hasChars.(take 15)) tail chars
    print password

hasChars :: String -> Bool
hasChars x = all (any (`elem` x)) $
    [ ['a'..'z']
    , ['A'..'Z']
    , ['0'..'9']
    , "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
    ]

그것은 매우 간단합니다. 범위 내에서 임의의 ASCII 문자로 무한 / 게으른 목록을 만듭니다. '!' 에를 '~'한 후, 처음 15 개 문자가 필요한 문자의 각 문자열에서 적어도 하나 개의 문자를 때까지 첫 번째 요소를 밖으로 던져.


1

Excel VBA, 209 바이트

For i = 1 To 15
x = x + Chr(Int(90 * Rnd + 33))
Next
p = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$"
With New RegExp
.Pattern = p
Set m = .Execute(x)
If m.Count = 0 Then
MsgBox "redo"
Else
MsgBox x
End If
End With

15 개의 ASCII 문자를 임의로 생성하므로 가능한 모든 조합이 가능합니다. 그런 다음 정규식 패턴을 사용하여 각 기준 중 하나 이상이 포함되어 있는지 확인하십시오.

암호가 표시되면 암호가 표시되고 그렇지 않으면 "재실행"이 표시됩니다.

정규 표현식 패턴에 대한 Bart Kiers의 감사의 글 : https://stackoverflow.com/questions/1559751/regex-to-make-sure-that-the-string-contains-at-least-one-lower-case-char- 높은


0

오토 핫키 352

global o:={}
loop 4
o[c()]:=o(A_index-1)
loop 11
o[c()]:=o(m(r(),4))
loop 15
s.=o[A_index-1]
msgbox % s
r(){
Random,z
return z
}
m(z,r){
return mod(z,r)
}
c(){
while o[t:=m(r(),15)]!=""
j++
return t
}
o(f){
r0:=48,l0:=10,r1:=97,l1:=l2:=26,r2:=65
r := chr(r%f%+m(r(),l%f%))
if f=3
r:=Substr("``~!@#$%^&*()_+-={}|[]\:"";'<>?,./",m(r(),32)+1,1)
return r
}

사용 -그냥 스크립트를 실행


0

파이썬 (121 자)

파이썬에서리스트를 곱할 수 있다는 사실을 이용합니다 [1,2,3] * 2는 [1,2,3,1,2,3]을줍니다. 무작위로 가져옵니다. 목록의 숫자에 3을 곱한 숫자는 필요한 문자의 ASCII 테이블 범위 사이의 경계입니다 (예 : [65, 90]은 대문자로 매핑됩니다).

print "".join([random.choice([chr(i) for i in range(z[0],z[1])]) for z in [[33,48],[48,58],[58,65],[65,90],[90,123]]* 3])

1
"허용 가능한 모든 문자의 모든 순열을 생성 할 수 있어야합니다." 범위가 항상 같은 순서로 적용되기 때문에 그렇게하지는 않습니다 ...?
— Joachim Isaksson

네 말이 맞아, 고마워 실제로 범위가 임의의 순서로 적용되어야한다는 것을 알지 못했습니다.
— Pawelmhm

실제로 import random코드에 포함시켜야 합니다.
— Mego

0

PHP 5.5 (230 바이트)

echo preg_replace_callback('/./', function ($a)
{
  return chr([rand(33, 126), rand(48, 57), rand(65, 90), rand(97, 122), ord(str_shuffle('`~!@#$%^&*()_+-={}|[]\:";\'<>?,./')[0])][$a[0]]);
}
, str_shuffle(str_pad('1234', 15, 0)));

또는 한 줄 (211 바이트)

echo preg_replace_callback('/./',function($a){return chr([rand(33,126),rand(48,57),rand(65,90),rand(97,122),ord(str_shuffle('`~!@#$%^&*()_+-={}|[]\:";\'<>?,./')[0])][$a[0]]);},str_shuffle(str_pad('1234',15,0)));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.