UNPKG

zxcvbn3

Version:

realistic password strength estimation

90 lines 3.34 kB
export class TimeEstimates { static estimate_attack_times(guesses) { const crack_times_seconds = { online_throttling_100_per_hour: guesses / (100 / 3600), online_no_throttling_10_per_second: guesses / 10, offline_slow_hashing_1e4_per_second: guesses / 1e4, offline_fast_hashing_1e10_per_second: guesses / 1e10 }; const crack_times_display = {}; for (let scenario in crack_times_seconds) { const seconds = crack_times_seconds[scenario]; crack_times_display[scenario] = this.display_time(seconds); } return { crack_times_seconds, crack_times_display, score: this.guesses_to_score(guesses) }; } static guesses_to_score(guesses) { const DELTA = 5; if (guesses < (1e3 + DELTA)) { // risky password: "too guessable" return 0; } else if (guesses < (1e6 + DELTA)) { // modest protection from throttled online attacks: "very guessable" return 1; } else if (guesses < (1e8 + DELTA)) { // modest protection from unthrottled online attacks: "somewhat guessable" return 2; } else if (guesses < (1e10 + DELTA)) { // modest protection from offline attacks: "safely unguessable" // assuming a salted, slow hash function like bcrypt, scrypt, PBKDF2, argon, etc return 3; } else { // strong protection from offline attacks under same scenario: "very unguessable" return 4; } } static display_time(seconds) { const minute = 60; const hour = minute * 60; const day = hour * 24; const month = day * 31; const year = month * 12; const century = year * 100; let [display_num, display_str] = Array.from((() => { let base; if (seconds < 1) { return [null, 'less than a second']; } else if (seconds < minute) { base = Math.round(seconds); return [base, `${base} second`]; } else if (seconds < hour) { base = Math.round(seconds / minute); return [base, `${base} minute`]; } else if (seconds < day) { base = Math.round(seconds / hour); return [base, `${base} hour`]; } else if (seconds < month) { base = Math.round(seconds / day); return [base, `${base} day`]; } else if (seconds < year) { base = Math.round(seconds / month); return [base, `${base} month`]; } else if (seconds < century) { base = Math.round(seconds / year); return [base, `${base} year`]; } else { return [null, 'centuries']; } })()); if ((display_num != null) && (display_num !== 1)) { display_str += 's'; } return display_str; } } //# sourceMappingURL=time_estimates.js.map