문자와 숫자의 가능한 모든 조합 자 문자열을 구성

그래서 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}