랜덤 비밀번호 생성기


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로케일 특정 환경 변수를 설정 (또는하지 LANGLC_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 코드에서 사용할 수 있다고 지적했습니다 . 테스트 암호를 네 번 반복하여 모든 검사를 한 번에 수행 할 수 있다고 생각한 경우. 내가 생각했던 경우에만 그리고 당신은 알고 sampleintToUtf8. 그러나 가능한 모든 암호를 얻으려면 샘플 메소드 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 Pstring[] 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.