Module: Zxcvbn::TimeEstimates

Defined in:
lib/zxcvbn/time_estimates.rb

Class Method Summary collapse

Class Method Details

.display_time(seconds) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/zxcvbn/time_estimates.rb', line 45

def self.display_time(seconds)
  minute = 60
  hour = minute * 60
  day = hour * 24
  month = day * 31
  year = month * 12
  century = year * 100
  display_num, display_str = if seconds < 1
    [nil, "less than a second"]
  elsif seconds < minute
    base = seconds.round
    [base, "#{base} second"]
  elsif seconds < hour
    base = (seconds / minute).round
    [base, "#{base} minute"]
  elsif seconds < day
    base = (seconds / hour).round
    [base, "#{base} hour"]
  elsif seconds < month
    base = (seconds / day).round
    [base, "#{base} day"]
  elsif seconds < year
    base = (seconds / month).round
    [base, "#{base} month"]
  elsif seconds < century
    base = (seconds / year).round
    [base, "#{base} year"]
  else
    [nil, "centuries"]
  end
  display_str += "s" if display_num && display_num != 1
  display_str
end

.estimate_attack_times(guesses) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/zxcvbn/time_estimates.rb', line 5

def self.estimate_attack_times(guesses)
  crack_times_seconds = {
    "online_throttling_100_per_hour" => guesses / (100.0 / 3600.0),
    "online_no_throttling_10_per_second" => guesses / 10.0,
    "offline_slow_hashing_1e4_per_second" => guesses / 1e4,
    "offline_fast_hashing_1e10_per_second" => guesses / 1e10
  }
  crack_times_display = {}
  crack_times_seconds.each do |scenario, seconds|
    crack_times_display[scenario] = display_time(seconds)
  end

  {
    "crack_times_seconds" => crack_times_seconds,
    "crack_times_display" => crack_times_display,
    "score" => guesses_to_score(guesses)
  }
end

.guesses_to_score(guesses) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/zxcvbn/time_estimates.rb', line 24

def self.guesses_to_score(guesses)
  delta = 5
  if guesses < 1e3 + delta
    # risky password: "too guessable"
    0
  elsif guesses < 1e6 + delta
    # modest protection from throttled online attacks: "very guessable"
    1
  elsif guesses < 1e8 + delta
    # modest protection from unthrottled online attacks: "somewhat guessable"
    2
  elsif guesses < 1e10 + delta
    # modest protection from offline attacks: "safely unguessable"
    # assuming a salted, slow hash function like bcrypt, scrypt, PBKDF2, argon, etc
    3
  else
    # strong protection from offline attacks under same scenario: "very unguessable"
    4
  end
end