字符和数字的所有可能组合


13

因此,我想生成所有可能组成5个字符串的大小写字符和数字的所有可能组合。

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

在bash中是否有任何优雅的方法可以做到这一点?


1
您想限制自己使用ASCII还是拉丁脚本?带有重音符号(é,â...)的变音符号呢?
斯特凡Chazelas

感谢您的跟进。更新了原始帖子以进行澄清。
2015年

真的需要参加bash吗?像Perl或awk这样的语言会做吗?
terdon

1
那么为什么不从bash调用Perl或Python呢?特别是使用时perl,将其用作单线非常容易。
terdon

2
您是要学习还是只想要结果?在第二种情况下,有很多程序可以像john the ripper(john)之类的程序来工作,这将为您提供很多可能性。
YoMismo

Answers:


13

这是一个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

高级语言很容易被暴力破解(这基本上就是您正在做的事情)。


@StéphaneChazelas非常感谢您的编辑。我当时写的很脏,忽略了“适当的”引号,因为在这种情况下不需要它,但是我非常感谢这些快捷方式!
PSkocik 2015年

我尝试了您的bash解决方案。这是很不错的; 我很喜欢。在大约24小时左右的时间内,它运行良好,直到我发现我的系统已完全锁定。尝试与`python;类似;结果也差不多,尽管速度更快。
声音

8

在中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

(在我的系统上,其输出速度为700 kiB / s,而perl等效速度为20MiB / s )。


我还认为,如果您要添加一种将其输出到文件的方法,它将增加答案。也许是因为它正在生成,所以它不会破坏您的RAM,或者在将其全部缓存到ram之后
Hellreaver 2015年

2
@Hellreaver,它们都写入文件(到stdout,打开的任何文件;如果在终端中运行,则为设备文件,例如/dev/pts/something;您可以使用shell重定向操作符更改该文件),而不是内存,但是第一个文件会生成整个输出(输出到标准输出打开的文件)之前,先将其存储在内存中。
斯特凡Chazelas

4

这是一种纯粹用bash进行操作而不必占用5 GB内存的方法:

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

2

这个bash版本仍然不如Perl快,但大约是五个嵌套循环的四倍:

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

1

您可以使用crunch(至少在Kali发行版中可用)。

crunch 5 5 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890

1

好吧...优雅?,是的(只是一个简单的例子):

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;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.