Rastgele Parola Oluşturucu


40

Etki alanı sunucusu, tüm çalışanların aşağıdaki kurallara uygun, güçlü ve rastgele bir parolaya sahip olmasını gerektirir:

  • Tam olarak 15 karakter uzunluğunda.
  • Yalnızca klavyede yazılabilir karakterler (aşağıdaki kod türünde gösterildiği gibi). Satışları ALT + NUMPAD kodlarını kullanmaya öğretmek yasaktır.
  • En az 1 küçük harf: abcdefghijklmnopqrstuvwxyz
  • En az 1 büyük harf: ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • En az 1 sayısal rakam: 0123456789
  • En az 1 sembol: `~!@#$%^&*()_+-={}|[]\:";'<>?,./

Bu amaçla BT devreye girdi ve tüm çalışanlara bir Rastgele Şifre Oluşturucu dağıtacak. Tüm çalışanların Rastgele Şifre Oluşturucu kullanması gerekecektir. Rastgele Şifre Oluşturucu için şartlar, yukarıdaki şifre kısıtlamalarına ek olarak:

  • Tüm izin verilen karakterlerin tüm izinlerini üretebilmelidir.
  • Oluşturulan şifreyi ekranda göstermesi gerekir.
  • Kodun olabildiğince küçük olması gerekir (bayt cinsinden).

Lütfen önerilen çözümünüzü önümüzdeki hafta içinde gönderin.


10
Ayrıca, izin verilen tüm şifrelerin aynı olasılıkta görünmesini talep etmelisiniz (aksi halde izin verilen karakterlerle 30 karakter uzunluğunda bir liste yapabilir, karıştırıp ilk 15'ini verebilirim)
Martin Thoma

@moose, kabul etti. Yeni bir kural ekledim.
El-E-Yemek

22
BT görevlileri kovulmalı ya da en azından daha iyi eğitimli olmalı: Eğer rastgele şifreler oluşturursanız, izin verilen şifreler kümesini her kategorinin en az bir karakterini içerenler ile sınırlandırmak, aslında şifresini zayıflatır , çünkü izin verilen küme. Ve bunu kontrol etmek zorunda kalmazsak programlarımız çok daha kolay olurdu… Tamam, çok fazla başvuru geldikten sonra yarışmayı değiştirmeyin; bu bir meydan okuma olarak iyi.
MvG


1
Tüm şifrelerin üretilebilir olmasını gerektiren @ moose kelimesini gerçekten yanıtlamadınız. Eşit olasılıkla görünmeleri gerekir.
Ethan Bolker,

Yanıtlar:


29

Mathematica (18)

Bana biraz hile yapalım

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

PS güvenli değil :)


6
Kod nerde?
DavidC

11
Her karakter sınıfı gereksiniminin en az birini yerine getirme garantisi var mı ?
El-E-Yemek

3
@ El-E-Yemek Evet, öyle! Yoruma bakarsanız, göreceksiniz: şifre uzunluğu 15, küçük harf gerekli, büyük harf gerekli, sayılar gerekli, özel karakterler gerekli.
ybeltukov

6
+1 Zekice, ama sinsi.
DavidC

10
Mathematica'nın her şey için bir işlevi olduğunu biliyordum, ama bu ?
Konrad Borowski

13

Ruby, 74 69 bayt

Tüm karakter sınıfları mevcut olana dek sadece 33 - 126 ascii aralığından rastgele örnek alın:

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

Ruby, 39 bayt

Mus'un zekice keşfini kullanarak:

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

Mafyayı tatmin etmek için düzenleyin:

Bunu ilk gönderdikten sonra kuralların değiştiğini unutmayın . O zaman hem önceki girişler kurallara uygulanırdu. Ayrıca kuralların hala çok iyi tanımlanmadığını da belirtmek isterim:

(..) tüm izin verilen karakterlerin tüm izinleri

"Permutasyonlar". Orada hiçbir permütasyon kuralların geri kalanı ile uyumlu olduğu, izin verilen karakterlerin setinin herhangi permütasyon izin verilen karakterlerin kendisi kümesi sürece çünkü (şifre 15 karakter uzunluğunda olması gerekiyordu iken) o izin verilen karakter. Ve bir permütasyonda tekrarlama yoktur. Ancak benim ilk girişim, buradaki diğer iyi reddedilen cevapların çoğundan daha "rastgele".

Yine de, işte burada. Karakter ve alt çizgi tekrarlarını sağlar:

Ruby, 77 bayt

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

Bunun putsyerine de kullandım pçünkü p"tırnak işaretleri" içine alınmış dizgiyi ve ters eğik çizgiyle kaçan bazı karakterleri yazdırıyor.

Ruby, 70 bayt

Ventero'nun işaret ettiği gibi, regex'lerin ~önüne atlanabilir ve printyerini alabilir puts$_. Ancak bu çirkin çıktıyla, reddedilen tüm şifreleri de tek bir linere sıkarak yazdırabilirsiniz:

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

açıklama

İstendiği gibi. $_girişten okunan son satırı içeren bir yarı büyülü değişkendir - her zaman olduğu gibi saklamak gerek kalmaz bu . Ancak burada başka bir özellik nedeniyle kullanıyoruz, yani ~operatör doğrudan kendisine regex uygular, ilk önce chron tarafından öğrendiğim bir numara . Kullanımının yerini değiştirdim all, ancak dinlenip dinlenmediğinizi anlamak oldukça kolay olmalı ( belgelere bakın ).


2
Lütfen kodunuzu biraz açıklayabilir misiniz? Ne yapar .all?{|r|~r}? Ne yapar $_=?
Martin Thoma

3
Örnek çizgi zekice ve hepsi, ancak bence “İzin verilen tüm karakterlerin tüm permütasyonlarını üretebilmelidir” ihlal ediyor. Hiçbir yerde, parolanın yalnızca harfler söz konusu olduğunda reklam içerebileceğini söylemez. Z izin verilen bir karakterse, z'nin şifrenizde> 0 olması ihtimali vardır.
nitro2k01

1
Does \WRuby alt çizgiyi _? Çoğu regex lehçesinde bilmiyorum. Eğer kodunuz, tek bir _alfanümerik olmayan sembolün tek olduğu bir şifre oluşturamazsa , bir şartı ihlal eder. İkinci yaklaşım açıkça açıkça bu gereksinimi ihlal ediyor, ancak sanırım o zaman doğru bir şekilde ifade edilmedi.
MvG

1
@ MVG: Haklısın. \WPerl uyumlu RegEx'te ( kaynak ) alt çizgi içermez .
Martin Thoma

1
Dahası, çözümünüz aynı problemden etkilenir @moose ve Python ile yaşadım: sampleelemanları tekrar etmiyor, bu yüzden tekrarlanan elemanlara sahip şifreler kodunuz tarafından üretilemiyor. Sizinkinin nasıl bir lider çözüm olduğunu görün, Wolfram Alpha dışında, uygun olup olmadığınızı görmek ve liderliği devam ettirmek iyi olurdu. Sanırım çok zor olmamalı.
MvG

12

Java 8 - 354 329 319 275 267 karakter

Sadece eğlence için, Java 8 ile lambda kullanmak - her bir olası çıktı aynı bulunma ihtimaline sahiptir.

İzin verilen karakterlerin 33 ile 126 arasında art arda ascii kodlarına sahip olduğu gerçeğini kullanır.

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

Örnek çıktı:

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

Sıkıştırılmış program:

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


Bunun yerine while(a+A+d+p<4)birlikte nasıl olur ? Veya kullanım değerleri bir bit maskesi gibi yani şeyler through ile, olarak döngü koşulu. Doğru sayılırsam, bu başka 13 karakter kaydeder. a|=1a++a|=1a|=8a<15
MvG

@ MVV iyi bir nokta - inanıyorum birkaç ekstra karakter tasarrufu, benzer bir şey yaptı.
assylias

@MvG Kullanarak new String(int[],int,int)başka 40 garip karakter kaydeder!
assylias

8

Python 2.X + 3.X (229 karakter): Üret ve değiştir

Fikir

  1. İlk önce izin verilen 15 sembolden oluşan bir liste yapın
  2. Rastgele bir pozisyonu rrastgele bir rakamla değiştirme
  3. Rastgele pozisyon değiştirin sile s != rbir büyük harf gelen,
  4. Küçük harf ve sembol 2 ve 3'teki ile aynıdır.

kod

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 karakter): Üretin ve kontrol edin

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)
  • Bunu bana söyleyen \uve \lPython regex'te olmayan MvG'ye teşekkürler .
  • Bana bunun değiştirilmemiş olduğunu söyleyen grc sayesinde, random.sampledeğiştirilen örneklememiz gereken izin verilen her şifreyi alabilmeniz için.

Problem açıklamasında kusur kullanımı

Şu anda, problem tanımı her sembol / rakamın aynı olasılıkta görünmesini gerektirmemektedir. Aşağıdaki çözümle, tek bir sembol ve / veya pozisyon hakkında herhangi bir varsayımda bulunamazsınız. Ama bunu birden fazla olanla yapabilirsiniz.

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

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

Fikir kullanmak için daniero teşekkürler örnek kullanmak için.


Kusuru bulmak çok yumuşak! Bunu taktım, ama tanımlamak için bonus puan. :-)
El-E-Yemek

Geniniz ve çekiniz benim yaklaşımıma benziyor. Meraktan: \lpython regex'ler için bu ve benzeri belgeler nerede? Bunu göremiyor musunuz referans . Python 3.3.3 bile kabul etmiyor "\u". str(…)3.3.3 veya 2.7.6 ya harfleri katılmak etmez. Optmization için bir öneri: all(s("\\"+i,p)for i in "dluW").
MvG

random.sampleöğeleri değiştirmeden seçer, böylece tüm şifreler mümkün değildir.
grc

@ MVG: Teşekkürler. Bunu daha önce gördüm \uve \lsadece vim olduğunu .
Martin Thoma

7

Bash üzerinde * nix (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

Düzgün çalışmak için, $aönceden geçerli ancak rastgele olmayan bir parola ayarlanmamalıdır. Dahil etmek a=ve bir satır önde olmak istiyorsanız , bu üç karakter daha var, ancak tekrar tekrar çalıştırmanıza olanak tanıyor. Açıkçası tüm yeni satırları değiştirebilir, ;böylece dilediğiniz sıklıkta uygulayabileceğiniz tek bir gömlek kullanabilirsiniz.

Ayrıca, karakter aralıkları ascii düzene eşit olan harmanlama sırasına bağlı olduğundan LC_ALL=Cyerel ve belirli herhangi bir ortam değişkenini ( LANGveya LC_CTYPEözellikle de) belirlemelisiniz veya ayarlamamalısınız .

/dev/urandomrastgele baytların kaynağıdır. !-~soruda belirtildiği gibi izin verilen tüm karakterlerin aralığıdır. tr -dctüm karakterleri kaldırır değil bir sonraki argüman listelenen. headkalan karakterlerden 15 tanesini alır. grepGerekli türlerin her birinin en az bir kez gerçekleşip gerçekleşmediğini kontrol eder. Girdileri adayın dört nüshasından oluşuyor, bu nedenle sembollerin sırası önemli değil, bu nedenle olası tüm şifreler seçme şansına sahip. -qBastırır çıktı grep.

Nedenleri bilinmeyen için, /dev/randomyerine /dev/urandomyaşları alır. Entropi oldukça çabuk tükenmiş gibi görünüyor. Eğer cdiçine /devkoyarsanız, biraz daha bayttan kaçınabilirsiniz, ancak bu biraz hile gibi geliyor.

Piton 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

Kodu okunaklı kılmak için, gerekli olmayan ve saymadığım döngüden sonra yeni bir satır ve girintiler ekledim.

Bu aslında bash versiyonundakiyle aynı fikirdir. Buradaki rastgele kaynak random.sample, elemanları tekrar etmeyecek olmasıdır. Bu gerçeğe karşı koymak için, izin verilen mektuplar listesinin 15 kopyasını kullanıyoruz. Bu şekilde, tekrarlanan harfleri olanlar daha az gerçekleşse de, her kombinasyon hala gerçekleşebilir. Ancak bu sorunun bir hata olarak görülmemesine karar verdim, çünkü soru tüm permütasyonlar için eşit olasılık gerektirmiyordu, sadece olasılık.

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

Bir newline ve bir girinti tekrar sayılmaz. Bazı Python-3'e özgü sözdizimlerinin yanı sıra, bu Python 2 ile aynı çözümdür.

JavaScript (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)

Okunabilirlik için yeni satırları ekledim ancak saymadım.

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

Döngü içindeki satır sonu ve girinti eklendi, ancak sayılmadı. Eğer böyle hissederseniz, bunu tekrar ayrı bir ;satıra taşıyabilirsiniz .


Ha! greplR kodunuzda kullanabileceğinizi belirtmek üzereydim . Keşke test şifresini dört kez tekrarlamayı düşünebilseydim bütün kontrolleri bir arada yapabildin. Ve bilirsin, keşke sampleve hakkında düşünseydim intToUtf8. Bununla birlikte, olası tüm şifreleri aldığınızdan emin olmak için örnek yönteminize eklemeniz replace=TRUE(veya daha kısa bir şekilde eklemeniz gerekir ,T) gerekir .
AmeliaBR

@AmeliaBR: Haklısın, bu replace=Thatayı düzelttin, bunu gösterdiğin için teşekkürler. intToUtf8Sekme tamamlama ile olası isimleri tahmin ederek bulmak biraz zaman aldı; Böyle bir işlevin var olması gerektiğini biliyordum, ama benzeri daha yaygın isimler chrkullanılmadı.
MvG,

@MvG: Python kodunuzun neden sonlandırıldığını anlamıyorum. Neden buna ihtiyacın var *4? Regex'inizin herhangi bir dizeyle eşleşeceğini düşündüm, o reklam ilk önce bir büyük harf, sonra herhangi bir şey, sonra bir küçük harf, her şeyden önce ... ne yanlış anladım?
Martin Thoma

@moose: Daha önce fark ettiğiniz gibi, regex'im gerekli kategorileri belirli bir sırada kontrol ediyor. Ancak mevcut adayın dört nüshasının bir araya getirilmesiyle, siparişin artık önemli olmamasını sağlayabilirim: Şifrem, sembollerin ardından gelen küçük harf ve ardından büyük harf ile gösterilen rakamlar olsa bile, yine de bir eşleşme olur. Bir eşleşmenin başarısız olabilmesinin tek yolu, bir kategorinin tamamen eksik olması. Ayrıca ben edemediğimizi re.searchdeğil re.matchregex aday şifreyi her yerde eşleşebileceğini yüzden. Bu nihayetinde neden sona ereceğini açıklıyor mu?
MvG

Ah, re.searchyerine kullandığını farketmedim re.match. Bu onu açıklar. Ama hala ihtiyacın olmadığını düşünüyorum *4. Açıklama için teşekkürler (+1)
Martin Thoma

7

C # ( 123 - 139 103 - 127 karakter sıkıştırılmış):

Mükemmel yeterli bir çerçeve yöntemi kullanarak System.Web.dll:

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

sıkıştırılmış:

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

Örnek:

b+m2ae0K:{dz7:A

Alternatif olarak, ikinci parametrenin ( int numberOfNonAlphanumericCharacters) değerini komut satırından alın:

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

3
GeneratePasswordsoruda belirtilen sembollerin tam setini desteklememektedir. Her karakter kategorisinin asgari oluşum sayısı hakkında hiçbir garanti bulamadım.
MvG

2
Sen kullanarak daha da sıkıştırmak olabilir class Pve string[] a.
d3dave

@ MVG, bu ilginç. Aksanlı karakterleri Fransızca gibi dillerde yazmak için yaygın olarak kullanılan herhangi bir sembolü içermez gibi görünüyor. Muhtemelen akıllıca bir hareket. Klavye dilini değiştirmek, şifrenizi doldurmanız için yeterli olacaktır.
El-E-Yemek

5

R (301 322 karakter)

Düzeltme rakamları kontrol etmeyi unuttu.

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

(sadece boşluk için beyaz boşluk eklendi).

94 karakterin tüm olası 15 karakterlik permütasyonlarını oluşturur. Ardından, ölçütleri karşılayana kadar rasgele birini seçer.

Sihir, birinci listedeki tüm faktörlerin ikinci listedeki tüm faktörlerle etkileşimi olanq:q yeni bir faktör veri türü üreten operasyonda, bu iki listenin her olası kombinasyonu "listesine dahil edildi" Bu faktörün seviyeleri ". İzin verilen karakter listesinin 15 kopyasını birleştirin ve (94 ^ 15) olası seviyelere sahip olun.q

Lütfen bunu evde denemeyin. Kodun, tüm üç karakterli permütasyonları bulması birkaç saniye sürüyor, bilgisayarınız 15: 15’deki tüm karakter karakterlerini çözmenin ne kadar süreceğini hayal bile edemiyorum. bu arada. Kontrol etmek için bitmiş (üç karakterli şifre) betiğini çalıştırdığımda, tükürdüğü ilk şifre "oO =" idi, ki sanırım bu koda vermeniz gereken tepkiyi özetliyor.


@MvG, çok daha az harika olsa, hem çok daha pratik hem de daha kısa bir R komut dosyasına sahiptir: codegolf.stackexchange.com/a/17700/12413
AmeliaBR

Yine de, fikrini beğendim. Gördüğüm birçok kod golfü snippet'i, dilin belirli özelliklerinin çok çalışmasına izin verdi. Ve kodunuz kesinlikle R için bu etkileşimlerle yapar.
MvG

4

Mathematica 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]

Örnekler

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


4

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

Sorunun tanımında gerekli olmadığından birleşimini kaldırarak 9 basamaktan daha az puan alabilirsiniz. Boşluk kaldırarak 2 daha az.
Martin Thoma

@ moose Yorum bırakmadan hemen önce boşlukları çıkardım :-) Kendimi joinorada olması gerektiği gibi hissediyorum : Kullanıcıların çıktıdan gelen python listesi sözdizimini anlamaları beklenir mi ['q', 'u', ...]?
Jonathon Reinhart

1
Baskıyı tamamen kaldırmayı düşündüm. Bayt cinsinden boyut önemliyse, delikli kart zamanında yaşayabilirler. Bu şekilde, hafızayı okuyabilirler ... sadece bakarak. Ya da "gerçek programcılar" dır
Martin Thoma

1
Kodu doğru okuyorsam, bu tüm izin şartlarını yerine getirmiyor , her zaman 12 küçük harf olacak ve diğer gruplardan (benzeri aA$bc1111111111) birden fazla şifreyi imkansız hale getirecek .
IQAndreas,

1
Johnathon'un savunmasında, permütasyonlar kuralının görevinden 5 dakika sonra eklendiğini düşünüyorum.
El-E-Yemek

4

Golf Yazısı (60)

Obl beri. golfscript eksik ve noob olarak yine de uygulamaya ihtiyacım var :)

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

Sadece gerekli 4 + 11 rasgele karakterden oluşan bir dizi oluşturur ve rasgele sırada sıralar.


İçin +1 {r}$. Bu bir listeyi karıştırmanın oldukça kirli bir yolu. ;-)
Ilmari Karonen

... bununla birlikte, bunun örneğin çıktısını alacağını sanmıyorum 0Aa~~~~~~~~~~~~. :-(
Ilmari Karonen

3

JavaScript 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(""))

Bir kural kullanarak nerede:

function(x){return x*x}olarak yeniden yazılabilir function(x)x*x. Sadece bir değer döndüren işlevlerde işe yarar gibi görünüyor.

Düşük sonraki iterasyon, x.sort(function().5-R())içinx.sort(y=>.5-R())

Sonraki iterasyon, ne yazık ki sadece Firefox 22 ve üzeri için işe yarayan şişman ok gösterimi ile daha da azaltıldı.


Güzel sıkıştırma! : D
IQAndreas

2

JavaScript (sıkıştırılmış 269 karakter)

Anlaşılır olması için, bu kodu daha önce bunu aşağı sıkıştırılmış bunun 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("");

Burada 269 karaktere kadar sıkıştırılmıştır ( JS-Fiddle ):

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

Noktaları noktalı virgüllerle sonlandırdığım için, tüm çıkarılabilir boşluklar karakter sayımı için göz ardı edildi, ancak netlik için bırakıldı.
IQAndreas

shuffle()Özel işlev olarak neyi kastediyorsunuz ? JavaScript'in veya kodun bir parçası mı, kendin yazmak zorunda mıydın?
El-E-Yiyecek

@ Hand-E-Food Bunun anlamı, JavaScript'in yerleşik olmadığı ve buradaki herhangi bir geliştiricinin bir dizinin nasıl karıştırılacağını bilmesi gerektiğinden, koddaki işlevi eklemenin gereksiz olduğunu hissettim. Yine de JS-Fiddle'da mevcuttur (satır 16).
IQAndreas

1
Demek istediğim, bayt sayınıza göre sayılır. Ama şimdi sıkıştırılmış versiyonda uyguladığınızı anlıyorum, bu yüzden lütfen beni dikkate almayın. :-)
El-E-Yemek

2

Clojure (63):

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

Ancak, her bir kategoriden en az 1 karakter içerdiğinden emin olmak için iyileştirilmesi gerekir (Üst, Alt, Rakam, Sembol).


2

Sql-server içinde

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)

Eylem görmek - 1

Eylem görmek - 2


1
Son satırı takip etmekte sorun yaşıyorum ancak kod tüm izin şartlarını yerine getiriyor gibi görünmüyor .
IQAndreas

Kodunuz, hiçbir zaman başlayan ~0Aabir şifre veya bardından gelen bir şifre üretmez a.
Heinzi

@Heinzi: evet gerekli tüm izinleri hesaba katmadan sadece 15 uzunluk gösterir .. katılıyorum ... rastgele seçilmiş bir ... z, A..Z, 0..9,! ... + :(. ..
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=

Yorumlananlar / girintili:

%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

Gofled Kodu

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

Un-golfed ve Yorumlandı

# 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

Bence bu regex biraz daha kısaltabilir: Bununla ^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$bir maç yapabilirsiniz, bu sadece bir Üst, Alt, Rakam, Sembol olduğunda eşleşir.
Vasili Syrakis

@ VasiliSyrakis Tamam, bu konuda biraz yürümek zorunda kalabilirsiniz. Bir süre alacağını düşünüyorsanız, bir sohbet odası başlatmaktan çekinmeyin. Kafamı karıştırdığım birkaç şey: 1.) Orada 15 numaralı numarayı görüyorum. Bu dize tam olarak 15 karakter olduğundan emin olmak için mi? Eğer öyleyse, bu ihmal edilebilir, çünkü senaryo doğal olarak sadece 15 karakterli dizeler oluşturur. 2.) "Sadece bir Üst, Alt, Rakam, Sembol olduğunda eşleşecek" derken ne demek istiyorsun? Bu, yalnızca her birinin tam olarak biri veya en az birinin olması durumunda eşleşeceği anlamına mı geliyor ? Eski şeyleri kıracak.
Iszi

Ayrıca, RegEx'iniz karakterlerin sırasını yok sayıyor mu? Örneğin, eğer her ikisi olur, 4 karakterli dizeleri maç için aşağı ayarlı 1aZ%ve (p3Rmaç? Bunu çevrimiçi yapmak için bazı yollar bulmakta zorlandım.
Iszi

Yeni RegEx'i mevcut betiğimin çıktısına karşı test etti. Çok güvenilir görünmüyor. Kod: $x-cmatch'^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$'İyi maçlar: C>suD1?hTwbDx(z j%4O]HyeG|u[U$5 O/rGeD0$hJk=GO/Başarısız maçlar: 3evthX3_X^nBrR` .nA ~ uYzrR4YV-r.`u-IjZE48ntQ;HxV
Iszi

Bir sohbet odasını nasıl açarım?
Vasili Syrakis

1

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

Daha okunaklı (çalıştırılabilir değil) bir şekilde yazılmıştır;

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

Oldukça dümdüz ileri ve şaşırtıcı bir şekilde bir "üretme, yeniden deneme başarısız" sürümünden çok daha uzun değil.


Bunun, örneğin, dahil olmak üzere tüm uygun şifreleri oluşturabileceğinden emin misiniz 0Aa~~~~~~~~~~~~? (Unutmayın '~' == chr(126).)
Ilmari Karonen

1

PSQL (189)

PSQL biraz ayrıntılı gibi geliyor ... :)

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


1

PHP, 235 225

Bu komut dosyası karakterleri karıştırır ve daha sonra parolanın güçlü olduğundan emin olmak için (veya yeniden oluşturulduğundan) RegEx aracılığıyla denetlenir.

<?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
Akıllıca, ancak yinelenen karakterlere izin vermiyor.
El-E-Yemek

1
Yerine while(true) ... if (condition) breakkullanabilirsinizwhile (!condition)
exussum

1

Javascript (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(''))

Yarı ungolfed;

// 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

Perl, 92

Ruby'nin cevabı kadar özlü değil, ama bir Perl sihirbazının bunu daha da kısaltabileceğinden eminim ... m//Sonunda bütün s ile çok mutlu değilim , ama işe yarayacak gibi görünüyor ve sonuçta ortaya çıkan koşulları yerine getirmeli. tüm permütasyonlar

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

Örnek kullanım:

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

Doğrulamayı düzeltmek ve MvG’lerin yorumlarının ardından olarak değiştirmek [[:punct:]]için düzenlenmiştir [\W_].


1
Oluşturma bölümünüz hoş, ancak döngü koşulundaki seçim ölçütünüz açıkça yanlış: örneğin bir parola aaaaaaaaaaaaaadöngünün sonlanmasına neden olur. Kriterleri rastgele olmayan şifrelerle test etmelisiniz, istediklerini yaptıklarından emin olmak için.
MvG

Aslında, haklısın, bunu düzelttim ve bazı baytlar kurtardım! Teşekkürler!
Dom Hastings

1
Bundan emin misin [[:punct:]]? Sanırım '[\ W_] , which is shorter and of which I'm even more sure that it is correct, at least combined with your 33..127` aralığını tercih ederim .
MvG

