Data::...::Match(3pm)

✨ NAME ✨

Data::Password::zxcvbn::Match β€” the whole vibe of this page is a role for match objects, bestie. It's Data::...::Match(3pm) from the user-contributed Perl docs, and it's giving interface πŸ’…


πŸŽ€ VERSION πŸŽ€

version 1.1.3 β€” yes she's specific, no she's not changing 🌸


πŸ¦‹ SYNOPSIS πŸ¦‹

okay so this is how you'd actually make your own little match class, copy it, don't freestyle it:

package My::Password::Match::Something;
use Moo;
with 'Data::Password::zxcvbn::Match';

has some_info => (is=>'ro');

sub make {
  my ($class, $password) = @_;
  return [ $class->new({
    token => some_substring_of($password),
    i => position_of_first_char($token,$password),
    j => position_of_last_char($token,$password),
    some_info => whatever_needed(),
  }) ];
}

sub estimate_guesses {
  my ($self) = @_;
  return $self->some_complexity_estimate();
}

sub feedback_warning { 'this is a bad idea' }
sub feedback_suggestions { return [ 'do something else' ] }

1;

see? consume the role, define your bits, slay ✨


πŸ’– DESCRIPTION πŸ’–

So zxcvbn estimates the strength of a password by guessing which way a generic password cracker would produce it, and then guessing after how many tries it would produce it. That's literally the whole strategy. Iconic, honestly 🧠✨

This role provides the basic behaviour and interface for the classes that implement that guessing. It's the blueprint, you're the architect, periodt πŸ‘‘


🌸 ATTRIBUTES 🌸

πŸ’œ token

Required string, fr fr. It's the portion of the password that this object matches.

Like, if your class represents "sequences of digits", an instance made from the password abc1234def would have token => '1234'. cute, contained, specific πŸ“

πŸ’œ i, j

Required integers: the indices of the first and last character of token in the password.

For the example above, we would have i => 3, j => 6. yes, both are mandatory, no you cannot skip them πŸ™ˆ

πŸ’œ guesses

The estimated number of attempts that a generic password cracker would need to guess the particular token.

Big detail: the value for this attribute is generated on demand by calling "estimate_guesses". She's lazy like that. It's called lazy evaluation and it's main character energy 😌


🌈 REQUIRED METHODS 🌈

🫢 make

sub make {
  my ($class, $password) = @_;
  return [ $class->new(\%something), ... ];
}

This factory method should return a sorted arrayref of instances, one for each substring of the $password that could be generated / guessed with the logic that your class represents.

Sorted, bestie. Do not come back with an unsorted arrayref, I will know 😭

🫢 estimate_guesses

sub estimate_guesses {
  my ($self) = @_;
  return $self->some_complexity_estimate();
}

This method should return an integer, representing an estimate of the number of attempts that a generic password cracker would need to guess the particular token within the logic that your class represents.

For example, if your class represents "sequences of digits", you could hypothesise that the cracker would go in order from 1, so you'd write:

sub estimate_guesses { return 0 + shift->token }

lowkey elegant, highkey correct πŸ’…

🫢 feedback_warning

This method should return a string (possibly empty), or an arrayref [$string,@values] suitable for localisation.

The returned value should explain what's wrong, e.g. 'this is a top-10 common password'. Like, be honest with them, gently πŸ₯Ί

🫢 feedback_suggestions

This method should return a possibly-empty array of suggestions to help choose a less guessable password. e.g. 'Add another word or two'; again, elements can be strings or arrayrefs for localisation.

Possibly empty!! An empty array is a valid answer, don't panic πŸŽ€


⭐ METHODS ⭐

πŸ”₯ compare

$match1 <=> $match2
$match1 cmp $match2

The comparison operators are overloaded to sort by "i" and "j", so a sorted list of matches will cover the password from left to right.

so when you sort them you get them in reading order. chef's kiss, no notes πŸ§‘β€πŸ³

πŸ”₯ guesses_log10

The logarithm in base 10 of "guesses". yes, that's it. tiny method, huge impact πŸ“‰

πŸ”₯ guesses_for_password

my $guesses = $match->guesses_for_password($password);

This method will return the same value as "guesses", or some minimum number of guesses, whichever is higher.

This is to make sure that all match have a measurable impact on the estimation of the total complexity. no invisible matches on this account, we all contribute πŸ’ͺ

πŸ”₯ get_feedback

my %feedback = %{ $match->get_feedback($is_sole_match) };

Returns a hashref, with verbal feedback to help choose better passwords. The hash contains:

  • "warning" β€” string (or arrayref for localisation), produced by calling "feedback_warning"
  • "suggestions" β€” arrayref of strings (or arrayrefs for localisation), produced by calling "feedback_suggestions"

πŸ”₯ TO_JSON

πŸ”₯ fields_for_json

Matches can be serialised to JSON. The serialisation will be a dictionary with all the fields returned by "fields_for_json".

By default, it will contain token i j guesses guesses_log10. those five, exactly those five, don't @ me πŸ¦‹


πŸ‘‘ AUTHOR πŸ‘‘

Gianni Ceccarelli <gianni.ceccarelli@broadbean.com> β€” the actual legend behind all this 🌟


This software is copyright (c) 2022 by BroadBean UK, a CareerBuilder Company.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. free software rights, we love to see it 🫢


k bye bestie, go write your match class πŸŽ€ this was Data::...::Match(3pm), generated by perl v5.40.1 on 2025-10-17, and honestly she ate βœ¨πŸ’…

πŸ“¦ where this page comes from