Czy chcesz ograniczyć się do ASCII lub skryptu łacińskiego? Co ze znakami diakrytycznymi, takimi jak akcenty (é, â ...)?
Stéphane Chazelas
Dzięki za kontynuację. Zaktualizowany oryginalny post dla wyjaśnienia.
ardevd
Czy to naprawdę musi być bash? Czy zrobi to język taki jak Perl czy awk?
terdon
1
Dlaczego więc nie po prostu wywołać Perla lub Pythona z bash? Zwłaszcza z tym perl, że jest bardzo łatwy w użyciu jako jednowarstwowy.
terdon
2
Próbujesz się nauczyć, czy chcesz tylko wynik? W drugim przypadku jest wiele programów, które wykonują takie zadania, jak John Ripper ( john) i tym podobne, co daje wiele możliwości.
YoMismo,
Odpowiedzi:
13
Oto rozwiązanie bash, które przyjmuje żądaną długość jako parametr (zrobiłbyś to permute 5w twoim przypadku):
#include <stdio.h>//global variables and magic numbers are the basis of good programming
const char* charset ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char buffer[50];
void permute(int level){
const char* charset_ptr = charset;if(level ==-1){
puts(buffer);}else{while(buffer[level]=*charset_ptr++){
permute(level -1);}}}
int main(int argc, char **argv){
int length;
sscanf(argv[1],"%d",&length);//Must provide length (integer < sizeof(buffer)==50) as first arg;//It will crash and burn otherwise
buffer[length]='\0';
permute(length -1);return0;}
Uruchom:
make CFLAGS=-O3 permute && time ./permute 5>/dev/null #about 20s on my PC
Języki wysokiego poziomu są do kipienia brutalnym wymuszaniem (to w zasadzie to, co robisz).
@ Stéphane Chazelas Dziękuję bardzo za tę edycję. Pisałem brudne, ignorując „właściwe” cytowanie, ponieważ w tym przypadku nie jest potrzebne, ale jestem bardzo wdzięczny za skróty!
PSkocik
Próbowałem twojego bashrozwiązania. To bardzo miłe; Bardzo to lubię. Działało dobrze przez około 24 godziny, zanim zauważyłem, że mój system został całkowicie zamknięty. Próbowałem czegoś podobnego z `python; z podobnym wynikiem, chociaż był znacznie szybszy.
Możesz wykonać tę samą pętlę bash, ale bashponieważ jest to najwolniejsza powłoka na zachodzie, zajmie to wiele godzin:
export LC_ALL=C # seems to improve performance by about 10%
shopt -s xpg_echo # 2% gain (against my expectations)set{a..z}{A..Z}{0..9}for a dofor b dofor c dofor d dofor e do
echo "$a$b$c$d$e"done;done;done;done;done
(w moim systemie wydajność ta wynosi 700 kiB / s, a nie 20MiB / s przy perlekwiwalencie).
Wydaje mi się również, że dodałoby to do odpowiedzi, gdybyś dodał sposób na wyprowadzenie go do pliku; może podczas generowania, aby nie zniszczył pamięci RAM, lub po tym, jak wszystko jest buforowane w pamięci RAM
Hellreaver
2
@Hellreaver, wszyscy piszą do pliku (na standardowe wyjście, do dowolnego pliku, na który jest otwarty; jeśli jest uruchamiany w terminalu, plik urządzenia jak /dev/pts/something; i można to zmienić za pomocą operatora przekierowania powłoki), nie pamięć, ale pierwszy buduje całe wyjście w pamięci przed wysłaniem (do pliku otwartego na standardowe wyjście).
Stéphane Chazelas
4
Oto sposób na zrobienie tego czysto w trybie bash bez konieczności gryzenia 5 GB pamięci:
perl
, że jest bardzo łatwy w użyciu jako jednowarstwowy.john
) i tym podobne, co daje wiele możliwości.Odpowiedzi:
Oto rozwiązanie bash, które przyjmuje żądaną długość jako parametr (zrobiłbyś to
permute 5
w twoim przypadku):Jest to jednak boleśnie powolne. Czy mogę polecić C? https://youtu.be/H4YRPdRXKFs?t=18s
Uruchom:
Języki wysokiego poziomu są do kipienia brutalnym wymuszaniem (to w zasadzie to, co robisz).
źródło
bash
rozwiązania. To bardzo miłe; Bardzo to lubię. Działało dobrze przez około 24 godziny, zanim zauważyłem, że mój system został całkowicie zamknięty. Próbowałem czegoś podobnego z `python; z podobnym wynikiem, chociaż był znacznie szybszy.W
bash
możesz spróbować:ale zajęłoby to wieczność i pochłonęło całą pamięć. Najlepiej byłoby użyć innego narzędzia, takiego jak
perl
:Uważaj, to 6 x 62 5 bajtów, więc 5 496 796,992.
Możesz wykonać tę samą pętlę
bash
, alebash
ponieważ jest to najwolniejsza powłoka na zachodzie, zajmie to wiele godzin:(w moim systemie wydajność ta wynosi 700 kiB / s, a nie 20MiB / s przy
perl
ekwiwalencie).źródło
/dev/pts/something
; i można to zmienić za pomocą operatora przekierowania powłoki), nie pamięć, ale pierwszy buduje całe wyjście w pamięci przed wysłaniem (do pliku otwartego na standardowe wyjście).Oto sposób na zrobienie tego czysto w trybie bash bez konieczności gryzenia 5 GB pamięci:
źródło
Ta wersja bash wciąż nie jest tak szybka jak Perl, ale jest około cztery razy szybsza niż pięć zagnieżdżonych pętli:
źródło
Możesz użyć
crunch
(który jest dostępny przynajmniej w dystrybucjach Kali).źródło
Cóż ... elegancki ?, tak (tylko szybka próbka):
To pełne wyrażenie najprawdopodobniej zablokuje komputer:
Jedną z opcji nieblokujących jest użycie kilku pętli:
Nazwij to tak:
Gdzie pierwszy argument to liczba znaków, a drugi to lista (oddzielone spacjami) użytych znaków.
To zbuduje zmienną (
loop
) ze skryptem do uruchomienia, a ostatnia ewaluacja wykona ten skrypt. Na przykład dla:Wartość
loop
będzie wynosić:źródło
Gnu Parallel może wykonywać kombinacje patrz https://www.gnu.org/software/parallel/ Coś takiego:
źródło