그래서 5 자 문자열을 구성 할 수있는 소문자와 대문자 및 숫자의 가능한 모든 조합을 생성하고 싶습니다.
가능성 : a..z, A..Z 및 0..9.
bash 에서이 작업을 수행하는 우아한 방법이 있습니까?
답변
다음은 원하는 길이를 매개 변수로 사용하는 bash 솔루션입니다 ( permute 5
귀하의 경우).
#!/bin/bash
charset=({a..z} {A..Z} {0..9})
permute(){
(($1 == 0)) && { echo "$2"; return; }
for char in "${charset[@]}"
do
permute "$((${1} - 1 ))" "$2$char"
done
}
permute "$1"
그래도 고통스럽게 느립니다. C를 추천합니까? https://youtu.be/H4YRPdRXKFs?t=18s
#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);
return 0;
}
그것을 실행 :
make CFLAGS=-O3 permute && time ./permute 5 >/dev/null #about 20s on my PC
고급 언어는 무차별 강제 (기본적으로 수행중인 작업)에 영향을줍니다.
답변
에서가 bash
, 당신은 시도 할 수 있습니다 :
printf "%s\n" {{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}
그러나 그것은 영원히 걸리고 모든 기억을 소모합니다. 다음과 같은 다른 도구를 사용하는 것이 가장 좋습니다 perl
.
perl -le '@c = ("A".."Z","a".."z",0..9);
for $a (@c){for $b(@c){for $c(@c){for $d(@c){for $e(@c){
print "$a$b$c$d$e"}}}}}'
6 x 62 5 바이트이므로 5,496,796,992입니다.
같은 루프를 수행 할 수 bash
있지만 bash
서쪽에서 가장 느린 쉘이므로 몇 시간이 걸릴 것입니다.
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 do for b do for c do for d do for e do
echo "$a$b$c$d$e"
done; done; done; done; done
(내 시스템에서는 20MiB / s와 반대로 700kiB / s로 출력 perl
합니다).
답변
다음은 5GB의 메모리를 소모하지 않고 bash에서 순수하게 수행하는 방법입니다.
for c1 in {A..Z} {a..z} {0..9}
do
for c2 in {A..Z} {a..z} {0..9}
do
for c3 in {A..Z} {a..z} {0..9}
do
for c4 in {A..Z} {a..z} {0..9}
do
for c5 in {A..Z} {a..z} {0..9}
do
printf "%s\n" "$c1$c2$c3$c4$c5"
done
done
done
done
done
답변
이 bash 버전은 여전히 Perl보다 빠르지는 않지만 5 개의 중첩 루프보다 약 4 배 빠릅니다.
printf -vtwo "%s " {{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}
for three in {{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}{{a..z},{A..Z},{0..9}}; do
printf "$three%s\n" $two;
done
답변
사용할 수 있습니다 crunch
(최소한 Kali 배포판에서 사용 가능).
crunch 5 5 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
답변
글쎄 … 우아한?, 예 (빠른 샘플) :
eval echo $(printf "%s" '{{a..z},{A..Z},{0..9}}'{,,} )
이 완전한 표현은 대부분 컴퓨터를 차단합니다.
eval echo $(printf "%s" '{{a..z},{A..Z},{0..9}}'{,,,,} )
비 차단 옵션 중 하나는 여러 루프를 사용하는 것입니다.
nl=$'\n'; tab=$'\t'
n=${1:-3}
eval set -- "$2"
eval "varnames=($(echo {a..z}))"
for i in "${varnames[@]:0:$n}"; do
header+='for '"$i"' do '
middle+='$'"$i"
traile+="done; "
done
loop="${header}${nl} printf %s \"$middle\";${nl}$traile"
#echo "$loop"
eval "$loop"
다음과 같이 호출하십시오.
./script 3 '{a..z} {A..Z} {0..9}'
여기서 첫 번째 인수는 문자 수이고 두 번째 인수는 사용 된 문자 목록 (공백으로 구분)입니다.
그러면 loop
실행할 스크립트로 변수 ( )가 작성되고 마지막 평가자는 해당 스크립트를 실행합니다. 예를 들면 다음과 같습니다.
$ ./script 5 '{a..z} {A..Z} {0..9}'
의 가치 loop
는 다음과 같습니다.
for a do for b do for c do for d do for e do
echo "$a$b$c$d$e";
done; done; done; done; done;
답변
Gnu Parallel은 https://www.gnu.org/software/parallel/을 참조하여 조합을 수행 할 수 있습니다 .
parallel echo ::: {a..z} {A..Z} {0..9} ::: {a..z} {A..Z} {0..9} ::: {a..z} {A..Z} {0..9} ::: {a..z} {A..Z} {0..9} ::: {a..z} {A..Z} {0..9}