Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose Score enum #81

Merged
merged 7 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ web-sys = { version = "0.3", features = ["Performance"] }
[dependencies.serde]
optional = true
version = "1"

[dependencies.serde_derive]
optional = true
version = "1"
features = ["derive"]

[dev-dependencies]
quickcheck = "1.0.0"
Expand All @@ -47,7 +44,7 @@ wasm-bindgen-test = "0.3"

[features]
default = ["builder"]
ser = ["serde", "serde_derive"]
ser = ["serde"]
builder = ["derive_builder"]

[profile.test]
Expand Down
6 changes: 3 additions & 3 deletions src/feedback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::fmt;

/// A warning explains what's wrong with the password.
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
#[allow(missing_docs)]
pub enum Warning {
StraightRowsOfKeysAreEasyToGuess,
Expand Down Expand Up @@ -67,7 +67,7 @@ impl fmt::Display for Warning {

/// A suggestion helps to choose a better password.
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
#[allow(missing_docs)]
pub enum Suggestion {
UseAFewWordsAvoidCommonPhrases,
Expand Down Expand Up @@ -131,7 +131,7 @@ impl fmt::Display for Suggestion {

/// Verbal feedback to help choose better passwords
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct Feedback {
/// Explains what's wrong, e.g. "This is a top-10 common password". Not always set.
warning: Option<Warning>,
Expand Down
2 changes: 1 addition & 1 deletion src/frequency_lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const US_TV_AND_FILM: &str = "you,i,to,that,it,me,what,this,know,i'm,no,have,my,
const MALE_NAMES: &str = "james,john,robert,michael,william,david,richard,charles,joseph,thomas,christopher,daniel,paul,mark,donald,george,kenneth,steven,edward,brian,ronald,anthony,kevin,jason,matthew,gary,timothy,jose,larry,jeffrey,frank,scott,eric,stephen,andrew,raymond,gregory,joshua,jerry,dennis,walter,patrick,peter,harold,douglas,henry,carl,arthur,ryan,roger,joe,juan,jack,albert,jonathan,justin,terry,gerald,keith,samuel,willie,ralph,lawrence,nicholas,roy,benjamin,bruce,brandon,adam,harry,fred,wayne,billy,steve,louis,jeremy,aaron,randy,eugene,carlos,russell,bobby,victor,ernest,phillip,todd,jesse,craig,alan,shawn,clarence,sean,philip,chris,johnny,earl,jimmy,antonio,danny,bryan,tony,luis,mike,stanley,leonard,nathan,dale,manuel,rodney,curtis,norman,marvin,vincent,glenn,jeffery,travis,jeff,chad,jacob,melvin,alfred,kyle,francis,bradley,jesus,herbert,frederick,ray,joel,edwin,don,eddie,ricky,troy,randall,barry,bernard,mario,leroy,francisco,marcus,micheal,theodore,clifford,miguel,oscar,jay,jim,tom,calvin,alex,jon,ronnie,bill,lloyd,tommy,leon,derek,darrell,jerome,floyd,leo,alvin,tim,wesley,dean,greg,jorge,dustin,pedro,derrick,dan,zachary,corey,herman,maurice,vernon,roberto,clyde,glen,hector,shane,ricardo,sam,rick,lester,brent,ramon,tyler,gilbert,gene,marc,reginald,ruben,brett,nathaniel,rafael,edgar,milton,raul,ben,cecil,duane,andre,elmer,brad,gabriel,ron,roland,jared,adrian,karl,cory,claude,erik,darryl,neil,christian,javier,fernando,clinton,ted,mathew,tyrone,darren,lonnie,lance,cody,julio,kurt,allan,clayton,hugh,max,dwayne,dwight,armando,felix,jimmie,everett,ian,ken,bob,jaime,casey,alfredo,alberto,dave,ivan,johnnie,sidney,byron,julian,isaac,clifton,willard,daryl,virgil,andy,salvador,kirk,sergio,seth,kent,terrance,rene,eduardo,terrence,enrique,freddie,stuart,fredrick,arturo,alejandro,joey,nick,luther,wendell,jeremiah,evan,julius,donnie,otis,trevor,luke,homer,gerard,doug,kenny,hubert,angelo,shaun,lyle,matt,alfonso,orlando,rex,carlton,ernesto,pablo,lorenzo,omar,wilbur,blake,horace,roderick,kerry,abraham,rickey,ira,andres,cesar,johnathan,malcolm,rudolph,damon,kelvin,rudy,preston,alton,archie,marco,pete,randolph,garry,geoffrey,jonathon,felipe,bennie,gerardo,dominic,loren,delbert,colin,guillermo,earnest,benny,noel,rodolfo,myron,edmund,salvatore,cedric,lowell,gregg,sherman,devin,sylvester,roosevelt,israel,jermaine,forrest,wilbert,leland,simon,irving,owen,rufus,woodrow,sammy,kristopher,levi,marcos,gustavo,jake,lionel,marty,gilberto,clint,nicolas,laurence,ismael,orville,drew,ervin,dewey,wilfred,josh,hugo,ignacio,caleb,tomas,sheldon,erick,frankie,darrel,rogelio,terence,alonzo,elias,bert,elbert,ramiro,conrad,noah,grady,phil,cornelius,lamar,rolando,clay,percy,bradford,merle,darin,amos,terrell,moses,irvin,saul,roman,darnell,randal,tommie,timmy,darrin,brendan,toby,van,abel,dominick,emilio,elijah,cary,domingo,aubrey,emmett,marlon,emanuel,jerald,edmond,emil,dewayne,otto,teddy,reynaldo,bret,jess,trent,humberto,emmanuel,stephan,louie,vicente,lamont,garland,micah,efrain,heath,rodger,demetrius,ethan,eldon,rocky,pierre,eli,bryce,antoine,robbie,kendall,royce,sterling,grover,elton,cleveland,dylan,chuck,damian,reuben,stan,leonardo,russel,erwin,benito,hans,monte,blaine,ernie,curt,quentin,agustin,jamal,devon,adolfo,tyson,wilfredo,bart,jarrod,vance,denis,damien,joaquin,harlan,desmond,elliot,darwin,gregorio,kermit,roscoe,esteban,anton,solomon,norbert,elvin,nolan,carey,rod,quinton,hal,brain,rob,elwood,kendrick,darius,moises,marlin,fidel,thaddeus,cliff,marcel,ali,raphael,bryon,armand,alvaro,jeffry,dane,joesph,thurman,ned,sammie,rusty,michel,monty,rory,fabian,reggie,kris,isaiah,gus,avery,loyd,diego,adolph,millard,rocco,gonzalo,derick,rodrigo,gerry,rigoberto,alphonso,rickie,noe,vern,elvis,bernardo,mauricio,hiram,donovan,basil,nickolas,scot,vince,quincy,eddy,sebastian,federico,ulysses,heriberto,donnell,denny,gavin,emery,romeo,jayson,dion,dante,clement,coy,odell,jarvis,bruno,issac,dudley,sanford,colby,carmelo,nestor,hollis,stefan,donny,linwood,beau,weldon,galen,isidro,truman,delmar,johnathon,silas,frederic,irwin,merrill,charley,marcelino,carlo,trenton,kurtis,aurelio,winfred,vito,collin,denver,leonel,emory,pasquale,mohammad,mariano,danial,landon,dirk,branden,adan,numbers,clair,buford,bernie,wilmer,emerson,zachery,jacques,errol,josue,edwardo,wilford,theron,raymundo,daren,tristan,robby,lincoln,jame,genaro,octavio,cornell,hung,arron,antony,herschel,alva,giovanni,garth,cyrus,cyril,ronny,stevie,lon,kennith,carmine,augustine,erich,chadwick,wilburn,russ,myles,jonas,mitchel,mervin,zane,jamel,lazaro,alphonse,randell,johnie,jarrett,ariel,abdul,dusty,luciano,seymour,scottie,eugenio,mohammed,arnulfo,lucien,ferdinand,thad,ezra,aldo,rubin,mitch,earle,abe,marquis,lanny,kareem,jamar,boris,isiah,emile,elmo,aron,leopoldo,everette,josef,eloy,dorian,rodrick,reinaldo,lucio,jerrod,weston,hershel,lemuel,lavern,burt,jules,gil,eliseo,ahmad,nigel,efren,antwan,alden,margarito,refugio,dino,osvaldo,les,deandre,normand,kieth,ivory,trey,norberto,napoleon,jerold,fritz,rosendo,milford,sang,deon,christoper,alfonzo,lyman,josiah,brant,wilton,rico,jamaal,dewitt,brenton,yong,olin,faustino,claudio,judson,gino,edgardo,alec,jarred,donn,trinidad,tad,porfirio,odis,lenard,chauncey,tod,mel,marcelo,kory,augustus,keven,hilario,bud,sal,orval,mauro,dannie,zachariah,olen,anibal,milo,jed,thanh,amado,lenny,tory,richie,horacio,brice,mohamed,delmer,dario,mac,jonah,jerrold,robt,hank,sung,rupert,rolland,kenton,damion,chi,antone,waldo,fredric,bradly,kip,burl,tyree,jefferey,ahmed,willy,stanford,oren,moshe,mikel,enoch,brendon,quintin,jamison,florencio,darrick,tobias,minh,hassan,giuseppe,demarcus,cletus,tyrell,lyndon,keenan,werner,theo,geraldo,columbus,chet,bertram,markus,huey,hilton,dwain,donte,tyron,omer,isaias,hipolito,fermin,chung,adalberto,jamey,teodoro,mckinley,maximo,raleigh,lawerence,abram,rashad,emmitt,daron,chong,samual,otha,miquel,eusebio,dong,domenic,darron,wilber,renato,hoyt,haywood,ezekiel,chas,florentino,elroy,clemente,arden,neville,edison,deshawn,carrol,shayne,nathanial,jordon,danilo,claud,sherwood,raymon,rayford,cristobal,ambrose,titus,hyman,felton,ezequiel,erasmo,lonny,milan,lino,jarod,herb,andreas,rhett,jude,douglass,cordell,oswaldo,ellsworth,virgilio,toney,nathanael,benedict,mose,hong,isreal,garret,fausto,arlen,zack,modesto,francesco,manual,gaylord,gaston,filiberto,deangelo,michale,granville,malik,zackary,tuan,nicky,cristopher,antione,malcom,korey,jospeh,colton,waylon,hosea,shad,santo,rudolf,rolf,renaldo,marcellus,lucius,kristofer,harland,arnoldo,rueben,leandro,kraig,jerrell,jeromy,hobert,cedrick,arlie,winford,wally,luigi,keneth,jacinto,graig,franklyn,edmundo,leif,jeramy,willian,vincenzo,shon,michal,lynwood,jere,elden,darell,broderick,alonso";

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub enum DictionaryType {
#[default]
Passwords,
Expand Down
9 changes: 2 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,13 @@ extern crate derive_builder;
#[macro_use]
extern crate lazy_static;

#[cfg(feature = "ser")]
extern crate serde;
#[cfg(feature = "ser")]
#[macro_use]
extern crate serde_derive;
use std::time::Duration;

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

use scoring::Score;
pub use scoring::Score;
use time_estimates::CrackTimes;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::wasm_bindgen;
Expand Down Expand Up @@ -68,7 +63,7 @@ where

/// Contains the results of an entropy calculation
#[derive(Debug, Clone)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct Entropy {
/// Estimated guesses needed to crack the password
guesses: u64,
Expand Down
2 changes: 1 addition & 1 deletion src/matching/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct Match {
/// Beginning of the match.
pub i: usize,
Expand Down Expand Up @@ -990,7 +990,7 @@
} else {
panic!("Wrong match pattern")
};
assert_eq!(p.reversed, true);

Check warning on line 993 in src/matching/mod.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

used `assert_eq!` with a literal bool
}
}

Expand Down Expand Up @@ -1063,7 +1063,7 @@
} else {
panic!("Wrong match pattern")
};
assert_eq!(p.l33t, true);

Check warning on line 1066 in src/matching/mod.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

used `assert_eq!` with a literal bool
}
}

Expand All @@ -1082,7 +1082,7 @@
} else {
panic!("Wrong match pattern")
};
assert_eq!(p.l33t, true);

