ruby-entropy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/ruby-entropy.rb +99 -0
  2. metadata +47 -0
@@ -0,0 +1,99 @@
1
+ class Password
2
+
3
+ attr_reader :password
4
+
5
+ #lowercase passwords only
6
+ COMMON_PASSWORDS = ["admin", "administrator", "jesus", "letmein", "master", "open sesame", "opensesame", "password", "sunshine", "trustnoi", "trustnol", "welcome"]
7
+ KEY_PATTERNS = ["zxc", "cxz", "bnm", "mnb", "jkl", "lkj", "asd", "dsa", "qwe", "ewq", "iop", "poi"]
8
+
9
+ def initialize(password)
10
+ @password = password
11
+ @passwords = []
12
+ end
13
+
14
+ def entropy
15
+ Math.log2(count ** length)
16
+ end
17
+
18
+ def strength
19
+ (31 * bad_password_multiplier * Math.log(entropy / 13.62)).round(2)
20
+ end
21
+
22
+ def length
23
+ @password.length
24
+ end
25
+
26
+ def letters
27
+ 26 if @password.match(/[a-z]|[A-Z]/)
28
+ end
29
+
30
+ def multiple_cases
31
+ 26 if @password.match(/[a-z]/) && @password.match(/[A-Z]/)
32
+ end
33
+
34
+ def digits
35
+ 10 if @password.match(/\d/)
36
+ end
37
+
38
+ def symbols
39
+ 33 if @password.match(/\W/)
40
+ end
41
+
42
+ def count
43
+ letters.to_i + multiple_cases.to_i + digits.to_i + symbols.to_i
44
+ end
45
+
46
+ def key_pattern?
47
+ KEY_PATTERNS.each { |pattern| return true if @password.downcase.include?(pattern) }
48
+ false
49
+ end
50
+
51
+ def numerical_pattern?
52
+ pattern = @password.split('').map(&:to_i)
53
+ pattern.each_with_index do |num, index|
54
+ return true if pattern[index + 1] == num + 1 && pattern[index + 2] == num + 2 && pattern[index + 3] == num + 3
55
+ return true if pattern[index + 1] == num - 1 && pattern[index + 2] == num - 2 && pattern[index + 3] == num - 3
56
+ end
57
+ false
58
+ end
59
+
60
+ def repetitious?
61
+ characters = @password.split('')
62
+ characters.each_with_index do |character, index|
63
+ return true if characters[index + 1] == character && characters[index + 2] == character
64
+ end
65
+ false
66
+ end
67
+
68
+ def common?
69
+ @passwords << @password
70
+ if @password.match(/[@0|1$5]/)
71
+ @passwords << @password.gsub('@', 'a').gsub('0', 'o').gsub(/[|1!]/, 'l').gsub(/[$5]/, 's')
72
+ @passwords << @password.gsub('@', 'a').gsub('0', 'o').gsub(/[|1!]/, 'i').gsub(/[$5]/, 's')
73
+ end
74
+ COMMON_PASSWORDS.each do |commoner|
75
+ @passwords.each { |password| return true if password.downcase.include?(commoner.downcase) }
76
+ end
77
+ false
78
+ end
79
+
80
+ def uniqueness
81
+ (@password.downcase.split('').uniq.length/length.to_f) < 0.4
82
+ end
83
+
84
+ def repeaters
85
+ mode = []
86
+ @password.downcase.split('').uniq.each do |character|
87
+ mode << @password.split('').count(character)
88
+ end
89
+ mode.max.downto(2) do |num|
90
+ return true if (mode.count(num)/mode.length.to_f) > 0.75
91
+ end
92
+ false
93
+ end
94
+
95
+ def bad_password_multiplier
96
+ repeaters || uniqueness ? (return 0.1) : 1
97
+ key_pattern? || numerical_pattern? || repetitious? || common? ? @password.length < 12 ? 0.5 : 0.75 : 1
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-entropy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brooks Mason
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-21 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Calculates password strength based on standard entropy definition. Strength
15
+ is reduced based on repeatability and common password test functions
16
+ email: brooksmason@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/ruby-entropy.rb
22
+ homepage: http://rubygems.org/gems/ruby-entropy
23
+ licenses: []
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 1.8.25
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: password strength algorithm
46
+ test_files: []
47
+ has_rdoc: