ruby-entropy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: