# A draft of program to convert rexgen rule into John the Ripper rules use strict; use warnings; my $rule = "\\0([123]|[oO]ne|[tT](wo|hree))"; # $rule = "\\0(1|[oO]no|ONE)(2|[tT]wo|TWO)(3|[tT]hree|THREE)"; # $rule = "\\0(1|[oO]no\\0|ONE)(2|[tT]wo|TWO)(3|[tT]hree|THREE\\0)"; # $rule = "(A|B)(1|2)"; # $rule = "asdf\\0qwer"; # TODO: \0 is evaluated as from input. Bad. # $rule = "b(\\|a)(0|1)e"; sub to_tokens { # TODO: Handle \ and things in [] . $_[0] =~ /([(|)]|[^(|)]+)/g } # Usage: mul(["a", "b"], ["1", "2"]) -> qw/a1 a2 b1 b2/ # The first list could be empty, the second list could not be empty. sub combine { # warn "combine 0: @{$_[0]}\n"; # warn "combine 1: @{$_[1]}\n"; my @a = @{shift()}; my @b = @{shift()}; if (@a) { map { my $a = $_; map { $a . $_ } @b; } @a } else { @b } } # Rename combine into combine_i to use this # sub combine { # my @r = combine_i @_; # warn "combine r: @r\n"; # @r # } sub parse_part; sub parse_group { # warn "parse_group: @{$_[0]}\n"; my @all; my @current_branch; while (@{$_[0]} && $_[0][0] ne ')') { while (@{$_[0]} && $_[0][0] ne '|' && $_[0][0] ne ')') { my @p = parse_part($_[0]); @current_branch = combine [@current_branch], [@p]; } if (@{$_[0]} && $_[0][0] eq '|') { shift @{$_[0]}; } push @all, @current_branch; @current_branch = (); } shift @{$_[0]}; @all } sub parse_part { # warn "parse_part: @{$_[0]}\n"; die unless @_; my $p = shift @{$_[0]}; $p eq '(' ? parse_group($_[0]) : $p } sub expand_braces { my @a; while (@_) { my @b = parse_part \@_; # warn "top\n"; @a = combine [@a], [@b]; } @a } # Expand \0 sub expand_0 { map { my @l = split /\\0/; if (/\\0$/) { push @l, ""; } my $f = shift @l; # TODO: Don't screw current memorized value. local $_ = qq/M A0"$f" /; $_ .= join " X0zz ", map { 'Az"' . $_ . '"' } @l; s/^M A0"" /M /; s/ Az""$//; # Don't use M if there is only one \0. s/^M // if $#l < 1; $_ } @_ } print "$_\n" for expand_0 expand_braces to_tokens $rule;