phoenix_password 0.2.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62fc2d5162961619812bc5c72b25b055c27c5540
4
- data.tar.gz: 68c1882f3687bdfe8163cedcbccfec2a0afe27ef
3
+ metadata.gz: 2d4eac9a6ff94dc2cc0f4b165c051afdcfb63e75
4
+ data.tar.gz: 53c8b1891a2847b09068067a7e6092a9545062bb
5
5
  SHA512:
6
- metadata.gz: '0588f9c5423c5b85cac84ee81621c93e5812f9641b7ea801f1473ed014eb3d4060a071fa30bb63e5df431c59668846e7a722d70919c5d47e2adfc0f71e1cea6e'
7
- data.tar.gz: 4ccba59a3c45a9a8cd79dc58d1b9243b1bfafab37b39d1f3d2116987497180a0867dd86ba3a0fdcf2d29d1274a3a8b688cba13fa0c96847807a48095e8fb9be2
6
+ metadata.gz: db1bfaec1ef9a45cf271b078d977e5d8dbc2b9c0bded7fe24cb07742a1dc83b6e385905c8e304ebf745072f4168a6298cf07bf932e9c1b4c436c7beb489010b2
7
+ data.tar.gz: 3b04f52dacf88299c4ae586ea8fc50d9a7f3d74fa1284c67545a7569aa81a57c37cbbc5e4e47d84887d0acf0f9a230c4f82f96e6883cac826750919cbcb968c3
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phoenix_password
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Spiros Avlonitis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-11 00:00:00.000000000 Z
11
+ date: 2017-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,16 +60,7 @@ email:
60
60
  executables: []
61
61
  extensions: []
62
62
  extra_rdoc_files: []
63
- files:
64
- - ".gitignore"
65
- - ".rspec"
66
- - CODE_OF_CONDUCT.md
67
- - Gemfile
68
- - LICENSE.txt
69
- - README.md
70
- - Rakefile
71
- - lib/phoenix_password.rb
72
- - lib/phoenix_password/version.rb
63
+ files: []
73
64
  homepage: https://github.com/spirosavlonitis/phoenix_password
74
65
  licenses:
75
66
  - MIT
@@ -90,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
81
  version: '0'
91
82
  requirements: []
92
83
  rubyforge_project:
93
- rubygems_version: 2.6.11
84
+ rubygems_version: 2.6.12
94
85
  signing_key:
95
86
  specification_version: 4
96
87
  summary: PhoenixPassword is an all purpose password genrator.
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- /*.gem
11
-
12
- /.travis.yml
13
- /bin
14
- /*.gemspec
15
-
16
- # rspec failure tracking
17
- .rspec_status
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at spirosa84@hotmail.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in phoenix_password.gemspec
4
- gemspec
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2017 Spiros Avlonitis
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/README.md DELETED
@@ -1,127 +0,0 @@
1
- # PhoenixPassword
2
-
3
- The PhoenixPassword generator gem is intended to be used
4
- in password recovery operations or random password generation
5
- purposes.
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'phoenix_password'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install phoenix_password
22
-
23
- ## Usage
24
- In order to generate combinations simply add the minimum of the required options
25
- here is an irb example:
26
-
27
- ```ruby
28
- irb(main):001:0> require 'phoenix_password'
29
- => true
30
- irb(main):002:0> PhoenixPassword.combinations({:piped=>true,:characters=>[0,1,2,3,4,5,6,7,8,9],:cmb_length=>[6],:type=>'matching'})
31
- ```
32
- 001273
33
-
34
- 001274
35
-
36
- 001275
37
-
38
- .....
39
-
40
- ## Manual
41
- This is a list of the options available to you and what they do
42
-
43
- ```ruby
44
- :piped=>(true or false)
45
- ```
46
- Lets you decide whether you want to pipe the results to an other program
47
- or write them to a file.
48
-
49
- ```ruby
50
- :cmb_length=>([5] or [5,6])
51
- ```
52
- Set the length of the possible combinations to be generated if
53
- there is more than one value first all the combinations with the
54
- starting value are generated and then once done combinations of
55
- the following length are generated till all the values have been used.
56
-
57
- ```ruby
58
- :characters=>["e","x","m","p","l","e",1]
59
- ```
60
- Sets the characters that will be used in the combination generation process.
61
-
62
- ```ruby
63
- :extra_chars=>["x",1] (Optional)
64
- ```
65
- Set extra characters to be used one at a time if the initial characters,minimum value 1 char.
66
- Note that when etxra_chars are used only combinations that include them will be written to file.
67
-
68
- ```ruby
69
- :type=>("matching" or "unique")
70
- ```
71
- Sets which type of combinations to be generated.
72
- Matching: Characters repeating them selves any number of times xx or xxx
73
- Unique:Characters are different in every position xz or xzx
74
-
75
- ```ruby
76
- :match_limit=> 2 (:optional)
77
- ```
78
- Set the max matching characters for each combination example:
79
-
80
- 2 = xxabc, axxbc,abxxc,abcxx
81
-
82
- 3 = xxxab, axxxb,abxxx
83
-
84
- Note that you can set the limit to more than 3 but file size info will
85
- not be accurate.
86
-
87
- ```ruby
88
- :skip_first=>(true |false) (Optional)
89
- ```
90
- Used with extra_chars allows you to skip the first iteration with the
91
- main characters thus starting from the extra characters.Useful if you
92
- want to continue from where you left off.
93
-
94
- ```ruby
95
- :uniqueness_type=>("repeat"|"singe") (Optional)
96
- ```
97
- If not set all possible unique combinations are generated i.e reappearing char xzx,single char xyz
98
- When set to repeat only reappearing character combinations are generated xzx
99
- When set to single only single character appearance combinations are generated xzy.
100
-
101
-
102
- ```ruby
103
- :cap_limit=>1 or more (optional)
104
-
105
- ```
106
- When used it ensures that each combination generated will contain only the amount of capital letters specified.
107
-
108
- **Note that file size and combination estimates when using match_limit may not be accurate**
109
-
110
-
111
-
112
-
113
- ## Development
114
-
115
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
116
-
117
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
118
-
119
- ## Contributing
120
-
121
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/phoenix_password. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
122
-
123
-
124
- ## License
125
-
126
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
127
-
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
@@ -1,3 +0,0 @@
1
- class PhoenixPassword
2
- VERSION = "0.2.0"
3
- end
@@ -1,770 +0,0 @@
1
- require "phoenix_password/version"
2
-
3
- class PhoenixPassword
4
- def self.generate_combinations(data)
5
- characters=data[:characters]
6
- if !data[:extra_chars].nil?
7
- characters.push(data[:extra_chars][data[:iteration]-1]) if data[:iteration] != 0
8
- end
9
- combination=Array.new(data[:cmb_length],data[:characters].first)
10
- combination_length=combination.length
11
- i=0
12
- possible_combinations=characters.length**combination_length
13
- chars_used=Array.new(data[:cmb_length],0)
14
-
15
- while i < possible_combinations/characters.length
16
- x=1
17
- change_count=1
18
- while x < combination_length
19
- if chars_used[x] == characters.length
20
- chars_used[x] = 0
21
- end
22
- if combination[x] == characters.last && combination[x+1] == characters.last
23
- change_count +=1
24
- if change_count == combination_length -1
25
- chars_used[0] += 1
26
- end
27
- end
28
- x +=1
29
- end
30
-
31
- y=0
32
- until y == combination_length
33
- combination[y]=characters[chars_used[y]]
34
- y+=1
35
- end
36
-
37
- combinations=[]
38
- if data[:extra_chars].nil? || data[:iteration] == 0
39
-
40
- combinations.<<(combination.join())
41
- if combination.last != characters.first
42
- reverse_comb=combination.reverse
43
- combinations.<<(reverse_comb.join())
44
- reverse_comb.pop
45
- reverse_compare=reverse_comb
46
- reverse_comb=reverse_comb.join()
47
- check_match= matching_check({:combination=>reverse_comb,:match_limit=>data[:match_limit],:cap_limit=>data[:cap_limit]})
48
- characters.each do |char|
49
- next if char == characters.first
50
- if data[:type] == "unique"
51
- combinations.<<("%s%s"%[reverse_comb,char])
52
- else
53
- if check_match
54
- combinations.<<("%s%s"%[reverse_comb,char])
55
- else
56
- combinations.<<("%s%s"%[reverse_comb,char]) if char == reverse_compare.last
57
- end
58
- end
59
- end
60
- end
61
-
62
- else
63
- combinations << combination.join() if combination.include?(characters.last)
64
- if combination.last != characters.first
65
- reverse_comb=combination.reverse
66
- reverse_comb.pop
67
- reverse_compare=reverse_comb
68
- reverse_comb=reverse_comb.join
69
- if reverse_comb.include?(characters.last)
70
- check_match= matching_check({:combination=>reverse_comb,:match_limit=>data[:match_limit],:cap_limit=>data[:cap_limit]}) if data[:type] == 'matching'
71
- characters.each do |char|
72
- if data[:type] == "unique"
73
- combinations.<<("%s%s"%[reverse_comb,char])
74
- elsif check_match
75
- combinations.<<("%s%s"%[reverse_comb,char])
76
- else
77
- combinations.<<("%s%s"%[reverse_comb,char]) if char == reverse_compare.last
78
- end
79
- end
80
- else
81
- combinations.<<("%s%s"%[reverse_comb,characters.last])
82
- end
83
- end
84
- end
85
-
86
- yield(combinations) if combinations.length >= 1
87
-
88
- z=combination_length-1
89
- while 1 < z
90
- if z == combination_length-1
91
- chars_used[z-1] +=1 if combination[z] == characters.last
92
- else
93
- diff=(combination_length-1)-z
94
- last_chars=0
95
- count_diff=1
96
- while count_diff <= diff
97
- if combination[z] == characters.last && combination[z+count_diff] == characters.last
98
- last_chars +=1
99
- end
100
- count_diff +=1
101
- end
102
- if last_chars == (combination_length-1)-z
103
- chars_used[z-1] +=1
104
- end
105
- end
106
- z-=1
107
- end
108
- chars_used[combination_length-1] +=1
109
- i+=1
110
- end
111
- return characters
112
- end
113
-
114
- def self.matching_combinations(info)
115
- data={:characters=>info[:characters],:cmb_length=>info[:cmb_length],:type=>info[:type]}
116
- unless info[:extra_chars].nil?
117
- data[:extra_chars]=info[:extra_chars]
118
- end
119
-
120
- matching_file=create_file(info) if !info[:piped]
121
-
122
- char_sum=data[:characters].length
123
- total_characters=data[:characters].length
124
- unless data[:extra_chars].nil?
125
- total_characters=data[:characters].length+data[:extra_chars].length
126
- data[:iteration]=0
127
- if info[:skip_first] || !info[:piped]
128
- data[:iteration] +=1
129
- char_sum +=1
130
- end
131
- end
132
-
133
- matching=0
134
- begin
135
- generate_combinations(data) do |combinations|
136
- combinations.each do |combination|
137
- if matching_check({:combination=>combination,:match_limit=>info[:match_limit],:cap_limit=>info[:cap_limit]})
138
- if info[:piped]
139
- puts combination
140
- else
141
- matching_file.puts(combination)
142
- end
143
- matching +=1
144
- end
145
- end
146
- end
147
- data[:iteration]+=1 unless data[:iteration].nil?
148
- char_sum +=1
149
- rescue => e
150
- raise
151
- end while char_sum <= total_characters
152
- matching_file.close unless matching_file.nil?
153
- return matching
154
- end
155
-
156
- def self.matching_check(info)
157
- combination=info[:combination]
158
- if info[:cap_limit]
159
- caps=combination.scan(/[A-Z]/)
160
- return false if caps.length == 0 || caps.length > info[:cap_limit]
161
- end
162
- i=0
163
- x=0
164
- u=0
165
- while i < (combination.length-1)
166
- if combination[i] == combination[i+1]
167
- return true if info[:match_limit].nil?
168
- if i == 0
169
- x +=1
170
- elsif combination[i] == combination[i-1] || combination[i] == combination[i+info[:match_limit]]
171
- x+=1
172
- end
173
- else
174
- u +=1
175
- end
176
- if x == info[:match_limit] || u == combination.length-1
177
- return false
178
- end
179
- i+=1
180
- end
181
- return true
182
- end
183
-
184
- def self.unique_combinations(info)
185
- data={:characters=>info[:characters],:cmb_length=>info[:cmb_length],:type=>info[:type],:uniqueness_type=>info[:uniqueness_type]}
186
- unless info[:extra_chars].nil?
187
- data[:extra_chars]=info[:extra_chars]
188
- end
189
-
190
- unique_file=create_file(info) unless info[:piped]
191
-
192
- total_characters=data[:characters].length
193
- char_sum= data[:characters].length
194
- unless data[:extra_chars].nil?
195
- total_characters=data[:characters].length+data[:extra_chars].length
196
- data[:iteration]=0
197
- if info[:skip_first] || !info[:piped]
198
- data[:iteration]+=1
199
- char_sum +=1
200
- end
201
- end
202
- unique_combs=0
203
- uniqueness=info[:uniqueness_type]
204
- begin
205
- generate_combinations(data) do |combinations|
206
- combinations.each do |combination|
207
- unique_chars=check_uniqueness(combination,uniqueness,info[:cap_limit])
208
- if unique_chars == combination.length-1
209
- if info[:piped]
210
- puts combination
211
- else
212
- unique_file.puts(combination)
213
- end
214
- unique_combs= unique_combs+1
215
- end
216
- end
217
- end
218
- data[:iteration] +=1 if !data[:iteration].nil?
219
- char_sum +=1
220
- rescue => e
221
- raise
222
- end while char_sum <= total_characters
223
-
224
- unless unique_file.nil?
225
- unique_file.close
226
- end
227
-
228
- return unique_combs
229
- end
230
-
231
- def self.check_uniqueness(combination,uniqueness,cap_limit)
232
- if cap_limit
233
- caps=combination.scan(/[A-Z]/)
234
- return 0 if caps.length == 0 || caps.length > cap_limit
235
- end
236
- i=0
237
- unique_chars=0
238
- chars_check=[]
239
- while i < (combination.length-1)
240
- if combination[i] != combination[i+1]
241
- if uniqueness.nil?
242
- unique_chars+=1
243
- elsif uniqueness == "single"
244
- if i == 0
245
- unique_chars+=1
246
- chars_check.push(combination[i])
247
- elsif !chars_check.include?(combination[i])
248
- chars_check << combination[i]
249
- if !chars_check.include?(combination[i+1])
250
- unique_chars +=1
251
- else
252
- return 0
253
- end
254
- end
255
- elsif uniqueness == "repeat"
256
- if i == 0
257
- unique_chars+=1
258
- chars_check.push(combination[i])
259
- elsif chars_check.include?(combination[i])
260
- unique_chars+=1
261
- elsif i == (combination.length-2)
262
- #since in last iteration compare against the next character as well
263
- unique_chars +=1 if chars_check.include?(combination[i]) || chars_check.include?(combination[i+1])
264
- else
265
- chars_check.push(combination[i])
266
- end
267
-
268
- return combination.length-1 if i == (combination.length-2) && unique_chars > 1
269
- end
270
- else
271
- return 0
272
- end
273
- i+=1
274
- end
275
- return unique_chars
276
- end
277
-
278
- def self.get_single_combs(data)
279
- i=0
280
- single_combinations=0
281
- extra_singe=0
282
- extra_chars=data[:characters].length+data[:extra_chars].length if !data[:extra_chars].nil?
283
- while i < data[:cmb_length]-1
284
- if i == 0
285
- single_combinations=(data[:characters].length-1)*data[:characters].length
286
- extra_singe=extra_chars*(extra_chars-1) if !extra_chars.nil?
287
- else
288
- single_combinations=single_combinations*(data[:characters].length-(i+1))
289
- extra_singe=extra_singe*(extra_chars-(i+1)) if !extra_chars.nil?
290
- end
291
- i+=1
292
- end
293
- return extra_singe - single_combinations if !data[:extra_chars].nil?
294
- return single_combinations
295
- end
296
-
297
- def self.get_combinations(data)
298
- if data[:extra_chars].nil?
299
- base=data[:characters].length
300
- else
301
- old_base=data[:characters].length
302
- old_combinations=old_base**data[:cmb_length]
303
- x=0
304
- post_matches=0
305
- while x < data[:cmb_length]-1
306
- if x == 0
307
- post_matches=old_base
308
- elsif x == 1
309
- post_matches=(old_base**x)+(1*(old_base-1))
310
- else
311
- post_matches=(old_base**x)+(post_matches*(old_base-1))
312
- end
313
- x+=1
314
- end
315
- old_matches=old_base*post_matches
316
- base=data[:characters].length+data[:extra_chars].length
317
- end
318
- previous_matches=0
319
- i=0
320
-
321
- while i < data[:cmb_length]-1
322
- if i==0
323
- previous_matches=base
324
- elsif i== 1
325
- previous_matches=(base**i)+(1*(base-1))
326
- else
327
- previous_matches=(base**i)+(previous_matches*(base-1))
328
- end
329
- i+=1
330
- end
331
- matches=base*previous_matches
332
-
333
- if data[:type]=='unique'
334
- possible_combinations=base**data[:cmb_length]
335
- if data[:uniqueness_type].nil?
336
- return (possible_combinations-matches)-(old_combinations-old_matches) if !data[:extra_chars].nil?
337
- return possible_combinations-matches
338
- else
339
- single_combs=get_single_combs(data)
340
- if data[:uniqueness_type]=="single"
341
- return single_combs
342
- elsif data[:uniqueness_type]=="repeat"
343
- return ((possible_combinations-matches)-(old_combinations-old_matches))-single_combs if !data[:extra_chars].nil?
344
- return (possible_combinations-matches)-single_combs
345
- end
346
- end
347
- else
348
- return matches-old_matches if !data[:extra_chars].nil?
349
- return matches
350
- end
351
- return 0
352
- end
353
-
354
- def self.get_above_limit(data)
355
- if data[:extra_chars].nil?
356
- base=data[:characters].length
357
- else
358
- old_base=data[:characters].length
359
- previous_matches=0
360
- previous_mult=0
361
- i=0
362
- while i < (data[:cmb_length] -1)
363
- if i == (data[:match_limit]-1)
364
- previous_matches=old_base
365
- old_matches=previous_matches
366
- elsif i == data[:match_limit]
367
- previous_matches=previous_matches+(1*(old_base-1))
368
- previous_mult=1
369
- else
370
- temp_mult=previous_matches
371
- previous_matches=(old_base**(i-1)+previous_mult*(old_base-1))+(previous_matches*(old_base-1))
372
- previous_mult=temp_mult
373
- end
374
-
375
- i+=1
376
- end
377
-
378
- old_matches=old_base*previous_matches if data[:cmb_length] != (data[:match_limit]+1)
379
- base=data[:characters].length+data[:extra_chars].length
380
- end
381
-
382
- previous_matches=0
383
- previous_mult=0
384
- i=1
385
- while i < (data[:cmb_length] -1)
386
- if i == (data[:match_limit]-1)
387
- previous_matches=base
388
- return previous_matches if data[:cmb_length] == (data[:match_limit]+i) && data[:extra_chars].nil?
389
- elsif i == data[:match_limit]
390
- previous_matches=previous_matches+(1*(base-1))
391
- previous_mult=1
392
- else
393
- temp_mult=previous_matches
394
- previous_matches=(base**(i-1))+(previous_mult*(base-1))+(previous_matches*(base-1))
395
- previous_mult=temp_mult
396
-
397
- end
398
- i+=1
399
- end
400
-
401
- unless data[:extra_chars].nil?
402
- return base-old_base if data[:cmb_length] == (data[:match_limit]+1)
403
- return (base*previous_matches)-old_matches
404
- else
405
- return base*previous_matches
406
- end
407
- end
408
-
409
- def self.cap_limit_matching(data)
410
- cap_data={}
411
- total_chars=data[:characters].join()
412
- caps_matched= total_chars.scan(/[A-Z]/)
413
- cap_data[:characters]=[]
414
- data[:characters].each do |char|
415
- next if caps_matched.include?(char)
416
- cap_data[:characters].push(char)
417
- end
418
- base=cap_data[:characters].length
419
- cap_matches=0
420
- case data[:cmb_length]
421
- when 3
422
- cap_matches += base*2
423
- when 4
424
- cap_matches+=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1})*2
425
- cap_matches+=(base**2)*2
426
- else
427
- cap_matches+=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1})*2
428
- cap_matches+=(get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-2})*base)*(data[:cmb_length]-2)
429
- end
430
-
431
- if !data[:extra_chars].nil?
432
- all_chars=data[:characters]+data[:extra_chars]
433
- new_cap_matches=cap_limit_matching({:cmb_length=>data[:cmb_length],:characters=>all_chars})
434
- return new_cap_matches-(cap_matches*caps_matched.length)
435
- else
436
- return cap_matches*caps_matched.length
437
- end
438
-
439
- end
440
-
441
- def self.cap_limit_matching_l(data)
442
- cap_data={}
443
- total_chars=data[:characters].join()
444
- caps_matched= total_chars.scan(/[A-Z]/)
445
- cap_data[:characters]=[]
446
- data[:characters].each do |char|
447
- next if caps_matched.include?(char)
448
- cap_data[:characters].push(char)
449
- end
450
- base=cap_data[:characters].length
451
- cap_matches=0
452
- no_limit_matches=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1})
453
- case data[:cmb_length]
454
- when 3
455
- cap_matches += base*2
456
- when 4
457
- cap_matches+=(no_limit_matches-get_above_limit({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:match_limit=>data[:match_limit]}))*2
458
- cap_matches+=(base**2)*2
459
- else
460
-
461
- #XXA
462
- cap_matches+=(no_limit_matches-get_above_limit({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:match_limit=>data[:match_limit]}))*2
463
- no_limit_matches=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-2})
464
- #XAX
465
- cap_matches+=((no_limit_matches-get_above_limit({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-2,:match_limit=>data[:match_limit]}))*base)*2
466
- x=data[:cmb_length]-4
467
- if x == 1
468
- cap_matches +=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-2})*base
469
- elsif x == 2
470
- grt_half_no_limit=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-3})
471
- grt_half_limit =grt_half_no_limit-get_above_limit({:characters=>cap_data[:characters],:match_limit=>data[:match_limit],:cmb_length=>data[:cmb_length]-3})
472
- cap_matches +=(((grt_half_limit*base**2)+(base*base**3))-(grt_half_no_limit*base))*2
473
- else
474
- #AXX
475
- i=3
476
- p=0
477
- l=0
478
- begin
479
- grt_half=get_combinations({:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-(3+l)})
480
- grt_half_limit =grt_half-get_above_limit({:characters=>cap_data[:characters],:match_limit=>data[:match_limit],:cmb_length=>data[:cmb_length]-(3+l)})
481
- if i == 3
482
- if data[:cmb_length] <=8
483
- cap_matches +=(((grt_half_limit*base**2)+(base*base**(x+1)))-(grt_half*base))*2
484
- else
485
- cap_matches +=((grt_half_limit*((base**2)-base))+(base*base**(x+1)))*2
486
-
487
- end
488
- else
489
- lsr_half=get_combinations({:characters=>cap_data[:characters],:cmb_length=>i-1})
490
- lsr_half_limit=lsr_half-get_above_limit(:characters=>cap_data[:characters],:match_limit=>data[:match_limit],:cmb_length=>i-1)
491
- cap_matches +=(((grt_half_limit*(base**(2+p)))+(lsr_half_limit*base**(x+1-p)))-(grt_half*lsr_half))*2
492
-
493
- end
494
- p+=1
495
- l+=1
496
- i+=1
497
- end while i < (data[:cmb_length]/2.0).ceil
498
-
499
-
500
-
501
- if x%2 == 1
502
- no_limit_matches=get_combinations({:characters=>cap_data[:characters],:cmb_length=>x-(p-1)})
503
- half_point=(((no_limit_matches-get_above_limit({:characters=>cap_data[:characters],:cmb_length=>x-(p-1),:match_limit=>data[:match_limit]})))*base**(x-(p-1)))*2
504
- if data[:cmb_length] == 7
505
- cap_matches+=half_point-((half_point/base))
506
- else
507
- half_no_limit=get_combinations(:characters=>cap_data[:characters],:cmb_length=>x-1)
508
- half_no_limit_b=get_combinations(:characters=>cap_data[:characters],:cmb_length=>x-2)
509
-
510
- if data[:cmb_length] >= 9 && data[:extra_chars].nil?
511
- puts "!------Approximately less than------!"
512
- end
513
- cap_matches+=half_point-((half_point/base))
514
-
515
- end
516
-
517
- else
518
- no_limit_matches_a=get_combinations({:characters=>cap_data[:characters],:cmb_length=>(x-l)+1})
519
- greater_half=(((no_limit_matches_a-get_above_limit({:characters=>cap_data[:characters],:cmb_length=>(x-l)+1,:match_limit=>data[:match_limit]})))*base**(x-l))
520
- no_limit_matches_b=get_combinations({:characters=>cap_data[:characters],:cmb_length=>(x-l)})
521
- lesser_half=(((no_limit_matches_b-get_above_limit({:characters=>cap_data[:characters],:cmb_length=>(x-l),:match_limit=>data[:match_limit]})))*base**(x-l+1))
522
-
523
- if data[:cmb_length] == 10 && data[:extra_chars].nil?
524
- puts "!------Approximately less than------!"
525
- elsif data[:cmb_length] == 12 && data[:extra_chars].nil?
526
- puts "!------Approximately more than------!"
527
- end
528
- cap_matches+=((greater_half+lesser_half)-((no_limit_matches_a*no_limit_matches_b)-(no_limit_matches_b*base)))*2
529
- end
530
-
531
- end
532
-
533
- end
534
-
535
- if (cap_data[:characters].length <= 2 || data[:cmb_length] >= 13) && data[:extra_chars].nil?
536
- puts "!!!----Inaccurate information----!!!"
537
- end
538
-
539
- if !data[:extra_chars].nil?
540
- all_chars=data[:characters]+data[:extra_chars]
541
- new_cap_matches=cap_limit_matching_l({:cmb_length=>data[:cmb_length],:characters=>all_chars,:match_limit=>data[:match_limit]})
542
- return new_cap_matches-(cap_matches*caps_matched.length)
543
- else
544
- return cap_matches*caps_matched.length
545
- end
546
- end
547
-
548
- def self.unique_cap_limit(data)
549
- cap_data={}
550
- total_chars=data[:characters].join()
551
- caps_matched= total_chars.scan(/[A-Z]/)
552
- cap_data[:characters]=[]
553
- data[:characters].each do |char|
554
- next if caps_matched.include?(char)
555
- cap_data[:characters].push(char)
556
- end
557
- base=cap_data[:characters].length
558
- unique_cap_limit=0
559
- if data[:uniqueness_type] == 'single'
560
- if data[:cmb_length] == 3
561
- unique_cap_limit=(((base**2)-(base))*3)
562
- else
563
- previous_single=get_single_combs(:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:type=>"unique")
564
- unique_cap_limit=previous_single*data[:cmb_length]
565
- end
566
- else
567
- case data[:cmb_length]
568
- when 3
569
- if data[:uniqueness_type].nil?
570
- unique_cap_limit=((base**2)*3)-(base*2)
571
- else
572
- unique_cap_limit=((base**2)*3)-(base*2)-(((base**2)-(base))*3)
573
- end
574
- when 4
575
- previous_unique=get_combinations(:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:type=>"unique")
576
- if data[:uniqueness_type].nil?
577
- unique_cap_limit=(previous_unique*2)+((((base**2)-base)*base)*2)
578
- else
579
- previous_single=get_single_combs(:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:type=>"unique")
580
- unique_cap_limit=(previous_unique*2)+((((base**2)-base)*base)*2)-(previous_single*data[:cmb_length])
581
- end
582
- else
583
- previous_unique_a=get_combinations(:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:type=>"unique")
584
- previous_unique_b=get_combinations(:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-2,:type=>"unique")
585
- if data[:uniqueness_type].nil?
586
- unique_cap_limit=(previous_unique_a*2)+((previous_unique_b*base)*(data[:cmb_length]-2))
587
- else
588
- previous_single=get_single_combs(:characters=>cap_data[:characters],:cmb_length=>data[:cmb_length]-1,:type=>"unique")
589
- unique_cap_limit=(previous_unique_a*2)+((previous_unique_b*base)*(data[:cmb_length]-2))-(previous_single*data[:cmb_length])
590
- end
591
- end
592
- end
593
-
594
- if !data[:extra_chars].nil?
595
- all_chars=data[:characters]+data[:extra_chars]
596
- new_unique_cap_limit=unique_cap_limit({:cmb_length=>data[:cmb_length],:characters=>all_chars,:uniqueness_type=>data[:uniqueness_type]})
597
- return new_unique_cap_limit-(unique_cap_limit*caps_matched.length)
598
- else
599
- return unique_cap_limit*caps_matched.length
600
- end
601
-
602
- end
603
-
604
- def self.cap_limit_combs(data,x=0)
605
- if data[:type] == "matching"
606
- if !data[:match_limit].nil?
607
- puts "Combinations and file size may vary when using match_limit" if x == 0
608
- cap_limit_matching_l(data)
609
- else
610
- cap_limit_matching(data)
611
- end
612
- else
613
- unique_cap_limit(data)
614
- end
615
- end
616
-
617
- def self.get_size(data)
618
- bytes=data[:combinations]*(data[:cmb_length]+1)
619
- kilo_bytes=bytes/1000.0
620
- mega_bytes=kilo_bytes/1000.0
621
- giga_bytes=mega_bytes/1000.0
622
- tera_bytes=giga_bytes/1000.0
623
- peta_bytes=tera_bytes/1000.0
624
- all_sizes= {:bytes=>bytes,:kilo=>kilo_bytes,:mega=>mega_bytes,:giga=>giga_bytes,:tera=>tera_bytes,:peta=>peta_bytes}
625
- return_sizes= {}
626
- all_sizes.each do |key,value|
627
- if kilo_bytes < 1
628
- return_sizes[key]=value
629
- break
630
- end
631
- return_sizes[key]=value if value > 0.01 && key != :bytes
632
- end
633
- yield(return_sizes) if block_given?
634
- return return_sizes
635
- end
636
-
637
-
638
- def self.create_file(data)
639
- continue=file_info(data)
640
- case continue
641
- when /(y|Y)/
642
- if data[:file_append]
643
- return File.open("#{data[:file_append]}.txt","a")
644
- else
645
- puts "Creating file"
646
- print "Enter save file name:"
647
- file_name=gets.chomp
648
- data[:file_append]=file_name if !data[:file_append].nil?
649
- return File.open("#{file_name}.txt","w")
650
- end
651
-
652
- when /(n|N)/
653
- puts "Goodbye"
654
- exit
655
- else
656
- puts "Invalid option"
657
- exit
658
- end
659
- end
660
-
661
- def self.file_info(data)
662
- if data[:file_append].nil? || !data[:file_append]
663
- if data[:write_cmbs].nil?
664
- poss_combs=get_combinations(data)
665
- if !data[:match_limit].nil?
666
- if !data[:cap_limit].nil?
667
- poss_combs=cap_limit_combs(data)
668
- else
669
- poss_combs -= get_above_limit(data)
670
- end
671
- elsif !data[:cap_limit].nil?
672
- poss_combs=cap_limit_combs(data)
673
- end
674
- matching_file_size=get_size({:cmb_length=>data[:cmb_length],:combinations=>poss_combs})
675
- else
676
- poss_combs=0
677
- matching_file_size={:bytes=>0,:kilo=>0,:mega=>0,:giga=>0,:tera=>0,:peta=>0}
678
- dataB=data.clone
679
- cmb_count=data[:write_cmbs].length if !data[:cap_limit].nil?
680
- data[:write_cmbs].each do |n|
681
- dataB[:cmb_length]=n
682
- if data[:cap_limit].nil?
683
- current_combs=get_combinations(dataB)
684
- poss_combs +=current_combs
685
- unless data[:match_limit].nil?
686
- poss_combs -= get_above_limit(dataB)
687
- current_combs -= get_above_limit(dataB)
688
- end
689
- else
690
- current_combs=cap_limit_combs(dataB,cmb_count)
691
- cmb_count -= 1
692
- poss_combs +=cap_limit_combs(dataB,cmb_count)
693
- end
694
- get_size({:cmb_length=>n,:combinations=>current_combs})do |sizes|
695
- sizes.each do |key,value|
696
- matching_file_size[key] +=value
697
- end
698
- matching_file_size[:bytes]=0 if matching_file_size[:kilo] >= 1
699
- end
700
- end
701
- end
702
- puts "Possible #{data[:type]} combinations #{poss_combs}."
703
- size_string="File size:"
704
- matching_file_size.each do |key,value|
705
- next if value == 0
706
- size_string += " #{"%.2f"% value}#{key.capitalize}#{'Bytes' if key != :bytes}"
707
- end
708
- puts size_string
709
- puts "Do you wish to continue ?"
710
- puts "y|Y n|N"
711
- return gets.chomp
712
-
713
- elsif data[:file_append]
714
- return "y"
715
- end
716
- end
717
-
718
- def self.multi_length_matching(data)
719
- dataB=data.clone
720
- i=0
721
- while i < data[:cmb_length].length
722
- dataB[:cmb_length] = data[:cmb_length][i]
723
- dataB[:characters]=data[:characters].clone
724
- matching_combinations(dataB)
725
- i+=1
726
- end
727
- end
728
-
729
- def self.multi_length_unique(data)
730
- dataB=data.clone
731
- i=0
732
- while i < data[:cmb_length].length
733
- dataB[:cmb_length] = data[:cmb_length][i]
734
- dataB[:characters]=data[:characters].clone
735
- unique_combinations(dataB)
736
- i+=1
737
- end
738
- end
739
-
740
- def self.combinations(data)
741
- case data[:type]
742
- when "matching"
743
- if data[:cmb_length].length == 1
744
- data[:cmb_length]=data[:cmb_length][0]
745
- matching_combinations(data)
746
- elsif data[:piped]
747
- multi_length_matching(data)
748
- else
749
- data[:file_append]=false
750
- data[:write_cmbs]=data[:cmb_length].clone
751
- multi_length_matching(data)
752
- end
753
-
754
- when "unique"
755
- if data[:cmb_length].length == 1
756
- data[:cmb_length]=data[:cmb_length].first
757
- unique_combinations(data)
758
- elsif data[:piped]
759
- multi_length_unique(data)
760
- else
761
- data[:file_append]=false
762
- data[:write_cmbs]=data[:cmb_length].clone
763
- multi_length_unique(data)
764
- end
765
- else
766
- puts "Invalid combination type"
767
- exit
768
- end
769
- end
770
- end