Check warning on line 1085 in src/matching/mod.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

used `assert_eq!` with a literal bool
}
}

Expand Down Expand Up @@ -1208,7 +1208,7 @@
panic!("Wrong match pattern")
};
assert_eq!(p.sequence_name, "lower");
assert_eq!(p.ascending, false);

Check warning on line 1211 in src/matching/mod.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

used `assert_eq!` with a literal bool
}

#[test]
Expand Down
14 changes: 7 additions & 7 deletions src/matching/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::HashMap;

/// Pattern type used to detect a match
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
#[cfg_attr(feature = "ser", serde(tag = "pattern"))]
#[cfg_attr(feature = "ser", serde(rename_all = "lowercase"))]
pub enum MatchPattern {
Expand Down Expand Up @@ -44,7 +44,7 @@ impl MatchPattern {
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct DictionaryPattern {
/// Word that has been found in a dictionary.
pub matched_word: String,
Expand Down Expand Up @@ -72,7 +72,7 @@ pub struct DictionaryPattern {
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct SpatialPattern {
/// Name of the graph for which a spatial match has been found.
pub graph: String,
Expand All @@ -86,7 +86,7 @@ pub struct SpatialPattern {
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct RepeatPattern {
/// Base token that repeats in the matched pattern.
pub base_token: String,
Expand All @@ -102,7 +102,7 @@ pub struct RepeatPattern {
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct SequencePattern {
/// Name of the sequence that was matched.
pub sequence_name: &'static str,
Expand All @@ -116,7 +116,7 @@ pub struct SequencePattern {
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct RegexPattern {
/// Name of the regular expression that was matched.
pub regex_name: &'static str,
Expand All @@ -128,7 +128,7 @@ pub struct RegexPattern {
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "builder", derive(Builder))]
#[cfg_attr(feature = "builder", builder(default))]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct DatePattern {
/// Separator of a date that was matched.
pub separator: String,
Expand Down
30 changes: 20 additions & 10 deletions src/scoring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
use std::collections::HashMap;
use std::{cmp, fmt::Display};

/// Score generated when measuring the entropy of a password.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[non_exhaustive]
#[cfg_attr(feature = "ser", derive(serde::Serialize, serde::Deserialize))]
pub enum Score {
/// Can be cracked with 10^3 guesses or less.
Zero = 0,
Expand All @@ -18,22 +20,30 @@
Four,
}

impl From<Score> for i8 {
fn from(score: Score) -> i8 {
score as i8
impl From<Score> for u8 {
fn from(score: Score) -> u8 {
score as u8
}
}

impl Display for Score {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", i8::from(*self))
impl TryFrom<u8> for Score {
type Error = &'static str;

fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(match value {
0 => Self::Zero,
1 => Self::One,
2 => Self::Two,
3 => Self::Three,
4 => Self::Four,
_ => return Err("zxcvbn entropy score must be in the range 0-4"),
})
}
}

#[cfg(feature = "ser")]
impl serde::Serialize for Score {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
i8::from(*self).serialize(serializer)
impl Display for Score {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", u8::from(*self))
}
}

Expand Down Expand Up @@ -533,7 +543,7 @@

quickcheck! {
fn test_n_ck_mul_overflow(n: usize, k: usize) -> TestResult {
if n >= 63 && n <= 100 {

Check warning on line 546 in src/scoring.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

manual `RangeInclusive::contains` implementation
scoring::n_ck(n, k); // Must not panic
TestResult::from_bool(true)
} else {
Expand Down Expand Up @@ -826,7 +836,7 @@
};
assert_eq!(
p.estimate(token),
(*scoring::REFERENCE_YEAR - 1972).abs() as u64

Check warning on line 839 in src/scoring.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

casting the result of `i32::abs()` to u64
);
}

Expand Down Expand Up @@ -861,7 +871,7 @@
let token = "1123";
assert_eq!(
p.estimate(token),
365 * (*scoring::REFERENCE_YEAR - p.year).abs() as u64

Check warning on line 874 in src/scoring.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

casting the result of `i32::abs()` to u64
);
}

Expand Down Expand Up @@ -889,7 +899,7 @@
let base_guesses = *scoring::KEYBOARD_STARTING_POSITIONS
* *scoring::KEYBOARD_AVERAGE_DEGREE
* (token.len() - 1) as u64;
assert_eq!(p.estimate(token), base_guesses as u64);

Check warning on line 902 in src/scoring.rs

View workflow job for this annotation

GitHub Actions / clippy-rustfmt

casting to the same type is unnecessary (`u64` -> `u64`)
}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions src/time_estimates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::scoring::Score;

/// Back-of-the-envelope crack time estimations, in seconds, based on a few scenarios.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
pub struct CrackTimes {
guesses: u64,
}
Expand Down Expand Up @@ -74,7 +74,7 @@ impl CrackTimes {

/// Represents the time to crack a password.
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "ser", derive(Serialize))]
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
#[cfg_attr(feature = "ser", serde(untagged))]
pub enum CrackTimeSeconds {
/// The number of seconds needed to crack a password, expressed as an integer.
Expand Down
Loading