recursive bruteforce ASCII range

Discussion in 'Perl Misc' started by bernd, Nov 26, 2004.

  1. bernd

    bernd Guest

    #!/usr/bin/perl -w
    #
    # hy group
    #
    # i feel really stupid. could it be that hard?
    #
    # i try to write a script to bruteforce the ASCII range. something
    # like:
    #
    # a..z
    # aa..zz
    # aaa..zzz
    # ...
    #
    # but there must be a smarter, solution than writing the same stuff
    # over and over again. i'd tried some recursive stuff but failed.
    #
    # any help really appreciated!
    #
    # greez bernd (who just didn't see the solution)

    use strict;

    # one character
    foreach my $a ('a'..'z','0'..'9') {
    print "$a\n";
    }

    # two character
    foreach my $a ('a'..'z','0'..'9') {
    foreach my $b ('a'..'z','0'..'9') {
    print "$a$b\n";
    }
    }

    # tree character
    foreach my $a ('a'..'z','0'..'9') {
    foreach my $b ('a'..'z','0'..'9') {
    foreach my $c ('a'..'z','0'..'9') {
    print "$a$b$c\n";
    }
    }
    }

    # n character ???
    bernd, Nov 26, 2004
    #1
    1. Advertising

  2. Also sprach bernd:

    > #!/usr/bin/perl -w
    > #
    > # hy group
    > #
    > # i feel really stupid. could it be that hard?
    > #
    > # i try to write a script to bruteforce the ASCII range. something
    > # like:
    > #
    > # a..z
    > # aa..zz
    > # aaa..zzz
    > # ...
    > #
    > # but there must be a smarter, solution than writing the same stuff
    > # over and over again. i'd tried some recursive stuff but failed.


    No need for recursion. Perl can do it for you.

    > # any help really appreciated!
    > #
    > # greez bernd (who just didn't see the solution)
    >
    > use strict;
    >
    > # one character
    > foreach my $a ('a'..'z','0'..'9') {
    > print "$a\n";
    > }


    print join "\n", 'a'..'z', '0'..'9';

    > # two character
    > foreach my $a ('a'..'z','0'..'9') {
    > foreach my $b ('a'..'z','0'..'9') {
    > print "$a$b\n";
    > }
    > }


    The values '0a' to '9z' are a bit annoying as one can't rely on Perl's
    string auto-increment.

    print join "\n", 'aa'..'zz',
    'a0'..'a9';
    map { my $a = $_; map { "$a$_" } 'a'..'z' } '0'..'9';
    '00'..'99';

    > # tree character
    > foreach my $a ('a'..'z','0'..'9') {
    > foreach my $b ('a'..'z','0'..'9') {
    > foreach my $c ('a'..'z','0'..'9') {
    > print "$a$b$c\n";
    > }
    > }
    > }


    Naturally, it gets longer and more annoying for three letter ranges.

    > # n character ???


    You don't really need recursion. What you need is a function that
    generates the next string item, so something that turns 'zz' into 'z0',
    '99' into 'aaa' etc. So a program could look thusly:

    sub next_item {
    my ($i, $tail) = shift;

    if (substr($i, -1, 1) eq 'z') {
    substr($i, -1, 1, '0');
    return $i;
    }
    if ($i =~ /^9+$/) {
    return 'a' x (length($i)+1);
    }
    if (substr($i, -1, 1) eq '9') {
    chop($i);
    $i = next_item($i) . 'a';
    return "$i";
    }
    if ($i =~ /\d.*[a-z]/) {
    substr($i, -1, 1)++;
    return $i;
    }
    return ++$i;
    }

    my $item = "a";
    while ($item ne '999') {
    print $item, "\n";
    $item = next_item($item);
    }

    next_item() is slightly recursive, though. The recursion is used for the
    case that an item ends on '9' in which case you get a carrier that
    ripples from right to left until a character other than '9' is found.

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Nov 26, 2004
    #2
    1. Advertising

  3. bernd wrote on 26 ÐоÑбрь 2004 16:50:

    > #!/usr/bin/perl -w
    > #
    > # hy group
    > #
    > # i feel really stupid. could it be that hard?
    > #
    > # i try to write a script to bruteforce the ASCII range. something
    > # like:
    > #
    > # a..z
    > # aa..zz
    > # aaa..zzz
    > # ...
    > #
    > # but there must be a smarter, solution than writing the same stuff
    > # over and over again. i'd tried some recursive stuff but failed.
    > #
    > # any help really appreciated!
    > #
    > # greez bernd (who just didn't see the solution)
    >
    > use strict;
    >
    > # one character
    > foreach my $a ('a'..'z','0'..'9') {
    > print "$a\n";
    > }
    >
    > # two character
    > foreach my $a ('a'..'z','0'..'9') {
    > foreach my $b ('a'..'z','0'..'9') {
    > print "$a$b\n";
    > }
    > }
    >
    > # tree character
    > foreach my $a ('a'..'z','0'..'9') {
    > foreach my $b ('a'..'z','0'..'9') {
    > foreach my $c ('a'..'z','0'..'9') {
    > print "$a$b$c\n";
    > }
    > }
    > }
    >
    > # n character ???


    You may try to play with Algorithm::GenerateSequence.

    use Algorithm::GenerateSequence;

    my $len = 3; #sequence length
    my $gen = Algorithm::GenerateSequence->new(
    map {['a' .. 'z', 0 .. 9]} (0 .. $len)
    );

    local $" = "";
    while(my @c = $gen->next) {
    print "@c\n";
    }

    --
    Andrew
    Andrew Tkachenko, Nov 26, 2004
    #3
  4. bernd

    Bill Smith Guest

    "bernd" <> wrote in message
    news:...
    > #!/usr/bin/perl -w
    > #
    > # hy group
    > #
    > # i feel really stupid. could it be that hard?
    > #
    > # i try to write a script to bruteforce the ASCII range. something
    > # like:
    > #
    > # a..z
    > # aa..zz
    > # aaa..zzz
    > # ...
    > #


    This specification omits many details, the most important of which is
    the order of the strings within each group.



    > # but there must be a smarter, solution than writing the same stuff
    > # over and over again. i'd tried some recursive stuff but failed.
    > #


    As I have said in other threads, recursive solutions are probably never
    "necessary" and seldom if ever efficient. Recursion can often be used
    to compactly specify a function which would be awkward otherwise. A
    perl implementation of such a spec can be almost indistinguishable from
    the spec. This is certainly an advantage in program validation.

    OK, I'll be honest. I never actually wrote the formal spec for this
    one. Here is my recursive solution.

    $ARGV[0] = 3 unless defined @ARGV;
    my $N = $ARGV[0]-1;

    my @SET = ('a'..'z', 0..9);

    recurse(''); # Run the recursion



    sub recurse{

    my $prefix = $_[0];
    if (length $prefix < $N){
    recurse($prefix.$_) foreach @SET;
    } else{
    print $prefix.$_."\n" foreach @SET;
    }

    }

    Note that the global "variable" names $N and @SET are in upper case to
    emphasize that they are logically constant. The command line argument
    (default 3) is the OP's "n". My $N is one less.


    Bill
    Bill Smith, Nov 27, 2004
    #4
  5. On 26 Nov 2004 08:50:27 -0800, (bernd) wrote:

    ># but there must be a smarter, solution than writing the same stuff
    ># over and over again. i'd tried some recursive stuff but failed.
    >#
    ># any help really appreciated!
    >#
    ># greez bernd (who just didn't see the solution)


    recursive, general purpose, certainly not terribly efficient!

    sub range;
    sub range {
    my $n=shift;
    return '' if $n == 0;
    map { my $c=$_;
    map $c.$_, range $n-1, @_ } @_;
    }

    print for range 3, 'a'..'z';


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Nov 27, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TOXiC
    Replies:
    5
    Views:
    1,249
    TOXiC
    Jan 31, 2007
  2. n00m
    Replies:
    12
    Views:
    1,112
  3. vamsi
    Replies:
    21
    Views:
    2,072
    Keith Thompson
    Mar 9, 2009
  4. James O'Brien
    Replies:
    3
    Views:
    250
    Ben Morrow
    Mar 5, 2004
  5. Alextophi
    Replies:
    8
    Views:
    508
    Alan J. Flavell
    Dec 30, 2005
Loading...

Share This Page