Apakah Anda ingin membatasi diri untuk ASCII atau skrip latin? Bagaimana dengan diakritik seperti aksen (é, â ...)?
Stéphane Chazelas
Terima kasih atas tindak lanjutnya. Pos asli yang diperbarui untuk klarifikasi.
ardevd
Apakah ini benar-benar perlu di bash? Apakah bahasa seperti Perl atau awk akan dilakukan?
terdon
1
Lalu mengapa tidak memanggil Perl atau Python dari bash? Apalagi dengan perl, sangat mudah menggunakannya sebagai one-liner.
terdon
2
Apakah Anda mencoba belajar atau hanya menginginkan hasilnya? Dalam kasus kedua ada banyak program yang melakukan pekerjaan seperti john the ripper ( john) dan sejenisnya, yang akan memberi Anda banyak kemungkinan.
YoMismo
Jawaban:
13
Inilah solusi bash yang menggunakan panjang yang diinginkan sebagai parameter (Anda akan melakukannya permute 5dalam kasus Anda):
#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;}
Menjalankannya:
make CFLAGS=-O3 permute && time ./permute 5>/dev/null #about 20s on my PC
Bahasa tingkat tinggi menyedot kekerasan (yang pada dasarnya adalah apa yang Anda lakukan).
@ Stéphane Chazelas Terima kasih banyak untuk suntingan itu. Saya menulis kata-kata kotor, mengabaikan kutipan yang "tepat" karena tidak diperlukan dalam kasus ini, tetapi saya sangat berterima kasih atas pintasannya!
PSkocik
Saya mencoba bashsolusi Anda . Itu sangat bagus; Saya sangat menyukainya. Ini bekerja dengan baik selama sekitar 24 jam sebelum saya perhatikan sistem saya benar-benar terkunci. Mencoba sesuatu yang mirip dengan `python; dengan hasil yang serupa, meskipun itu jauh lebih cepat.
Anda dapat melakukan loop yang sama bash, tetapi bashmenjadi shell paling lambat di barat, itu akan memakan waktu berjam-jam:
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
(pada sistem saya, yang output pada 700 kiB / s sebagai lawan 20MiB / s dengan yang perlsetara).
Saya juga merasa bahwa itu akan menambah jawaban jika Anda ingin menambahkan cara untuk mengeluarkannya ke file; mungkin karena sedang dibuat sehingga tidak merusak RAM Anda, atau setelah itu semua di-cache dalam ram
Hellreaver
2
@ Hellreaver, mereka semua menulis ke file (ke stdout, file apa pun yang terbuka untuk; jika dijalankan di terminal, file perangkat seperti /dev/pts/something; dan Anda dapat mengubahnya dengan operator pengalihan shell), bukan memori, tetapi yang pertama dibangun seluruh output dalam memori sebelum mengeluarkannya (ke file terbuka di stdout).
Stéphane Chazelas
4
Berikut cara untuk melakukannya murni di bash tanpa harus mengisi memori 5 GB:
perl
, sangat mudah menggunakannya sebagai one-liner.john
) dan sejenisnya, yang akan memberi Anda banyak kemungkinan.Jawaban:
Inilah solusi bash yang menggunakan panjang yang diinginkan sebagai parameter (Anda akan melakukannya
permute 5
dalam kasus Anda):Tapi lambat sekali. Berani saya sarankan C? https://youtu.be/H4YRPdRXKFs?t=18s
Menjalankannya:
Bahasa tingkat tinggi menyedot kekerasan (yang pada dasarnya adalah apa yang Anda lakukan).
sumber
bash
solusi Anda . Itu sangat bagus; Saya sangat menyukainya. Ini bekerja dengan baik selama sekitar 24 jam sebelum saya perhatikan sistem saya benar-benar terkunci. Mencoba sesuatu yang mirip dengan `python; dengan hasil yang serupa, meskipun itu jauh lebih cepat.Di
bash
, Anda dapat mencoba:tapi itu akan memakan waktu lama dan menghabiskan semua ingatanmu. Yang terbaik adalah menggunakan alat lain seperti
perl
:Waspadalah itu 6 x 62 5 byte, jadi 5.496.796.992.
Anda dapat melakukan loop yang sama
bash
, tetapibash
menjadi shell paling lambat di barat, itu akan memakan waktu berjam-jam:(pada sistem saya, yang output pada 700 kiB / s sebagai lawan 20MiB / s dengan yang
perl
setara).sumber
/dev/pts/something
; dan Anda dapat mengubahnya dengan operator pengalihan shell), bukan memori, tetapi yang pertama dibangun seluruh output dalam memori sebelum mengeluarkannya (ke file terbuka di stdout).Berikut cara untuk melakukannya murni di bash tanpa harus mengisi memori 5 GB:
sumber
Versi bash ini masih tidak secepat Perl tetapi sekitar empat kali lebih cepat dari lima loop bersarang:
sumber
Anda dapat menggunakan
crunch
(yang tersedia setidaknya di distribusi Kali).sumber
Yah ... elegan ?, ya (hanya sampel cepat):
Ekspresi penuh ini kemungkinan besar akan memblokir komputer Anda:
Salah satu opsi non-blocking adalah menggunakan beberapa loop:
Sebut saja seperti:
Di mana argumen pertama adalah jumlah karakter dan yang kedua adalah daftar (spasi terpisah) dari karakter yang digunakan.
Itu akan membangun variabel (
loop
) dengan skrip untuk menjalankan dan eval terakhir akan menjalankan skrip itu. Misalnya untuk:Nilai
loop
akan:sumber
Gnu Parallel dapat melakukan kombinasi, lihat https://www.gnu.org/software/parallel/ Sesuatu seperti ini:
sumber