İyi bir nokta, bence \Wdahil etmediğim için endişeliydim _, ancak kesinlikle haklısınız, buna gerek yok: gist.github.com/anonymous/8301237 . Teşekkür ederim!
Dom Hastings

1

Java 7 ( 270 234 karakter)

Öncül java 8 ile @assylias tarafından kullanılan aynıdır (geçerli parola kadar rasgele şifreler oluşturmak). Ancak, lambdas kullanmak yerine, şifre bir karakter dizisini yineleyerek üretilir ve bir regex eşleştirerek doğrulanır.

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

Küçük Kod:

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

Güç kalkanı


Bir Liner sürümü (143 bayt)

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

Mini sürüm (146 bayt)

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

Okunabilir versiyon (860 bayt)

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
}

Kodu kısaltmak için çeşitli ipuçları için Iszi'ye teşekkür ederiz.


1
Bu, tüm permütasyonları kapsamaz. Bir örnek olarak, abcd1234ABCD{|}~çünkü yukarı gelmeyecek $symbolsembollerin güçleri en az bir ASCII 33 ve 47 arasında olduğu
El-E-Gıda

Dangit! Tembellikten bahsetmek zorunda mısın? Şaka yapıyorum ... Şimdi değiştirdim. Ayrıca her "gereksinim" karakterini, dördünün aynı dizinde bir araya toplanması yerine, dizgideki ayrı bir dizine gitmesini sağladım. Şimdi eğer bunu kısaltabilirsem ...
Vasili Syrakis

