passphrase 0.1.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.
@@ -1,81 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require File.join(File.dirname(__FILE__), 'options')
4
- require File.join(File.dirname(__FILE__), 'wordlist')
5
- require File.join(File.dirname(__FILE__), 'random')
6
-
7
- module Passphrase
8
- class Generator
9
-
10
- NON_ALPHANUM_REGEX = /[~!#\$%\^&\*\(\)\-=\+\[\]\\\{\}:;"'<>\?\/]/
11
- NON_ALPHANUM_ARRAY = %w( ~ ! # $ % ^ & * \( \) - = + [ ] \\ { } : ; " ' < > ? / )
12
-
13
- attr_reader :phrase
14
- attr_reader :unmixed_phrase
15
-
16
- def initialize(argv)
17
- @options = Options.new(argv)
18
- @words = []
19
- Random.use_local if @options.local
20
- end
21
-
22
- def run
23
- num_words = @options.num_words
24
- word_list = WordList.create
25
- list_selector = Random.new(num_words, 0, word_list.length - 1).to_array
26
- num_words.times do |iword|
27
- word_hash = Random.new(5, 1, 6).to_array.join.to_sym
28
- @words << word_list[list_selector[iword]][word_hash]
29
- end
30
- @unmixed_phrase = @words.join(" ")
31
- @phrase = @unmixed_phrase.clone
32
- mix_phrase if mix?
33
- end
34
-
35
- def mix?
36
- @options.mix
37
- end
38
-
39
- private
40
-
41
- def mix_phrase
42
- mixin_capital unless @phrase =~ /[A-Z]/
43
- mixin_number unless @phrase =~ /\d/
44
- mixin_nonalphanum unless @phrase =~ NON_ALPHANUM_REGEX
45
- end
46
-
47
- def mixin_capital
48
- index, character = make_character_selection
49
- @phrase[index] = character.upcase
50
- end
51
-
52
- def mixin_number
53
- index, character = make_character_selection
54
- numbers = ("0".."9").to_a
55
- number = numbers[one_random_number(numbers.length - 1)]
56
- @phrase[index] = number
57
- end
58
-
59
- def mixin_nonalphanum
60
- index, character = make_character_selection
61
- len = NON_ALPHANUM_ARRAY.length
62
- non_alphanum = NON_ALPHANUM_ARRAY[one_random_number(len - 1)]
63
- @phrase[index] = non_alphanum
64
- end
65
-
66
- def make_character_selection
67
- return [] unless @phrase =~ /[a-z]/
68
- index = one_random_number(@phrase.length - 1)
69
- character = @phrase.slice(index, 1)
70
- until character =~ /[a-z]/
71
- index = index.succ.modulo(@phrase.length)
72
- character = @phrase.slice(index, 1)
73
- end
74
- [index, character]
75
- end
76
-
77
- def one_random_number(max)
78
- Random.new(1, 0, max).to_array.shift
79
- end
80
- end
81
- end
@@ -1,65 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'optparse'
4
- require File.join(File.dirname(__FILE__), 'version')
5
-
6
- module Passphrase
7
- class Options
8
-
9
- NUM_WORDS_RANGE = (3..10)
10
- DEFAULT_NUM_WORDS = 5
11
-
12
- attr_reader :num_words
13
- attr_reader :mix
14
- attr_reader :local
15
-
16
- def initialize(argv)
17
- @num_words = DEFAULT_NUM_WORDS
18
- @mix = true
19
- @local = false
20
- parse(argv)
21
- validate
22
- end
23
-
24
- private
25
-
26
- def parse(argv)
27
- OptionParser.new do |opts|
28
- opts.banner = "Usage: passphrase [options]"
29
- opts.separator "Options:"
30
- opts.on("-n", "--num-words NUMBER", Integer,
31
- "Desired number of words (#{NUM_WORDS_RANGE.to_s}), default #{DEFAULT_NUM_WORDS}") do |num|
32
- @num_words = num
33
- end
34
- opts.on("-x", "--[no-]mix", "Mix in cap, num, non-alphanum, default mix") do |m|
35
- @mix = m
36
- end
37
- opts.on("-l", "--local", "Force use of local random number generator") do |l|
38
- @local = l
39
- end
40
- opts.on_tail("-h", "--help", "Show this message and exit") do
41
- puts opts
42
- exit
43
- end
44
- opts.on_tail("-v", "--version", "Show version and exit") do
45
- puts "#{File.basename($PROGRAM_NAME)}, version #{Passphrase::Version::STRING}"
46
- exit
47
- end
48
-
49
- begin
50
- opts.parse!(argv)
51
- rescue OptionParser::ParseError => e
52
- STDERR.puts e.message, "\n", opts
53
- exit(1)
54
- end
55
- end
56
- end
57
-
58
- def validate
59
- unless NUM_WORDS_RANGE.include?(@num_words)
60
- STDERR.puts "Number of words out of range: allowed #{NUM_WORDS_RANGE.to_s}: specified #{@num_words}"
61
- exit(1)
62
- end
63
- end
64
- end
65
- end
@@ -1,56 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'net/http'
4
- require 'securerandom'
5
-
6
- module Passphrase
7
- class Random
8
-
9
- @@use_random_org = true
10
-
11
- def initialize(num, min, max)
12
- @num, @min, @max = num, min, max
13
- @array_of_rands = []
14
- @via_random_org = true
15
- generate_array_of_rands
16
- end
17
-
18
- def via_random_org?
19
- @via_random_org
20
- end
21
-
22
- def to_array
23
- @array_of_rands
24
- end
25
-
26
- def self.use_local
27
- @@use_random_org = false
28
- end
29
-
30
- private
31
-
32
- def generate_array_of_rands
33
- if @@use_random_org
34
- query = "/integers/?col=1&base=10&format=plain&rnd=new" +
35
- "&num=#{@num}&min=#{@min}&max=#{@max}"
36
- site = Net::HTTP.new("www.random.org")
37
- response, data = site.get(query)
38
- raise unless response.code == "200"
39
- @array_of_rands = data.split.collect {|num| num.to_i}
40
- else
41
- local_rands
42
- end
43
- rescue
44
- local_rands
45
- end
46
-
47
- def local_rands
48
- max = @max - @min + 1
49
- offset = @min
50
- @num.times do
51
- @array_of_rands << (SecureRandom.random_number(max) + offset)
52
- end
53
- @via_random_org = false
54
- end
55
- end
56
- end
@@ -1,30 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'zlib'
4
- require 'base64'
5
- require File.join(File.dirname(__FILE__), 'data')
6
-
7
- module Passphrase
8
- module WordList
9
-
10
- def self.create
11
- decoded_wordlists
12
- end
13
-
14
- private
15
-
16
- def self.decoded_wordlists
17
- Data::ENCODED.collect {|encoded_list| self.decode(encoded_list) }
18
- end
19
-
20
- def self.decode(encoded_list)
21
- decoded_list = {}
22
- lines = Zlib::Inflate.inflate(Base64.decode64(encoded_list)).split(/\n/)
23
- lines.grep(/^\d{5}/).each do |line|
24
- key, value = line.chomp.split
25
- decoded_list[key.to_sym] = value
26
- end
27
- decoded_list
28
- end
29
- end
30
- end
data/test/test_options.rb DELETED
@@ -1,33 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'test/unit'
4
- require 'options'
5
-
6
- class TestOptions < Test::Unit::TestCase
7
-
8
- def test_000_empty_args
9
- opts = Passphrase::Options.new([])
10
- assert_equal Passphrase::Options::DEFAULT_NUM_WORDS, opts.num_words
11
- assert opts.mix
12
- end
13
-
14
- def test_001_specify_num_words
15
- num = Passphrase::Options::DEFAULT_NUM_WORDS - 1
16
- opts = Passphrase::Options.new(%W{--num-words #{num}})
17
- assert_equal num, opts.num_words
18
- assert opts.mix
19
- end
20
-
21
- def test_002_specify_mix
22
- opts = Passphrase::Options.new(%W{--no-mix})
23
- assert_equal Passphrase::Options::DEFAULT_NUM_WORDS, opts.num_words
24
- assert !opts.mix
25
- end
26
-
27
- def test_003_specify_num_words_and_mix
28
- num = Passphrase::Options::DEFAULT_NUM_WORDS - 1
29
- opts = Passphrase::Options.new(%W{--num-words #{num} --no-mix})
30
- assert_equal num, opts.num_words
31
- assert !opts.mix
32
- end
33
- end
@@ -1,17 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'test/unit'
4
- require 'wordlist'
5
-
6
- class TestOptions < Test::Unit::TestCase
7
-
8
- def setup
9
- @wordlist = Passphrase::WordList.create
10
- end
11
-
12
- def test_000_sample_words
13
- assert_equal 2, @wordlist.length
14
- assert_equal "embalm", @wordlist[0][:'24356']
15
- assert_equal "potato", @wordlist[1][:'46132']
16
- end
17
- end