Serwer domeny wymaga, aby wszyscy pracownicy mieli silne, losowe hasło zgodne z następującymi zasadami:
- Dokładnie 15 znaków.
- Tylko znaki wpisywane na klawiaturze (jak pokazano poniżej w kodzie). Nauczanie sprzedaży używania kodów ALT + NUMPAD jest niedozwolone.
- Co najmniej 1 mała litera:
abcdefghijklmnopqrstuvwxyz
- Co najmniej 1 duża litera:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
- Co najmniej 1 cyfra:
0123456789
- Co najmniej 1 symbol:
`~!@#$%^&*()_+-={}|[]\:";'<>?,./
W tym celu dział IT zlecił i rozprowadzi generator losowych haseł do wszystkich pracowników. Wszyscy pracownicy będą zobowiązani do korzystania z generatora losowych haseł. Wymagania dotyczące generatora losowych haseł to, oprócz powyższych ograniczeń hasła:
- Musi być w stanie wygenerować wszystkie permutacje wszystkich dozwolonych znaków.
- Musi wyświetlać wygenerowane hasło na ekranie.
- Kod musi być jak najmniejszy (w bajtach).
Prześlij swoje proponowane rozwiązanie w ciągu następnego tygodnia.
correcthorsebatterystaple
Odpowiedzi:
Matematyka (18)
Pozwól mi trochę oszukać
PS to nie bezpieczeństwo :)
źródło
Ruby,
7469 bajtówPo prostu losowo próbkuj z zakresu ascii 33–126, aż wszystkie klasy znaków będą obecne:
Rubin, 39 bajtów
Wykorzystując sprytne odkrycie łosia:
Edytuj, aby zaspokoić tłum:
Pamiętaj, że zasady uległy zmianie po pierwszym opublikowaniu tego. W tym czasie oba poprzednie wpisy dotyczyły reguł. Chciałbym również zauważyć, że reguły wciąż nie są zbyt dobrze zdefiniowane:
„Permutacje”. Nie ma permutacji dozwolonych znaków, która jest zgodna z resztą reguł, ponieważ każda permutacja zestawu dozwolonych znaków jest tak długa, jak sam zestaw dopuszczalnych znaków (podczas gdy hasło powinno mieć 15 znaków). I nie ma powtórzeń w permutacji. Mój pierwszy wpis jest jednak bardziej „losowy” niż wiele innych dobrze ocenianych odpowiedzi tutaj.
Niemniej jednak masz to. Umożliwia powtórzenia znaków i podkreślenie:
Rubinowy, 77 bajtów
Użyłem również
puts
zamiastp
tego, ponieważp
drukuje ciąg zamknięty w „cudzysłowie”, a niektóre znaki uciekały odwrotnym ukośnikiem.Rubinowy, 70 bajtów
Jak zauważa Ventero,
~
można go pominąć przed wyrażeniami regularnymi iprint
zastąpićputs$_
. Ale z brzydkim wyjściem powoduje to, że równie dobrze możesz wydrukować wszystkie odrzucone hasła, ściskając je w jednej linijce:Wyjaśnienie
Zgodnie z prośbą.
$_
jest pół-magiczną zmienną, która zawiera ostatni wiersz odczytany z danych wejściowych - więc nie zawsze musisz ją przechowywać, tak jak to . Tutaj jednak używamy go z powodu innej właściwości, a mianowicie, że~
operator stosuje do niej wyrażenie regularne, sztuczkę, której nauczyłem się po raz pierwszy przez Chrona . Zastąpiłem użycieall
, ale powinno być dość łatwe do zrozumienia, jeśli dostaniesz resztę ( zobacz dokumenty ).źródło
.all?{|r|~r}
zrobić? Co ma$_=
zrobić?\W
w Ruby zawiera podkreślenie_
? W większości dialektów regularnych wiem, że tak nie jest. A jeśli twój kod nie mógł wygenerować haseł, w których pojedynczy_
był jedynym niealfanumerycznym symbolem, to naruszyłoby jedno wymaganie. Drugie podejście bardzo oczywiście narusza ten wymóg, ale wydaje mi się, że w tamtym czasie nie było poprawnie sformułowane.\W
nie zawiera podkreślenia w RegEx kompatybilnym z Perlem ( źródło ).sample
nie powtarza elementów, więc hasła z powtarzającymi się elementami nie mogą być generowane przez kod. Czy możesz rozwiązać te dwa problemy, aby twoja odpowiedź była zgodna z pytaniem? Widząc, jak twoje jest wiodącym rozwiązaniem, z wyjątkiem Wolfram Alpha, fajnie byłoby zobaczyć, czy możesz się dostosować i nadal utrzymać pozycję lidera. Myślę, że nie powinno to być zbyt trudne.Java 8 -
354329319275267 znakówDla zabawy, używając lambda z Javą 8 - każde możliwe wyjście ma takie samo prawdopodobieństwo znalezienia.
Wykorzystuje fakt, że dozwolone znaki mają kolejne kody ascii, od 33 do 126.
Przykładowe dane wyjściowe:
Skompresowany 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);}}
źródło
while(a+A+d+p<4)
wraz za|=1
zamiasta++
? Lub użyj masek bitowych, tj. Takich jaka|=1
przelotowea|=8
, za<15
warunkiem pętli as. To oszczędza kolejne 13 znaków, jeśli poprawnie policzyłem.new String(int[],int,int)
zapisuje kolejne 40 znaków nieparzystych!Python 2.X + 3.X (229 znaków): Generuj i zamień
Pomysł
r
na losową cyfręs
, zs != r
, przez górną literyKod
Python 2.X + 3.X (194 znaki): Wygeneruj i sprawdź
\u
i\l
nie istnieje w wyrażeniu regularnym Python.random.sample
nie ma zamiany, aby uzyskać każde możliwe dozwolone hasło, musimy pobrać próbkę z wymianą.Wykorzystanie błędu w opisie problemu
Obecnie opis problemu nie wymaga, aby każdy symbol / cyfra pojawiał się z takim samym prawdopodobieństwem. Dzięki poniższemu rozwiązaniu nie można zakładać żadnego pojedynczego symbolu i / lub pozycji. Ale możesz to zrobić za pomocą wielu.
Python 2.X + 3.X (62 znaki)
Dzięki Daniero za pomysł użycia próbki.
źródło
\l
udokumentowane dla wyrażeń regularnych w Pythonie? Nie widzę tego w referencji . Mój Python 3.3.3 nawet nie zaakceptuje"\u"
.str(…)
Nie łączy litery w obu 3.3.3 lub 2.7.6. Jedna sugestia dla optmization:all(s("\\"+i,p)for i in "dluW")
.random.sample
wybiera elementy bez zamiany, więc nie wszystkie hasła są możliwe.\u
i\l
jest to tylko vim.Bash na * nix (109)
Aby działać poprawnie,
$a
nie może być ustawione na prawidłowe, ale nieprzypadkowe hasło z góry. Jeśli chcesz dołączyća=
i linię z przodu, to trzy kolejne znaki, ale pozwala ci to powtarzać. Oczywiście możesz również zastąpić wszystkie nowe wiersze,;
aby mieć linijkę, którą możesz wykonywać tak często, jak chcesz.Ponadto powinno być ustawione
LC_ALL=C
czy nie ustawić jakieś zmienne środowiskowe locale specyficzne (LANG
aLC_CTYPE
zwłaszcza), ponieważ zakresy znaków zależą kolejność sortowania jest równa kolejności ASCII./dev/urandom
jest źródłem losowych bajtów.!-~
to zakres wszystkich dopuszczalnych znaków, jak określono w pytaniu.tr -dc
usuwa wszystkie znaki niewymienione w następnym argumencie.head
bierze 15 pozostałych postaci.grep
sprawdza, czy każdy z wymaganych rodzajów występuje przynajmniej raz. Jego dane wejściowe składają się z czterech kopii kandydata, więc kolejność symboli nie ma znaczenia, dlatego wszystkie możliwe hasła mają szansę zostać wybranymi. Opcja-q
grep tłumi wyjście.Z nieznanych przyczyn
/dev/random
zamiast na/dev/urandom
wieki. Wygląda na to, że entropia dość szybko się wyczerpała. Jeślicd
w/dev
, można uniknąć jeszcze kilka bajtów, ale czuje się trochę jak oszustwo.Python 2 (138)
Aby kod był czytelny, dodałem nowy wiersz i wcięcie po pętli, które nie są konieczne i których nie policzyłem.
Jest to zasadniczo ten sam pomysł, co w wersji bash. Tutaj jest losowe źródło
random.sample
, które nie będzie powtarzać elementów. Aby temu zaradzić, używamy 15 kopii listy dozwolonych liter. W ten sposób każda kombinacja może nadal występować, chociaż te z powtarzającymi się literami będą występować rzadziej. Ale decyduję się uznać to za cechę, a nie za błąd, ponieważ pytanie nie wymagało jednakowego prawdopodobieństwa dla wszystkich permutacji, tylko możliwość.Python 3 (145)
Jeden nowy wiersz i jedno tiret ponownie nie są liczone. Oprócz pewnych narzutów składni specyficznych dla Python-3 jest to to samo rozwiązanie, co dla Python 2.
JavaScript (161)
Dodałem nowe wiersze dla czytelności, ale ich nie policzyłem.
R (114)
Dodano przerwanie linii i wcięcie wewnątrz pętli, ale nie zostało zliczone. Jeśli masz na to ochotę, możesz ponownie przenieść to do pojedynczej
;
linii.źródło
grepl
w swoim kodzie R. Gdybym tylko pomyślał o powtórzeniu hasła testowego cztery razy, abyś mógł wykonać wszystkie kontrole za jednym razem. I wiesz, gdybym tylko pomyślałsample
iintToUtf8
. Musisz jednak dodaćreplace=TRUE
(lub bardziej zwięźle, wystarczy dodać,T
) do przykładowej metody, aby upewnić się, że otrzymujesz wszystkie możliwe hasła.replace=T
błąd, dziękuję za zwrócenie na to uwagi. ZnalezienieintToUtf8
zgadując prawdopodobne nazwiska z zakończeniem zakładce zajęło mi sporo czasu; Wiedziałem, że taka funkcja musi istnieć, alechr
nie używano bardziej popularnych nazw takich jak i tak dalej.*4
? Myślałem, że twoje wyrażenie regularne będzie pasować do dowolnego łańcucha, w tej reklamie najpierw jedna wielka litera, potem cokolwiek, a potem jedna mała litera, niż cokolwiek ... co pomyliłem?re.search
niere.match
, więc wyrażenie regularne może pasować w dowolnym miejscu w haśle kandydata. Czy to wyjaśnia, dlaczego ostatecznie wygasa?re.search
zamiastre.match
. To wyjaśnia to. Ale nadal uważam, że nie potrzebujesz*4
. Dziękuję za wyjaśnienie (+1)C # (
123 - 139103 - 127 znaków zagęszczonych):Korzystanie z idealnie odpowiedniej metody ramowej w
System.Web.dll
:Zagęszczony:
Przykład:
Możesz też pobrać wartość drugiego parametru (
int numberOfNonAlphanumericCharacters
) z wiersza poleceń:źródło
GeneratePassword
nie obsługuje pełnego zestawu symboli określonych w pytaniu. Nie znalazłem też żadnych gwarancji co do minimalnej liczby wystąpień każdej kategorii postaci.class P
istring[] a
.R (
301322 znaków)Korekta zapomniała sprawdzić cyfry.
(białe znaki dodano tylko dla jasności).
Generuje wszystkie możliwe 15-znakowe kombinacje 94 znaków. Następnie losowo wybiera jeden, dopóki nie spełni kryteriów.
Magia tkwi w
q:q
operacji, która generuje nowy typ danych czynników, czyli interakcję wszystkich czynników z pierwszejq
listy ze wszystkimi czynnikami z drugiej listy , przy czym każda możliwa kombinacja tych dwóch list znajduje się na liście „ poziomy ”tego czynnika. Wejdź w interakcję z 15 kopiami listy dozwolonych postaci, a otrzymasz (94 ^ 15) możliwych poziomów.Nie próbuj tego w domu. Kod zajmuje kilka sekund, aby dowiedzieć się o wszystkich 3-znakowych kombinacjach. Naprawdę nie wyobrażam sobie, ile czasu zajęłoby ustalenie wszystkich 15-znakowych kombinacji, jeśli komputerowi nie zabrakło pamięci w międzyczasie. Kiedy uruchomiłem gotowy skrypt (hasło składające się z trzech znaków), aby to sprawdzić, pierwsze hasło, które wypluło, to „oO =”, co myślę o podsumowaniu reakcji na ten kod.
źródło
Mathematica 170
Przykłady
"<]} Pg3 / e? 3 + Z ~ Oz"
"X / 8jWe @ f (_x5P: ="
"2wz2VQhtJC? * R7 ^"
źródło
Python 2.7 (182)
źródło
join
musi być: Czy użytkownicy powinni rozumieć składnię listy python z wyjścia['q', 'u', ...]
:?aA$bc1111111111
).Golfscript (60)
Ponieważ obl. brakuje skryptu golfowego i i tak potrzebuję praktyki :)
Po prostu buduje tablicę z 4 wymaganymi + 11 losowymi postaciami i sortuje w losowej kolejności.
źródło
{r}$
. To dość brudny sposób na przetasowanie listy - podoba mi się! ;-)0Aa~~~~~~~~~~~~
. :-(JavaScript
258240233225Stosując regułę, w której:
function(x){return x*x}
można ponownie zapisać jakofunction(x)x*x
. Wydaje się, że działa tylko w przypadku funkcji zwracających wartość.Następna iteracja, zmniejszona
x.sort(function().5-R())
dox.sort(y=>.5-R())
Kolejna iteracja, zmniejszona dodatkowo dzięki grubej notacji strzałek, która niestety działa tylko w przeglądarce Firefox 22 i nowszych.
źródło
JavaScript (kompaktowane 269 znaków)
Dla jasności jest to kod, zanim go skompresowałem JS-Fiddle :
Tutaj jest spakowany do 269 znaków ( JS-Fiddle tego ):
źródło
shuffle()
że jesteś „funkcją niestandardową”? Czy to część kodu JavaScript lub kodu, który musiałbyś napisać sam?Clojure (63):
Ale należy je poprawić, aby zawierały co najmniej 1 znak z każdej kategorii (górny, dolny, cyfra, symbol).
źródło
Na serwerze SQL
Zobacz to w akcji - 1
zobacz to w Akcji - 2
źródło
~0Aa
, ani żadnego hasła, po którymb
następujea
.SAS (191)
*TQP,(f=h10*)S=
Skomentowane / wcięte:
źródło
PowerShell: 119
Kod Gofled
Nie grał w golfa i skomentował
źródło
^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$
możesz zrobić z nim jedno dopasowanie, które będzie pasować tylko wtedy, gdy będzie jeden górny, dolny, cyfrowy, symbol.1aZ%
i(p3R
pasują? Miałem trudności ze znalezieniem sposobów na zrobienie tego online.$x-cmatch'^.*(?=.{15,})(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!#$%&? "]).*$'
Dobre mecze:C>suD1?hTwbDx(z
j%4O]HyeG|u[U$5
O/rGeD0$hJk=GO/
Nieudane mecze:3evthX3_X^nBrR`
.nA ~ uYzrR4YV-r.u-IjZE48ntQ;HxV
Python 2.7 (149)
Napisane w bardziej czytelny (i nie wykonywalny) sposób;
Dość prosta i zaskakująco niewiele dłuższa niż wersja „generuj, spróbuj ponownie po porażce”.
źródło
0Aa~~~~~~~~~~~~
? (Uwaga'~' == chr(126)
.)PSQL (189)
Wydaje się, że PSQL jest trochę gadatliwy ... :)
Demo SQLfiddle .
źródło
PHP,
235225Ten skrypt tasuje znaki, a następnie jest sprawdzany przez RegEx, aby upewnić się, że hasło jest silne (lub zostało zregenerowane).
źródło
while(true) ... if (condition) break
możesz użyćwhile (!condition)
JavaScript (209)
Na wpół nieprzygotowany;
źródło
Perl, 92
Nie tak zwięzłe jak odpowiedź Ruby, ale jestem pewien, że czarodziej Perla może to jeszcze skrócić ... Nie jestem zbyt zadowolony ze wszystkich
m//
s na końcu, ale wydaje się, że działa i powinien spełniać warunki, aby w końcu wygenerować wszystkie permutacje.Przykładowe użycie:
Edytowane, aby naprawić sprawdzanie poprawności i zmienić
[[:punct:]]
na[\W_]
komentarze po MvG.źródło
aaaaaaaaaaaaaa
spowoduje, że pętla się zakończy. Powinieneś przetestować kryteria przy użyciu nieprzypadkowych haseł, aby upewnić się, że robią to, co chcesz.[[:punct:]]
? Chyba wolałbym, which is shorter and of which I'm even more sure that it is correct, at least combined with your
zasięg „[\ W_] 33..127”.\W
nie uwzględniono_
, ale masz absolutną rację, nie jest to konieczne: gist.github.com/anonymous/8301237 . Dziękuję Ci!Java 7 (
270234 znaków)Ta sama zasada jest używana przez @assylias z java 8 (generuj losowe hasła do prawidłowego hasła). Jednak zamiast używać lambdas, hasło jest generowane przez iterację tablicy char i sprawdzane przez dopasowanie wyrażenia regularnego.
Kod minimalny:
źródło
PowerShell
Wersja One Liner (143 bajty)
Wersja mini (146 bajtów)
Wersja do odczytu (860 bajtów)
źródło
abcd1234ABCD{|}~
nigdy nie pojawi się, ponieważ$symbol
zmusza co najmniej jeden z symboli do umieszczenia między ASCII 33 a 47.$SR
do$Q
?(g(65..90))
aby65..90|g'. And change the
wypowiadać instrukcje doforeach-object
pętli za pomocą%
aliasu. Przykład:foreach($N in (1..11)){
...}
powinno być wykonalne jak1..11|%{
...}
. Jestem pewien, że istnieją inne optymalizacje, które są możliwe, ale tak naprawdę mam zupełnie inną implementację, którą zamierzam wypróbować później.Współczynnik, 196 znaków
Ten sam algorytm jak MvG i łoś. Nie jest najkrótszy, ale powinien spełniać wszystkie (obecne) kryteria w pytaniu:
źródło
~{}|1234abcdABCD
zawiedzie wyrażenie regularne."~{}|1234abcdABCD" 60 cycle "[A-Z].*[a-z].*[0-9].*[\\W_]" findall empty? not => t
C - 154 znaków
Jak nienawidzę
srand()
? Pozwól mi policzyć drogi.źródło
Haskell, 192
Wydrukowany ciąg ma wokół siebie cudzysłowy i ucieka przed odwrotnym ukośnikiem i znakami cudzysłowu; jeśli to niedopuszczalne,
print
można je zastąpićputStrLn
przez 3 kolejne bajty. Oto bardziej czytelna wersja:Jest to dość proste, to po prostu tworzy nieskończoną / lazy listę losowych znaków ASCII w przedziale
'!'
do'~'
, a następnie rzuca się pierwszy element aż 15 pierwszych znaków mieć co najmniej jeden znak z każdej struny wymaganych znaków.źródło
Excel VBA, 209 bajtów
Generuje losowo 15 znaków ASCII, dzięki czemu możliwe są wszystkie możliwe kombinacje. Następnie używa wzorca wyrażenia regularnego, aby sprawdzić, czy zawiera on przynajmniej jedno z każdego kryterium.
Jeśli tak, pojawi się hasło, jeśli nie, pojawi się „ponów”.
Podziękowania dla Barta Kiersa za wzór wyrażeń regularnych: https://stackoverflow.com/questions/1559751/regex-to-make-sure-that-the-string-contains-at-least-one-lower-case-char- górny
źródło
AutoHotkey 352
Korzystanie - wystarczy uruchomić skrypt
źródło
Python (121 znaków)
Wykorzystuje fakt, że możesz pomnożyć listy w Pythonie [1,2,3] * 2 daje [1,2,3,1,2,3]. Importuje losowo. Liczby na liście pomnożone przez trzy są granicami między zakresami w tabeli ascii dla potrzebnych znaków, np. [65, 90] odwzorowuje na wielkie litery.
źródło
import random
w kodzie.PHP 5.5 (230 bajtów)
Lub w jednym wierszu (211 bajtów)
źródło