random_token 1.0.0

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