$SRBelki de kısaltarak birkaç karakteri daha fazla tıraş etmemenin bir nedeni var mı $Q?
Iszi

Ayrıca , takma adı kullanarak döngüler (g(65..90))için 65..90|g'. And change the foreach ifadelerinin aşağısındaki gibi şeyleri de kesebilmelisiniz . Örnek: ... yapılabilir gibi olmalıdır ... . Diğer optimizasyonların da mümkün olduğundan eminim, ancak daha sonra denemeyi düşündüğümden tamamen farklı bir uygulamaya sahibim. foreach-object%foreach($N in (1..11)){}1..11|%{}
Iszi

Güzel püf noktaları :) Taşıyıcıların iadelerini alıp noktalı virgüllerle değiştirirsem 213 bayta düşürdüm.
Vasili Syrakis

1

Faktör, 196 karakter

MvG ve moose's ile aynı algoritma. En kısa değil, ancak sorudaki tüm (mevcut) kriterleri yerine getirmesi gerekiyor:

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

Regex'i yanlış yorumluyor olabilirim, ama bence ~{}|1234abcdABCDregex'in başarısız olacağını düşünüyorum .
El-E-Yemek

1
Hayır, işe yarayacak:"~{}|1234abcdABCD" 60 cycle "[A-Z].*[a-z].*[0-9].*[\\W_]" findall empty? not => t
Björn Lindqvist

