Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recognizing "type" of hash keys

I'd like to use a "compiled regex" (I mean: an expression in the form qr/../) as a key for an hash structure.

To discern between constant strings and these regexes when iterating over the hash keyes, I was trying to use ref(), or is_regexp(), but the former returns a null string, and the latter doesn't work. I'm afraid I'm missing something fundamental about Perl refs vs. scalars.

Apart from that, my solution seems to work. Is it too ugly anyway? Any alternate proposal is welcome.

Some code to understand ref() function:

my $regex = qr/foo/;
printf "ref(\$regex): %s \n", ref($regex);
printf "is_regexp(\$regex): %d \n", is_regexp($regex);
# ref($regex): Regexp
# is_regexp($regex): 1

my $scalar = 3;
printf "ref(\$scalar): [%s] \n", ref($scalar);
# ref($scalar): []

my %my_hash = ('name', 'Becky', 'age', 23);
for my $k (keys %my_hash) {
    printf "%s [%s] -> %s [%s] \n", $k, ref($k), $my_hash{$k}, ref($my_hash{$k});
}
# name [] -> Becky []
# age [] -> 23 []
like image 736
AndreaG Avatar asked Mar 05 '12 11:03

AndreaG


People also ask

Can you decipher a hash?

First of all, unlike encryption, hashing is always one way. In fact, hashing is often called "one way encryption". So, while you can decrypt an encrypted text, you cannot "de-hash" a hashed text.

What type of hash is $1$?

$1$ is the prefix used to identify md5-crypt hashes, following the Modular Crypt Format. salt is 0-8 characters drawn from the regexp range [./0-9A-Za-z] ; providing a 48-bit salt ( 5pZSV9va in the example).

What tool can be used to determine what type of hash a particular hash value is?

About the Hash Analyzer The tool can look at the characters that make up the hash to possibly identify which type of hash it is and what it may be used for. Hash types this tool can positively identify: MD5. SHA1 (SHA128)

What is hash identifier?

Software to identify the different types of hashes used to encrypt data and especially passwords. Installed size: 49 KB.


2 Answers

As Qtax notes in the comments, Perl hash keys are always strings: if you use something other than a string as a hash key, it's first converted to a string.

In another comment you write:

"I read counter definitions from a config file; I want to be able to support some pattern syntax, for example: McDouglas, McDonald, /Mc[A-Za-z]*/. I then read counter values from text files, and I update relevant counterS accordingly: McDonald 23 McIntosh 11"

If I understand this right, one simple solution might be to to store the compiled regexps in another hash, keyed on their string representation:

my @patterns = (
    'McDouglas',
    'McDonald',
    'Mc[A-Za-z]*',
);

my %regexps = map +($_ => qr/^$_$/), @patterns;
my %counters;

while (<>) {
    while (my ($pat, $re) = each %regexps) {
        $counters{$pat}++  if /$re/;
    }
}

foreach my $pat (@patterns) {
    print "$pat: ", ($counters{$pat} || 0), "\n";
}
like image 63
Ilmari Karonen Avatar answered Oct 22 '22 12:10

Ilmari Karonen


Is there anything wrong with using Tie::RegexpHash? It saves you from having to reinvent the wheel :)

use Tie::RegexpHash;

my %hash;

tie %hash, 'Tie::RegexpHash';

$hash{ qr/^5(\s+|-)?gal(\.|lons?)?/i } = '5-GAL';

$hash{'5 gal'};     # returns "5-GAL"
$hash{'5GAL'};      # returns "5-GAL"
$hash{'5  gallon'}; # also returns "5-GAL"
like image 39
Zaid Avatar answered Oct 22 '22 13:10

Zaid