文字と数字のすべての可能な組み合わせ

文字と数字のすべての可能な組み合わせ

それで、小文字、大文字、数字のすべての可能な組み合わせを生成して5つの文字列を作成したいと思います。

可能性:a..z、A..Z、0..9。

Bashでこれを行うエレガントな方法はありますか?

答え1

以下は、必要な長さをパラメータとして使用する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>

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

高級言語は、無差別代入(基本的に実行する作業)に対して非常に脆弱です。

答え2

では、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

(マイシステムの出力速度は700kiB / sですが、同等のシステムの出力速度は20MiB / sですperl。)

答え3

crunch(少なくともKaliディストリビューションでは)使用できます。

crunch 5 5 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890

答え4

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}

関連情報