Module: Zxcvbn::CrackTime Private

Included in:
Scorer
Defined in:
lib/zxcvbn/crack_time.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Mixin that converts a guess count into estimated crack times and scores.

Provides #estimate_attack_times, #guesses_to_score, and #display_time mirroring the crack-time logic from zxcvbn.js v4.

Constant Summary collapse

ATTACK_SCENARIOS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

{
  'online_throttling_100_per_hour' => 100.0 / 3600,
  'online_no_throttling_10_per_second' => 10.0,
  'offline_slow_hashing_1e4_per_second' => 1e4,
  'offline_fast_hashing_1e10_per_second' => 1e10
}.freeze

Instance Method Summary collapse

Instance Method Details

#display_time(seconds) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert a number of seconds into a human-readable display string.

Parameters:

  • seconds (Numeric)

    duration in seconds

Returns:

  • (String)

    e.g. “instant”, “3 minutes”, “centuries”



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/zxcvbn/crack_time.rb', line 54

def display_time(seconds)
  minute  = 60
  hour    = minute * 60
  day     = hour * 24
  month   = day * 31
  year    = month * 12
  century = year * 100

  if seconds < 1
    'less than a second'
  elsif seconds < minute
    t = seconds.round
    "#{t} second#{'s' unless t == 1}"
  elsif seconds < hour
    t = (seconds / minute).round
    "#{t} minute#{'s' unless t == 1}"
  elsif seconds < day
    t = (seconds / hour).round
    "#{t} hour#{'s' unless t == 1}"
  elsif seconds < month
    t = (seconds / day).round
    "#{t} day#{'s' unless t == 1}"
  elsif seconds < year
    t = (seconds / month).round
    "#{t} month#{'s' unless t == 1}"
  elsif seconds < century
    t = (seconds / year).round
    "#{t} year#{'s' unless t == 1}"
  else
    'centuries'
  end
end

#estimate_attack_times(guesses) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the estimated seconds and display strings for each attack scenario.

Parameters:

  • guesses (Numeric)

    estimated guess count

Returns:

  • (Hash)

    with :crack_times_seconds and :crack_times_display



21
22
23
24
25
# File 'lib/zxcvbn/crack_time.rb', line 21

def estimate_attack_times(guesses)
  seconds = ATTACK_SCENARIOS.transform_values { |rate| [guesses / rate, Float::MAX].min }
  display = seconds.transform_values { |s| display_time(s) }
  { crack_times_seconds: seconds, crack_times_display: display }
end

#guesses_to_score(guesses) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert a guess count to a 0–4 score using zxcvbn.js v4 thresholds.

A small delta (5) is added to each threshold so that passwords just at a boundary are not bumped up to the next score band by floating-point noise in the guess count.

Parameters:

  • guesses (Numeric)

    estimated number of guesses to crack the password

Returns:

  • (Integer)

    score in the range 0..4



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/zxcvbn/crack_time.rb', line 35

def guesses_to_score(guesses)
  delta = 5
  if guesses < 1_000 + delta
    0
  elsif guesses < 1_000_000 + delta
    1
  elsif guesses < 100_000_000 + delta
    2
  elsif guesses < 10_000_000_000 + delta
    3
  else
    4
  end
end