This seems to accurately verify version 0 and version 1 stamps, and return proper timestamps and resource values (so long as the resource doesn't contain escaped colons - I don't remember whether that's allowed or not). It perhaps ought to return 0 for bits, and null strings for timestamp/resource values, for those that don't exist or are invalid. diff -dur Digest-Hashcash-0.03-o/Hashcash.pm Digest-Hashcash-0.03/Hashcash.pm --- Digest-Hashcash-0.03-o/Hashcash.pm 2005-03-03 17:24:10.000000000 +0000 +++ Digest-Hashcash-0.03/Hashcash.pm 2005-06-03 14:19:49.318948480 +0000 @@ -29,7 +29,7 @@ no warnings; -$VERSION = 0.03; +$VERSION = 0.031; XSLoader::load Digest::Hashcash, $VERSION; @@ -110,12 +110,11 @@ Any additional parameters are interpreted the same way as arguments to C<new>. -=item $prefix = $cipher->verify ($token [, param => value...])) +=item $prefix = $cipher->verify ($token) -Checks the given token and returns true if the token has the minimum -number of prefix bits, or false otherwise. The value returned is actually -the number of collisions, so to find the number of collisions bits specify -C<< collisions => 0 >>. +Version 0: Checks the given token and returns the number of collision bits +Version 1: Returns 0 if stated value is more than the computed collision value, + otherwise returns the stated stamp value. Any additional parameters are interpreted the same way as arguments to C<new>. @@ -148,32 +147,45 @@ sub verify { my ($self, $token) = (shift, shift); - my %arg = (%$self, @_); my $prefix = &_prefixlen($token); - $prefix < $arg{size} - ? undef - : $prefix; + if ($token =~ /^0:/) { + ($ver, $ts, $res, $rand) = split(':', $token, 4); + return $prefix >= 0 ? $prefix : 0; + } elsif ($token =~ /^1:/) { + ($ver, $bits, $ts, $res, $junk) = split(':', $token, 5); + return $prefix >= $bits ? $bits : 0; + } + else { return undef; } } sub resource { my ($self, $token) = @_; - $token =~ /^\d+:\d*:(.*):/ - or return undef; - - return $1; + if ($token =~ /^0:/) { + ($ver, $ts, $res, $rand) = split(':', $token, 4); + } + elsif ($token =~ /^1:/) { + ($ver, $bits, $ts, $res, $junk) = split(':', $token, 5); + } + else { return undef; } + return $res; } sub timestamp { my ($self, $token) = @_; - $token =~ /^\d+:(\d*):.*:/ - or return undef; + if ($token =~ /^0:/) { + ($ver, $ts, $res, $rand) = split(':', $token, 4); + } + elsif ($token =~ /^1:/) { + ($ver, $bits, $ts, $res, $junk) = split(':', $token, 5); + } + else { return undef; } my ($y, $m, $d, $H, $M, $S); - local $_ = $1; + local $_ = $ts; $y = /\G(\d\d)/gc ? $1 : return undef; $m = /\G(\d\d)/gc ? $1 : 1; $d = /\G(\d\d)/gc ? $1 : 1;