random_token 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.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sibevin Wang
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,224 @@
1
+ # Random Token
2
+
3
+ A simple way to generate a random token.
4
+
5
+ jjukoguwegcvclkuhljvsblrpfnd
6
+ je dzl pu
7
+ qu yrllvr bsnehow pplshyo
8
+ sw hwzedi cnjdpqw pnuctvl
9
+ fY sJmss msg2Qpbx 7sgtFpD
10
+ 5V 90Ofl83da 3TQ6fQj
11
+ il q93H GLpCNvakC Fd0ppyd
12
+ QW TWZLX WFQUWYMD MJSYRJI
13
+ IX AIVBZI andomPR okenYIN
14
+ DRRJVYVMEVREBFYXLLFQGISGAGED
15
+
16
+ ## Usage
17
+
18
+ ### Basic
19
+
20
+ Use "gen" method to create a random token with a given length.
21
+
22
+ RandomToken.gen(8)
23
+ # "iUEFxcG2"
24
+
25
+ Some options can help to modify the token format.
26
+
27
+ RandomToken.gen(20, :seed => :alphabet, :friendly => true, :case => :up)
28
+ # "YTHJHTXKSSXTPLARALRH"
29
+
30
+ Use string format to create a random in the particular format. Please read "Format" below to get more details.
31
+
32
+ RandomToken.gen("Give me a token %8?")
33
+ # "Give me a token 6HRQZp8O"
34
+
35
+ ### Seed
36
+
37
+ Use `:seed` option to customize the random characters.
38
+
39
+ Use `:a` (or `:alphabet`, `:l`, `:letter`) to create a token with alphabets.
40
+
41
+ RandomToken.gen(32, :seed => :a)
42
+ # "DTVbCnRldQnLAoERHAzjLOTJBTWoBGQb"
43
+
44
+ Use `:n` (or `:number`, `10`, `1`) to create a token with numbers.
45
+
46
+ RandomToken.gen(32, :seed => :n)
47
+ # "41107838709625922353782552721916"
48
+
49
+ Use `:b` (or `:binary`, `2`) to create a binary token.
50
+
51
+ RandomToken.gen(32, :seed => :b)
52
+ # "11101001110110110000101101010101"
53
+
54
+ Use `:o` (or `:oct`, 8) to create a octal token.
55
+
56
+ RandomToken.gen(32, :seed => :o)
57
+ # "57531726664723324643140173424423"
58
+
59
+ Use `:h` (or `:hex`, 16) to create a hexadecimal token.
60
+
61
+ RandomToken.gen(32, :seed => :h)
62
+ # "B7E1FD250D250008314496AE48EDE310"
63
+
64
+ Use an `array` to customize random seeds.
65
+
66
+ RandomToken.gen(32, :seed => ['a', 'b', 'c'])
67
+ # "cbbcbcabbbacbaaababcbcabcacbcacb"
68
+
69
+ Use a `hash` to customize random seeds and their distribution. For example, the following hash would create a token with "a" and "b" where p("a") = 1/3 and p("b") = 2/3.
70
+
71
+ RandomToken.gen(32, :seed => { 'a' => 1, 'b' => 2 })
72
+ # "bbabbaaaabaabbbabbbbbbbbbaababbb"
73
+
74
+ ### Friendly
75
+
76
+ Use `:friendly` option to remove the ambiguous characters, the default mask includes *1, I, l, i, 0, O, o, Q, D, C, c, G, 9, 6, U, u, V, v, E, F, M, N, 8, B*.
77
+
78
+ RandomToken.gen(32, :friendly => true)
79
+ # "fjx5WTb4wbPmbwb7b4szzY4szfrqtJLj"
80
+
81
+ The default `:friendly` option is false. There is a convenient method "genf" using `:friendly => true` by default.
82
+
83
+ RandomToken.genf(32)
84
+ # "kPafJh5gHAPJjYsssjW7yhthPr4Zg4t3"
85
+
86
+ Friendly is not supported with some `:seed` options(`:b`, `:o`, `:h` and customized hash seeds).
87
+
88
+ RandomToken.genf(32, :seed => :b)
89
+ # RandomToken::RandomTokenError: RandomToken::RandomTokenError
90
+
91
+ Use `:mask` to customize your own friendly mask. Note that `:friendly` is true by default if `:mask` is given.
92
+
93
+ RandomToken.gen(32, :mask => ['a', 'A', 'b', 'c'])
94
+ # "QlHhMpfrGnOykMS8tpfYrW0EnqvRsItw"
95
+
96
+ ### Case
97
+
98
+ Use `:case` option to modify the token case.
99
+
100
+ Use `:u` (or `:up`) to create an upper-case token.
101
+
102
+ RandomToken.gen(32, :case => :u)
103
+ # "YKNOAMC5FQZTMRS9U3SI4U9QWEMU7TLL"
104
+
105
+ Use `:d` (or `:down`) to create a down-case token.
106
+
107
+ RandomToken.gen(32, :case => :d)
108
+ # "8fvs6dfxko4buxcho23vz5jpxw9arj7t"
109
+
110
+ Use `:m` (or `:mixed`) to create a mixed-case token. It is the default option.
111
+
112
+ RandomToken.gen(32, :case => :m)
113
+ # "BjWRJjU2iKF2O1cKrWpnF1EzZHuoUCM5"
114
+
115
+ Case is not supported with some `:seed` options(`:n`, `:b`, `:o` and customized hash seeds).
116
+
117
+ RandomToken.gen(32, :seed => :n, :case => :u)
118
+ # RandomToken::RandomTokenError: RandomToken::RandomTokenError
119
+
120
+ With :hex seed, i.e, `:seed => :h`, the default case is changed to upper-case. You can override it by giving the `:case` option.
121
+
122
+ RandomToken.gen(32, :seed => :h, :case => :d)
123
+ # "d331ce7dae87f3bb3dcb3975be9c430d"
124
+
125
+ ### Format
126
+
127
+ You can embed random tokens in your own string using the format feature. Here are some examples:
128
+
129
+ RandomToken.gen("%4H-%4H-%4H-%4H")
130
+ # "FD77-2792-91A9-6CE3"
131
+
132
+ RandomToken.gen("%2A-%4n")
133
+ # "VS-6921"
134
+
135
+ RandomToken.genf("Your redeem code: %16?")
136
+ # "Your redeem code: 4xgRH2JaLxtR3dWK"
137
+
138
+ RandomToken.gen("Lucky Number = %n")
139
+ # "Lucky Number = 8"
140
+
141
+ The directive consists of a percent(%), length, and type.
142
+
143
+ %[length][type]
144
+
145
+ where
146
+
147
+ * length
148
+
149
+ > The length of random token you want to create. The default value is 1 if no length is given.
150
+
151
+ * type
152
+
153
+ > A - upper-case alphabets
154
+ > a - down-case alphabets
155
+ > n - numbers
156
+ > b - binaries
157
+ > o - octal digits
158
+ > H - upper-case hexadecimal digits
159
+ > h - down-case hexadecimal digits
160
+ > X - upper-case alphabets and numbers
161
+ > x - down-case alphabets and numbers
162
+ > ? - mixed-case alphabets and numbers
163
+ > % - show the % sign
164
+
165
+ Note that `:seed`, `:friendly`, `:case` options are also supported in the format string, and they would override the type behavior.
166
+
167
+ RandomToken.gen("%32X", :seed => :a, :friendly => true, :case => :d)
168
+ # "ddbpeqhtmaenxsaksxrmeaawnwpkfess"
169
+
170
+ ## Use Cases
171
+
172
+ ### Case 1
173
+
174
+ How to create a RPG random desert map?
175
+
176
+ 1.upto(10).each { puts RandomToken.gen(28, :seed => { '.' => 1000, 'o' => 20, 'O' => 5, '_' => 1 }) }
177
+
178
+ ............................
179
+ .......................O.o..
180
+ ............................
181
+ ........................_...
182
+ .....o...............O......
183
+ ............................
184
+ ............................
185
+ ............................
186
+ .........o....O.............
187
+ .o..........................
188
+
189
+ Is it a desert? Of course!! . = sand, o = small stone, O = large stone, and _ = oasis.
190
+
191
+ Oh..., I think I am not a man of imagination like you...
192
+
193
+ ### Case 2
194
+
195
+ How to create a cool logo?
196
+
197
+ puts RandomToken.gen("%28a\n%2a#{' '*9}%3a#{' '*12}%2a\n%2a %6a %7a %7a\n%2a %6a %7a %7a\n%2? %5? %8? %7?\n%2?#{' '*8}%9? %7?\n%2? %4? %9? %7?\n%2A %5A %8A %7A\n%2A %6A andom%2A oken%3A\n%28A")
198
+
199
+ ieqccitkalecvbfehlfbkejdthxc
200
+ kt vhk mw
201
+ mt rktuhx wvniunx yckqxih
202
+ gu mbrjdf ratkfyj oxcvtle
203
+ F7 tFpoz 8QZpLT1Y vxNl778
204
+ VZ gXqKqXDkr Nx1j0Ig
205
+ n9 ee7s UeDOXLl3D pxf6mgH
206
+ VM QGSPP VAJCAVDM UJRCCXP
207
+ KC TMWEVM andomAX okenQNE
208
+ NMVJJAXHHAPLDSYNHCXILCFWYAQA
209
+
210
+ Uh, I don't think it is cool enough...
211
+
212
+ ## Test
213
+
214
+ Go to random_token gem folder and run
215
+
216
+ ruby ./test/test_all.rb
217
+
218
+ ## Authors
219
+
220
+ Sibevin Wang
221
+
222
+ ## Copyright
223
+
224
+ Copyright (c) 2013 Sibevin Wang. Released under the MIT license.
@@ -0,0 +1,229 @@
1
+ require "random_token/random_token_error"
2
+
3
+ module RandomToken
4
+
5
+ # The number seed
6
+ NUMBERS = ('0'..'9')
7
+
8
+ # The alphabet seed
9
+ ALPHABETS = ('A'..'Z')
10
+
11
+ # The default friendly mask
12
+ MASK = ['1', 'I', 'l', 'i', '0', 'O', 'o', 'Q', 'D',
13
+ 'C', 'c', 'G', '9', '6', 'U', 'u', 'V', 'v',
14
+ 'E', 'F', 'M', 'N', '8', 'B']
15
+
16
+ # The default option definition
17
+ DEFAULT_OPT = {
18
+ :seed => nil,
19
+ :friendly => false,
20
+ :case => :mixed
21
+ }
22
+
23
+ # The default seeds definition
24
+ SEED_TYPES = {
25
+ :default => {
26
+ :abbr => [nil],
27
+ :seed => [NUMBERS, ALPHABETS],
28
+ :support_friendly => true,
29
+ :support_case => true,
30
+ :default_case => :mixed
31
+ },
32
+ :alphabet => {
33
+ :abbr => [:letter, :a, :l],
34
+ :seed => [ALPHABETS],
35
+ },
36
+ :number => {
37
+ :abbr => [:n, 1, 10],
38
+ :seed => [NUMBERS],
39
+ :support_case => false
40
+ },
41
+ :binary => {
42
+ :abbr => [:b, 2],
43
+ :seed => [('0'..'1')],
44
+ :support_case => false,
45
+ :support_friendly => false
46
+ },
47
+ :oct => {
48
+ :abbr => [:o, 8],
49
+ :seed => [('0'..'7')],
50
+ :support_case => false,
51
+ :support_friendly => false
52
+ },
53
+ :hex => {
54
+ :abbr => [:h, 16],
55
+ :seed => [NUMBERS, ('A'..'F')],
56
+ :support_friendly => false,
57
+ :default_case => :up
58
+ }
59
+ }
60
+
61
+ # The directives used in the {RandomToken.strf} method.
62
+ STRF_ARG_MAP = {
63
+ 'A' => { :seed => :alphabet, :case => :up },
64
+ 'a' => { :seed => :alphabet, :case => :down },
65
+ 'n' => { :seed => :number },
66
+ 'b' => { :seed => :binary },
67
+ 'o' => { :seed => :oct },
68
+ 'h' => { :seed => :hex, :case => :down },
69
+ 'H' => { :seed => :hex, :case => :up },
70
+ 'X' => { :case => :up },
71
+ 'x' => { :case => :down },
72
+ '?' => {}
73
+ }
74
+
75
+ class << self
76
+ # The major method to generate a random token. It would call {RandomToken.get} or {RandomToken.strf} according to the given arg.
77
+ # @param arg [Fixnum, String]
78
+ # To give a token length or the string format for generating token.
79
+ # @param options [Hash]
80
+ # The options to modify the token.
81
+ # Three options :seed, :friendly and :case are supported.
82
+ # Please see {file:README} to get more examples
83
+ # @return [String]
84
+ # The generated token.
85
+ # @raise [RandomTokenError]
86
+ # Please see {RandomToken::RandomTokenError}
87
+ # @see RandomToken.get
88
+ # @see RandomToken.strf
89
+ def gen(arg, options = {})
90
+ if arg.class.name == 'Fixnum'
91
+ get(arg, options)
92
+ elsif arg.class.name == 'String'
93
+ strf(arg, options)
94
+ else
95
+ raise RandomTokenError.new(:invalid_gen_arg, arg)
96
+ end
97
+ end
98
+
99
+ # A convenient method to generate a friendly token. It would call {RandomToken.gen} with :friendly => true option.
100
+ # @param arg (see RandomToken.gen)
101
+ # @param options (see RandomToken.gen)
102
+ # @return (see RandomToken.gen)
103
+ # @raise (see RandomToken.gen)
104
+ def genf(arg, options = {})
105
+ gen(arg, { :friendly => true }.merge(options))
106
+ end
107
+
108
+ # To generate a random token with a given length.
109
+ # @param length [Fixnum]
110
+ # The token length.
111
+ # @param options (see RandomToken.gen)
112
+ # @return (see RandomToken.gen)
113
+ # @raise (see RandomToken.gen)
114
+ def get(length, options = {})
115
+ seeds = gen_seeds(options)[:seed]
116
+ token = (0...length).map{ seeds[rand(seeds.length)] }.join
117
+ end
118
+
119
+ # To generate a random token with a string format. Please see {file:README.rdoc} to get more detail usage and examples
120
+ # @param pattern [String]
121
+ # The string format pattern.
122
+ # @param options (see RandomToken.gen)
123
+ # @return (see RandomToken.gen)
124
+ # @raise (see RandomToken.gen)
125
+ def strf(pattern, options = {})
126
+ in_arg = false
127
+ result = ''
128
+ length = ''
129
+ pattern.split(//).each do |x|
130
+ if x == '%'
131
+ if in_arg
132
+ result << x * (length == "" ? 1 : length.to_i)
133
+ length = ''
134
+ in_arg = false
135
+ else
136
+ in_arg = true
137
+ end
138
+ elsif ('0'..'9').include?(x)
139
+ if in_arg
140
+ length << x
141
+ else
142
+ result << x
143
+ end
144
+ elsif STRF_ARG_MAP.keys.include?(x)
145
+ if in_arg
146
+ result << self.get((length == "") ? 1 : length.to_i,
147
+ STRF_ARG_MAP[x].merge(options))
148
+ length = ''
149
+ in_arg = false
150
+ else
151
+ result << x
152
+ end
153
+ else
154
+ if in_arg
155
+ raise RandomTokenError.new(:invalid_strf_pattern, pattern)
156
+ else
157
+ result << x
158
+ end
159
+ end
160
+ end
161
+ result
162
+ end
163
+
164
+ private
165
+
166
+ # To generate seeds according to the :seed options
167
+ def gen_seeds(opt)
168
+ opt_seed = opt[:seed]
169
+ default_opt = SEED_TYPES[:default]
170
+ if opt_seed == nil || opt_seed.is_a?(Symbol) || opt_seed.is_a?(Fixnum)
171
+ SEED_TYPES.each do |key, value|
172
+ if ([key] + value[:abbr]).include?(opt_seed)
173
+ opt.delete(:seed)
174
+ opt = default_opt.merge(value).merge(opt)
175
+ opt[:seed] = opt[:seed].map { |s| s.to_a }.flatten
176
+ return seed_modifier(opt)
177
+ end
178
+ end
179
+ raise RandomTokenError.new(:unknown_seed, opt_seed)
180
+ elsif opt_seed.is_a?(Array)
181
+ return seed_modifier(default_opt.merge(:case => :keep).merge(opt))
182
+ elsif opt_seed.is_a?(Hash)
183
+ seeds = opt_seed.to_a.map {|s| (s.first * s.last).split(//)}.flatten
184
+ return seed_modifier(default_opt.merge(opt).merge(:seed => seeds,
185
+ :support_case => false,
186
+ :support_friendly => false ))
187
+ else
188
+ raise RandomTokenError.new(:unknown_seed, opt_seed)
189
+ end
190
+ end
191
+
192
+ # To modify seeds according to the :case, :friendly and :mask options
193
+ def seed_modifier(opt)
194
+ if opt[:support_case]
195
+ case_opt = opt[:case] || opt[:default_case]
196
+ case case_opt
197
+ when :up, :u
198
+ cased_seed = opt[:seed].map { |s| s.upcase }
199
+ when :down, :d, :lower, :l
200
+ cased_seed = opt[:seed].map { |s| s.downcase }
201
+ when :mixed, :m
202
+ cased_seed = opt[:seed].map { |s| [s.upcase, s.downcase] }.flatten
203
+ else
204
+ # :keep, keep the seed case
205
+ cased_seed = opt[:seed]
206
+ end
207
+ opt[:seed] = cased_seed.uniq
208
+ else
209
+ raise RandomTokenError.new(:not_support_case, opt) if opt[:case] != nil
210
+ end
211
+ if opt[:support_friendly]
212
+ if opt[:friendly] || (opt[:friendly] == nil && opt[:mask])
213
+ masked_seed = opt[:seed].dup
214
+ mask = opt[:mask] || MASK
215
+ mask.each { |m| masked_seed.delete(m) }
216
+ opt[:seed] = masked_seed
217
+ elsif opt[:friendly] == false && opt[:mask]
218
+ raise RandomTokenError.new(:false_friendly_with_given_mask, opt)
219
+ end
220
+ else
221
+ if opt[:friendly] == true || opt[:mask] != nil
222
+ raise RandomTokenError.new(:not_support_friendly, opt)
223
+ end
224
+ end
225
+ raise RandomTokenError.new(:mask_remove_all_seeds, opt) if opt[:seed] == []
226
+ opt
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,67 @@
1
+ module RandomToken
2
+
3
+ # A customized exception for RandomToken
4
+ class RandomTokenError < StandardError
5
+
6
+ # Errors used in RandomToken
7
+ ERRORS = {
8
+ :unknown_seed => {
9
+ :value => 1,
10
+ :msg => "Unknown given seed"
11
+ },
12
+ :not_support_case => {
13
+ :value => 2,
14
+ :msg => "Case feature is not supported in this case, but the case option is given."
15
+ },
16
+ :not_support_friendly => {
17
+ :value => 3,
18
+ :msg => "Friendly feature is not supported in this case, but the friendly option is true."
19
+ },
20
+ :false_friendly_with_given_mask => {
21
+ :value => 4,
22
+ :msg => "The mask is given but the friendly option is false."
23
+ },
24
+ :invalid_strf_pattern => {
25
+ :value => 5,
26
+ :msg => "The given pattern is invalid."
27
+ },
28
+ :invalid_gen_arg => {
29
+ :value => 6,
30
+ :msg => "The given arg is invalid."
31
+ },
32
+ :mask_remove_all_seeds => {
33
+ :value => 7,
34
+ :msg => "The friendly mask removes all seeds."
35
+ }
36
+ }
37
+
38
+ attr_reader :code, :value, :msg, :info
39
+
40
+ # The RandomTokenError constructor.
41
+ # @param error [Fixnum, String]
42
+ # You can give a error number defined in the keys of {RandomToken::RandomTokenError::ERRORS} or a string message for internal usage.
43
+ # @param info [Hash]
44
+ # Anything you want to put in the info attribute of RandomTokenError.
45
+ def initialize(error, info = {})
46
+ @code = error
47
+ @info = info
48
+ if ERRORS.keys.include?(error)
49
+ @value = ERRORS[error][:value]
50
+ @msg = ERRORS[error][:msg]
51
+ elsif error.class.name == 'String'
52
+ @code = :internal
53
+ @value = 90000
54
+ @msg = error
55
+ else
56
+ @code = :internal
57
+ @value = 99999
58
+ @msg = "Internal Error"
59
+ end
60
+ end
61
+
62
+ # Override the message method to show more information in RandomTokenError
63
+ def message
64
+ "RandomTokenError(#{@code.to_s}): value = #{@value}, msg = #{@msg}, info = #{@info.inspect}"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module RandomToken
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'random_token/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "random_token"
7
+ spec.version = RandomToken::VERSION
8
+ spec.authors = ["Sibevin Wang"]
9
+ spec.email = ["sibevin@gmail.com"]
10
+ spec.description = %q{A simple way to generate a random token.}
11
+ spec.summary = <<-EOF
12
+ Use "gen" method to create a random token with a given length.
13
+
14
+ RandomToken.gen(8)
15
+ # "iUEFxcG2"
16
+
17
+ Some options can help to modify the token format.
18
+
19
+ RandomToken.gen(20, :seed => :alphabet, :friendly => true, :case => :up)
20
+ # "YTHJHTXKSSXTPLARALRH"
21
+
22
+ Use string format to create a random in the particular format.
23
+
24
+ RandomToken.gen("Give me a token %8?")
25
+ # "Give me a token 6HRQZp8O"
26
+
27
+ Please see "README" to get more details.
28
+ EOF
29
+ spec.homepage = "https://github.com/sibevin/random_token"
30
+ spec.license = "MIT"
31
+ spec.files = `git ls-files`.split($/)
32
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
33
+ spec.require_paths = ["lib"]
34
+ end
@@ -0,0 +1,45 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestCase < Test::Unit::TestCase
5
+ def test_get_should_create_a_random_with_upper_case_alphabets_or_numbers
6
+ length = 10000
7
+ token = RandomToken.get(length, :case => :up)
8
+ assert_match(/^[A-Z0-9]{#{length}}$/, token)
9
+ token = RandomToken.get(length, :case => :u)
10
+ assert_match(/^[A-Z0-9]{#{length}}$/, token)
11
+ end
12
+
13
+ def test_get_should_create_a_random_with_lower_case_alphabets_or_numbers
14
+ length = 10000
15
+ token = RandomToken.get(length, :case => :down)
16
+ assert_match(/^[a-z0-9]{#{length}}$/, token)
17
+ token = RandomToken.get(length, :case => :d)
18
+ assert_match(/^[a-z0-9]{#{length}}$/, token)
19
+ end
20
+
21
+ def test_get_should_not_support_case_feature_when_creating_binray_random
22
+ length = 10000
23
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :seed => :b, :case => :up) }
24
+ assert(e.code == :not_support_case)
25
+ end
26
+
27
+ def test_get_should_not_support_case_feature_when_creating_octal_random
28
+ length = 10000
29
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :seed => :o, :case => :up) }
30
+ assert(e.code == :not_support_case)
31
+ end
32
+
33
+ def test_get_should_use_upper_case_by_default_when_creating_hexdecimal_random
34
+ length = 10000
35
+ token = RandomToken.get(length, :seed => :h)
36
+ assert_match(/^[0-9A-F]*$/, token)
37
+ end
38
+
39
+ def test_get_should_keep_case_by_default_when_creating_random_with_given_seeds
40
+ length = 10000
41
+ seeds = ['a', 'B', 'c', 'D', 'e', 'F', 'g', 'H', 'i', 'J', 'k', 'L', 'm', 'N']
42
+ token = RandomToken.get(length, :seed => seeds)
43
+ assert_match(/^#{"[#{Regexp.escape(seeds.join)}]"}*$/, token)
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestFriendly < Test::Unit::TestCase
5
+ def test_get_should_not_create_a_random_including_masked_alphabets_or_numbers
6
+ length = 10000
7
+ token = RandomToken.get(length, :friendly => true)
8
+ assert((RandomToken::MASK - token.split(//).uniq) == RandomToken::MASK)
9
+ end
10
+
11
+ def test_get_should_not_support_friendly_feature_when_creating_binary_random
12
+ length = 10000
13
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :seed => :b, :friendly => true) }
14
+ assert(e.code == :not_support_friendly)
15
+ end
16
+
17
+ def test_get_should_not_support_friendly_feature_when_creating_octal_random
18
+ length = 10000
19
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :seed => :o, :friendly => true) }
20
+ assert(e.code == :not_support_friendly)
21
+ end
22
+
23
+ def test_get_should_not_support_friendly_feature_when_creating_hexadecimal_random
24
+ length = 10000
25
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :seed => :h, :friendly => true) }
26
+ assert(e.code == :not_support_friendly)
27
+ end
28
+
29
+ def test_get_should_support_friendly_feature_when_creating_random_with_given_seeds
30
+ length = 10000
31
+ seeds = ['a','b','c','d','e','0','1','2','3','4']
32
+ token = RandomToken.get(length, :seed => seeds, :friendly => true)
33
+ assert((token.split(//).uniq - RandomToken::MASK) == token.split(//).uniq)
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestHashSeed < Test::Unit::TestCase
5
+ def test_get_should_create_a_random_with_the_given_seeds
6
+ length = 10000
7
+ token = RandomToken.get(length, :seed => { 'a' => 1, 'b' => 2, 'c' => 3 })
8
+ assert_match(/^[a-c]{#{length}}$/, token)
9
+ end
10
+
11
+ def test_get_should_create_a_random_with_the_given_distribution_of_seeds
12
+ length = 1000000
13
+ token = RandomToken.get(length, :seed => { 'a' => 1, 'b' => 2, 'c' => 3 })
14
+ a_count = token.count('a')
15
+ b_count = token.count('b')
16
+ c_count = token.count('c')
17
+ assert_in_delta(b_count.to_f/(2*a_count), 1, 0.01)
18
+ assert_in_delta(c_count.to_f/(3*a_count), 1, 0.01)
19
+ end
20
+
21
+ def test_get_should_not_support_case_feature_when_given_the_hash_seed
22
+ length = 10000
23
+ e = assert_raise(RandomToken::RandomTokenError) {
24
+ RandomToken.get(length, :seed => { 'a' => 1, 'b' => 2, 'c' => 3 }, :case => :up)
25
+ }
26
+ assert(e.code == :not_support_case)
27
+ end
28
+
29
+ def test_get_should_not_support_friendly_feature_when_given_the_hash_seed
30
+ length = 10000
31
+ e = assert_raise(RandomToken::RandomTokenError) {
32
+ RandomToken.get(length, :seed => { 'a' => 1, 'b' => 2, 'c' => 3 }, :friendly => true)
33
+ }
34
+ assert(e.code == :not_support_friendly)
35
+ end
36
+ end
@@ -0,0 +1,10 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestLength < Test::Unit::TestCase
5
+ def test_get_should_create_a_given_length_random_string
6
+ length = 8
7
+ token = RandomToken.get(length)
8
+ assert_match(/^.{#{length}}$/, token)
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestMask < Test::Unit::TestCase
5
+ def test_get_should_use_given_mask
6
+ length = 10000
7
+ mask = ['a','b','c','d','e','0','1','2','3','4']
8
+ token = RandomToken.get(length, :mask => mask)
9
+ assert((token.split(//).uniq - mask) == token.split(//).uniq)
10
+ end
11
+
12
+ def test_get_should_raise_an_exception_if_mask_is_given_but_friendly_option_is_false
13
+ length = 10000
14
+ mask = ['a','b','c','d','e','0','1','2','3','4']
15
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :mask => mask,
16
+ :friendly => false) }
17
+ assert(e.code == :false_friendly_with_given_mask)
18
+ end
19
+
20
+ def test_get_should_raise_an_exception_if_mask_remove_all_seeds
21
+ length = 10000
22
+ seed = ['a']
23
+ mask = ['a']
24
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.get(length, :seed => seed,
25
+ :mask => mask) }
26
+ assert(e.code == :mask_remove_all_seeds)
27
+ end
28
+ end
@@ -0,0 +1,68 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestSeed < Test::Unit::TestCase
5
+ def test_get_should_create_a_random_with_alphabets_only
6
+ length = 10000
7
+ token = RandomToken.get(length, :seed => :a)
8
+ assert_match(/^[A-Za-z]*$/, token)
9
+ token = RandomToken.get(length, :seed => :alphabet)
10
+ assert_match(/^[A-Za-z]*$/, token)
11
+ token = RandomToken.get(length, :seed => :l)
12
+ assert_match(/^[A-Za-z]*$/, token)
13
+ token = RandomToken.get(length, :seed => :letter)
14
+ assert_match(/^[A-Za-z]*$/, token)
15
+ end
16
+
17
+ def test_get_should_create_a_random_with_numbers_only
18
+ length = 10000
19
+ token = RandomToken.get(length, :seed => :n)
20
+ assert_match(/^[0-9]*$/, token)
21
+ token = RandomToken.get(length, :seed => :number)
22
+ assert_match(/^[0-9]*$/, token)
23
+ token = RandomToken.get(length, :seed => 1)
24
+ assert_match(/^[0-9]*$/, token)
25
+ token = RandomToken.get(length, :seed => 10)
26
+ assert_match(/^[0-9]*$/, token)
27
+ end
28
+
29
+ def test_get_should_create_a_random_with_0_and_1_only
30
+ length = 10000
31
+ token = RandomToken.get(length, :seed => :b)
32
+ assert_match(/^[01]*$/, token)
33
+ token = RandomToken.get(length, :seed => :binary)
34
+ assert_match(/^[01]*$/, token)
35
+ token = RandomToken.get(length, :seed => 2)
36
+ assert_match(/^[01]*$/, token)
37
+ end
38
+
39
+ def test_get_should_create_a_random_with_octal_digits
40
+ length = 10000
41
+ token = RandomToken.get(length, :seed => :o)
42
+ assert_match(/^[0-7]*$/, token)
43
+ token = RandomToken.get(length, :seed => :oct)
44
+ assert_match(/^[0-7]*$/, token)
45
+ token = RandomToken.get(length, :seed => 8)
46
+ assert_match(/^[0-7]*$/, token)
47
+ end
48
+
49
+ def test_get_should_create_a_random_with_hexadecimal_digits
50
+ length = 10000
51
+ token = RandomToken.get(length, :seed => :h)
52
+ assert_match(/^[0-9A-F]*$/, token)
53
+ token = RandomToken.get(length, :seed => :hex)
54
+ assert_match(/^[0-9A-F]*$/, token)
55
+ token = RandomToken.get(length, :seed => 16)
56
+ assert_match(/^[0-9A-F]*$/, token)
57
+ end
58
+
59
+ def test_get_should_create_a_random_with_given_seeds
60
+ length = 10000
61
+ seeds = ['a', 'b', 'c', '1', '2', '3', '!', '@', '#', '$', '%',
62
+ '^', '&', '*', '(', ')', '-', '_', '=', '+', '{', '}',
63
+ '[', ']', '\\', '|', ';', ':', '\'', '"', ',', '<',
64
+ '.', '>', '/', '?', '`', '~']
65
+ token = RandomToken.get(length, :seed => seeds)
66
+ assert_match(/^#{"[#{Regexp.escape(seeds.join)}]"}*$/, token)
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestPattern < Test::Unit::TestCase
5
+ def test_get_should_create_a_random_with_alphabets
6
+ length = 10000
7
+ pattern = "===%#{length}A===%#{length}a===Aa==="
8
+ token = RandomToken.strf(pattern)
9
+ assert_match(/^===[A-Z]{#{length}}===[a-z]{#{length}}===Aa===$/, token)
10
+ end
11
+
12
+ def test_get_should_create_a_random_with_numbers
13
+ length = 10000
14
+ pattern = "===%#{length}n===n==="
15
+ token = RandomToken.strf(pattern)
16
+ assert_match(/^===[0-9]{#{length}}===n===$/, token)
17
+ end
18
+
19
+ def test_get_should_create_a_random_with_0_and_1
20
+ length = 10000
21
+ pattern = "===%#{length}b===b==="
22
+ token = RandomToken.strf(pattern)
23
+ assert_match(/^===[0-1]{#{length}}===b===$/, token)
24
+ end
25
+
26
+ def test_get_should_create_a_random_with_octal_digits
27
+ length = 10000
28
+ pattern = "===%#{length}o===o==="
29
+ token = RandomToken.strf(pattern)
30
+ assert_match(/^===[0-8]{#{length}}===o===$/, token)
31
+ end
32
+
33
+ def test_get_should_create_a_random_with_hexadecimal_digits
34
+ length = 10000
35
+ pattern = "===%#{length}h===%#{length}H===hH==="
36
+ token = RandomToken.strf(pattern)
37
+ assert_match(/^===[0-9a-f]{#{length}}===[0-9A-F]{#{length}}===hH===$/, token)
38
+ end
39
+
40
+ def test_get_should_create_a_random_with_alphabets_and_numbers
41
+ length = 10000
42
+ pattern = "===%#{length}x===%#{length}X===xX==="
43
+ token = RandomToken.strf(pattern)
44
+ assert_match(/^===[0-9a-z]{#{length}}===[0-9A-Z]{#{length}}===xX===$/, token)
45
+ end
46
+
47
+ def test_get_should_create_a_random_with_given_format
48
+ length = 10000
49
+ pattern = "===%#{length}?===?==="
50
+ token = RandomToken.strf(pattern)
51
+ assert_match(/^===.{#{length}}===\?===$/, token)
52
+ end
53
+
54
+ def test_get_should_raise_an_exception_if_the_given_pattern_is_invalid
55
+ pattern = "===%123==="
56
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.strf(pattern) }
57
+ assert(e.code == :invalid_strf_pattern)
58
+ end
59
+ end
@@ -0,0 +1,11 @@
1
+ require "test/unit"
2
+ require "random_token"
3
+
4
+ class TestPercent < Test::Unit::TestCase
5
+ def test_get_should_create_a_random_with_percent_signs
6
+ length = 10000
7
+ pattern = "===%#{length}%===%%==="
8
+ token = RandomToken.strf(pattern)
9
+ assert_match(/^===%{#{length}}===%===$/, token)
10
+ end
11
+ end
data/test/test_all.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "random_token"
6
+ require "test_get"
7
+ require "test_strf"
8
+ require "test_gen"
data/test/test_gen.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "random_token"
6
+
7
+ class TestGen < Test::Unit::TestCase
8
+ def test_gen_should_raise_an_exception_if_the_given_arg_is_invalid
9
+ e = assert_raise(RandomToken::RandomTokenError) { RandomToken.gen(nil) }
10
+ assert(e.code == :invalid_gen_arg)
11
+ end
12
+ end
data/test/test_get.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "random_token"
6
+ require "get/test_length"
7
+ require "get/test_case"
8
+ require "get/test_friendly"
9
+ require "get/test_seed"
10
+ require "get/test_mask"
11
+ require "get/test_hash_seed"
@@ -0,0 +1 @@
1
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
data/test/test_strf.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "random_token"
6
+ require "strf/test_pattern"
7
+ require "strf/test_percent"
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: random_token
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sibevin Wang
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-28 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple way to generate a random token.
15
+ email:
16
+ - sibevin@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE.txt
22
+ - README.md
23
+ - lib/random_token.rb
24
+ - lib/random_token/random_token_error.rb
25
+ - lib/random_token/version.rb
26
+ - random_token.gemspec
27
+ - test/get/test_case.rb
28
+ - test/get/test_friendly.rb
29
+ - test/get/test_hash_seed.rb
30
+ - test/get/test_length.rb
31
+ - test/get/test_mask.rb
32
+ - test/get/test_seed.rb
33
+ - test/strf/test_pattern.rb
34
+ - test/strf/test_percent.rb
35
+ - test/test_all.rb
36
+ - test/test_gen.rb
37
+ - test/test_get.rb
38
+ - test/test_helper.rb
39
+ - test/test_strf.rb
40
+ homepage: https://github.com/sibevin/random_token
41
+ licenses:
42
+ - MIT
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.25
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: ! 'Use "gen" method to create a random token with a given length. RandomToken.gen(8)
65
+ # "iUEFxcG2" Some options can help to modify the token format. RandomToken.gen(20,
66
+ :seed => :alphabet, :friendly => true, :case => :up) # "YTHJHTXKSSXTPLARALRH" Use
67
+ string format to create a random in the particular format. RandomToken.gen("Give
68
+ me a token %8?") # "Give me a token 6HRQZp8O" Please see "README" to get more details.'
69
+ test_files:
70
+ - test/get/test_case.rb
71
+ - test/get/test_friendly.rb
72
+ - test/get/test_hash_seed.rb
73
+ - test/get/test_length.rb
74
+ - test/get/test_mask.rb
75
+ - test/get/test_seed.rb
76
+ - test/strf/test_pattern.rb
77
+ - test/strf/test_percent.rb
78
+ - test/test_all.rb
79
+ - test/test_gen.rb
80
+ - test/test_get.rb
81
+ - test/test_helper.rb
82
+ - test/test_strf.rb
83
+ has_rdoc: