alexpass 0.1.0 → 0.1.1

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 (3) hide show
  1. data/lib/alexpass.rb +6 -80
  2. data/test/test_alexpass.rb +2 -57
  3. metadata +5 -6
data/lib/alexpass.rb CHANGED
@@ -1,90 +1,16 @@
1
1
  class Alexpass
2
2
 
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
+ DEPRECATED = 'Sorry, but this gem has been replaced by Altpass: https://github.com/abatko/altpass'
4
5
 
5
- DEFAULT_LENGTH = 8
6
- DEFAULT_OPTIONS = {:length => DEFAULT_LENGTH, :memorizable => true}
7
-
8
- # character sets divided by touch typing hands
9
- LN = '12345'.split('') # Left-hand Numbers
10
- RN = '67890' .split('') # Right ''
11
- LL = ('qwert'+'asdfg'+'zxcvb').split('') # Left-hand Lowercase letters
12
- RL = ('yuiop'+'hjkl'+'nm').split('') # Right '' ''
13
- LU = LL.collect {|c| c.capitalize} # Left-hand Uppercase letters
14
- RU = RL.collect {|c| c.capitalize} # Right '' ''
15
-
16
- AMBIGUOUS = '1lI0O' + # visually ambiguous
17
- '6b' # left/right ambiguous
18
-
19
- # patterns for even and odd length passwords;
20
- # alternating hands, with the last always being on the left;
21
- # only the first in each subset takes part in the "memorizable" pattern: LUUNLLNL
22
- @pattern_even = [[RL], [LU, LN, LL], [RU, RN, RL], [LN, LL, LU], [RL, RU, RN], [LL, LU, LN], [RN, RL, RU], [LL]]
23
-
24
- @pattern_odd = [[LL], [RU, RN, RL], [LU, LN, LL], [RN, RL, RU], [LL, LU, LN], [RL, RU, RN], [LN, LL, LU], [RL]]
25
-
26
- # return a password
27
6
  def self.generate(options={})
28
- options = self._verify_options(options)
29
- password = ''
30
- iterations = options[:length]/DEFAULT_LENGTH + 1
31
- iterations.times { password += self._generate(options) }
32
- password.slice(0...options[:length])
7
+ warn DEPRECATED
8
+ DEPRECATED
33
9
  end
34
10
 
35
- # return the number of permutations,
36
- # and additionally print out details when options[:permutations] contains v's
37
11
  def self.permutations(options={})
38
- options = self._verify_options(options)
39
- p = 1
40
- pattern = options[:length].even? ? @pattern_even : @pattern_odd
41
- plen = pattern.length
42
- samples = []
43
- (0...options[:length]).each { |i|
44
- samples[i] = (options[:memorizable] ? pattern[i%plen][0] : pattern[i%plen].flatten).reject{|c| AMBIGUOUS.include?(c)}
45
- p *= samples[i].length # take the product of all sample sizes to get the total number of permutations
46
- }
47
- if options[:permutations] =~ /^v{3,}\Z/
48
- puts "sample sets:"
49
- samples.each {|s|
50
- puts s.inspect
51
- }
52
- end
53
- puts "#{samples.collect {|s| s.length}.join(' * ')} permutations" if options[:permutations] =~ /^v{2,}\Z/
54
- p
55
- end
56
-
57
- private
58
-
59
- # verify and return an options hash, after merging the default options with the incoming ones
60
- def self._verify_options(options=nil)
61
- raise ArgumentError, "expected a Hash, but got: #{options.inspect}" unless options.kind_of?(Hash)
62
- options = DEFAULT_OPTIONS.merge(options)
63
- raise ArgumentError, "expected :memorizable to be boolean, but got: #{options[:memorizable].inspect}" unless options[:memorizable].kind_of?(TrueClass) || options[:memorizable].kind_of?(FalseClass)
64
- raise ArgumentError, "expected :length to be a Fixnum, but got: #{options[:length].inspect}" unless options[:length].kind_of?(Fixnum)
65
- raise ArgumentError, "expected :length > 0, but got: #{options[:length]}" unless options[:length] > 0
66
- options
67
- end
68
-
69
- # generate and return a string, having a parity-appropriate pattern, where each character is sampled from the appropriate character set (depending on whether :memorizable is true or false)
70
- def self._generate(options={})
71
- options = self._verify_options(options)
72
- pattern = options[:length].even? ? @pattern_even : @pattern_odd
73
- return pattern.collect { |i|
74
- s =''
75
- loop do
76
- s = _sample(i[options[:memorizable] ? 0 : rand(i.length)])
77
- break unless AMBIGUOUS.include?(s)
78
- end
79
- s
80
- }.join.slice(0..-1)
81
- end
82
-
83
- # pick a random element from the given array
84
- def self._sample(a=[])
85
- raise ArgumentError, "expected an Array, but got: #{a.class}" unless a.kind_of?(Array)
86
- raise ArgumentError, "expected a non-empty Array, but got an empty one" unless a.length > 0
87
- a[rand(a.length)]
12
+ warn DEPRECATED
13
+ DEPRECATED
88
14
  end
89
15
 
90
16
  end
@@ -3,63 +3,8 @@ require 'test_helper'
3
3
 
4
4
  class AlexpassTest < Test::Unit::TestCase
5
5
 
6
- def test__generate__default_length
7
- assert_equal Alexpass::DEFAULT_LENGTH, Alexpass.generate.length
8
- end
9
-
10
- def test__generate__random_length
11
- random_length = rand(20)+1
12
- assert_equal random_length, Alexpass.generate(:length=>random_length).length
13
- end
14
-
15
- def test__generate__raise_exception_for_non_hash_argument
16
- non_hash_argument = 10
17
- exception = assert_raise(ArgumentError) { Alexpass.generate(non_hash_argument) }
18
- assert_equal "expected a Hash, but got: #{non_hash_argument}", exception.message
19
- end
20
-
21
- def test__generate__raise_exception_for_bad_memorizable_hash_value_type
22
- non_boolean = {:memorizable => 10}
23
- exception = assert_raise(ArgumentError) { Alexpass.generate(non_boolean) }
24
- assert_equal "expected :memorizable to be boolean, but got: #{non_boolean[:memorizable].inspect}", exception.message
25
- end
26
-
27
- def test__generate__raise_exception_for_bad_length_hash_value_type
28
- non_fixnum = {:length => 'A'}
29
- exception = assert_raise(ArgumentError) { Alexpass.generate(non_fixnum) }
30
- assert_equal "expected :length to be a Fixnum, but got: #{non_fixnum[:length].inspect}", exception.message
31
- end
32
-
33
- def test_raise_exception_for_fixnum_argument_less_than_one_to_generate_to_length
34
- fixnum_argument = {:length => 0}
35
- exception = assert_raise(ArgumentError) { Alexpass.generate(fixnum_argument) }
36
- assert_equal "expected :length > 0, but got: #{fixnum_argument[:length].inspect}", exception.message
37
- end
38
-
39
- def test__sample
40
- assert_equal 'a', Alexpass._sample(['a'])
41
- assert_equal 'a', Alexpass._sample(['a', 'a', 'a'])
42
- random_element = Alexpass._sample(['a', 'b', 'c'])
43
- assert_equal String, random_element.class
44
- assert_equal 1, random_element.length
45
- end
46
-
47
- def test__sample_raise_exception_for_non_array_argument
48
- exception = assert_raise(ArgumentError) { Alexpass._sample({}) }
49
- assert_equal "expected an Array, but got: Hash", exception.message
50
- end
51
-
52
- def test__sample_raise_exception_for_empty_array_argument
53
- exception = assert_raise(ArgumentError) { Alexpass._sample([]) }
54
- assert_equal "expected a non-empty Array, but got an empty one", exception.message
55
- end
56
-
57
- def test__permutations
58
- # these hardcoded values will need to be updated if/when the character set lengths change
59
- assert_equal 31752000, Alexpass.permutations
60
- assert_equal 53572004640, Alexpass.permutations(:memorizable => false)
61
- assert_equal 60011280000, Alexpass.permutations(:memorizable => true, :length => 11)
62
- assert_equal 544505855160960, Alexpass.permutations(:memorizable => false, :length => 11)
6
+ def test__deprecated
7
+ assert_equal Alexpass::DEPRECATED, Alexpass.generate
63
8
  end
64
9
 
65
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alexpass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-10 00:00:00.000000000Z
12
+ date: 2012-12-14 00:00:00.000000000Z
13
13
  dependencies: []
14
- description: Generate passwords derived from hand-alternating, visually unambiguous,
15
- alphanumeric characters.
14
+ description: ! 'Sorry, but this gem has been replaced by Altpass: https://github.com/abatko/altpass
15
+ (sorry!)'
16
16
  email:
17
17
  - alexbatko@gmail.com
18
18
  executables: []
@@ -46,8 +46,7 @@ rubyforge_project:
46
46
  rubygems_version: 1.8.10
47
47
  signing_key:
48
48
  specification_version: 3
49
- summary: Generate passwords derived from hand-alternating, visually unambiguous, alphanumeric
50
- characters
49
+ summary: ! 'Sorry, but this gem has been replaced by Altpass: https://github.com/abatko/altpass'
51
50
  test_files:
52
51
  - test/test_alexpass.rb
53
52
  - test/test_helper.rb