Bunun için sözünü alacağım. :-)
El-E-Yemek

1

C - 154 karakter

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

Nasıl nefret ederim srand()? Yollarını saymama izin ver.


1

Haskell, 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

Yazdırılan dizenin etrafında tırnaklar vardır ve ters eğik çizgiden ve alıntı karakterlerinden kaçar; Bu kabul edilemezse, 3 bayt için printdeğiştirilebilir putStrLn. İşte daha okunaklı bir sürüm:

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']
    , "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
    ]

Sorun yok, sadece aralığında rasgele bir ASCII karakter sonsuz / tembel liste oluşturur, oldukça basittir '!'için '~', sonra ilk 15 karakter gerekli her karakter dizisinin en az bir karaktere sahip kadar ilk elemanını dışarı fırlatır.


1

Excel VBA, 209 bayt

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

Rasgele 15 ASCII karakter oluşturur, böylece tüm olası kombinasyonlar mümkün olur. Ardından, her kriterden en az birini içerip içermediğini kontrol etmek için normal bir ifade deseni kullanır.

Bunu yaparsa, şifre görüntülenir, "yeniden yapılmadıysa" görüntülenir.

Düzenli İfade deseni için Bart Kiers'a teşekkür ederiz: https://stackoverflow.com/questions/1559751/regex-to-make-sure-that-the-string-contains-at-least-one-lower-case-char- üst


0

AutoHotkey 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
}

Kullanımı - Sadece betiği çalıştırın


0

Python (121 karakter)

Python [1,2,3] * 2'deki listeleri çoğaltabileceğiniz gerçeğinden faydalanır [1,2,3,1,2,3]. Rastgele alır. Üç ile çarpılan bir listedeki sayılar, ascii tablosundaki gerekli karakterler için aralıklar arasındaki sınırlardır, örneğin [65, 90] büyük harflerle eşleşir.

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
Msgstr "İzin verilen tüm karakterlerin tüm izinlerini üretebilmelidir". Aralıkları her zaman aynı sırayla uyguladığınız için bunu yaptığını sanmıyorum ...?
Joachim Isaksson

Haklısın teşekkür ederim. Aslında, aralıkların rasgele sırayla uygulanması gerektiğini fark etmedim, karıştırıldılar, birazdan bunu düzenleyeceğim.
Pawelmhm

Bunun aslında import randomkoda dahil edilmesi gerekiyor .
Mego

0

PHP 5.5 (230 bayt)

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

Veya bir satırda (211 bayt)

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)));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.