No need to use while loops, use backreferences in your pattern. In the following code I make arrays of references to substrings of 2, 4 & 8 characters without converting bytes to string representations. I then test by matching each dereferenced element against the pattern and print an error if I find repeats. I test a clean string first then introduce some repeats and test it again.
use strict;
use warnings;
use 5.014;
my $str = q{};
$str .= chr for 0 .. 31;
say qq{\n}, q{| . . . ^ . . . } x 4;
say unpack q{H*}, $str;
for my $len ( 8, 4, 2 )
{
say qq{\nChecking groups of $len};
my $quant = $len - 1;
my @groups =
map { \ substr $str, $_ * $len, $len }
0 .. ( length( $str ) / $len ) - 1;
for my $idx ( 0 .. $#groups )
{
say
qq{Found @{ [ unpack q{H*}, $1 ] } },
qq{at offset @{ [ $len * $idx ] }}
if ${ $groups[ $idx ] } =~ m{((.)\2{$quant})};
}
}
substr $str, 0, 2, qq{\x3e\x3e};
substr $str, 16, 8, qq{\xac} x 8;
substr $str, 4, 4, qq{\x7f} x 4;
substr $str, 26, 4, qq{\x45} x 4;
say qq{\n}, q{| . . . ^ . . . } x 4;
say unpack q{H*}, $str;
for my $len ( 8, 4, 2 )
{
say qq{\nChecking groups of $len};
my $quant = $len - 1;
my @groups =
map { \ substr $str, $_ * $len, $len }
0 .. ( length( $str ) / $len ) - 1;
for my $idx ( 0 .. $#groups )
{
say
qq{Found @{ [ unpack q{H*}, $1 ] } },
qq{at offset @{ [ $len * $idx ] }}
if ${ $groups[ $idx ] } =~ m{((.)\2{$quant})};
}
}
The output.
| . . . ^ . . . | . . . ^ . . . | . . . ^ . . . | . . . ^ . . .
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Checking groups of 8
Checking groups of 4
Checking groups of 2
| . . . ^ . . . | . . . ^ . . . | . . . ^ . . . | . . . ^ . . .
3e3e02037f7f7f7f08090a0b0c0d0e0facacacacacacacac1819454545451e1f
Checking groups of 8
Found acacacacacacacac at offset 16
Checking groups of 4
Found 7f7f7f7f at offset 4
Found acacacac at offset 16
Found acacacac at offset 20
Checking groups of 2
Found 3e3e at offset 0
Found 7f7f at offset 4
Found 7f7f at offset 6
Found acac at offset 16
Found acac at offset 18
Found acac at offset 20
Found acac at offset 22
Found 4545 at offset 26
Found 4545 at offset 28
I hope this helps you along.
|