module RandomToken
Constants
- ALPHABETS
The alphabet seed
- DEFAULT_OPT
The default option definition
- MASK
The default friendly mask
- NUMBERS
The number seed
- SEED_TYPES
The default seeds definition
- STRF_ARG_MAP
The directives used in the format string
- SUPPORTED_OPTS
The supported options
- VERSION
Public Class Methods
The major method to generate a random token. @param arg [Fixnum, String]
To give a token length or the string format for generating token.
@param options [Hash]
The options to modify the token. Three options :seed, :friendly and :case are supported. Please see {file:README} to get more examples
@return [String]
The generated token.
@raise [RandomTokenError]
Please see {RandomToken::RandomTokenError}
# File lib/random_token.rb, line 118 def gen(arg, options = {}) arg_dispatcher(arg, options) do |length, seeds| (0...length).map{ seeds[SecureRandom.random_number(seeds.length)] }.join end end
A convenient method to generate a friendly token. It would call {RandomToken.gen} with :friendly => true option. @param arg (see RandomToken.gen
) @param options (see RandomToken.gen
) @return (see RandomToken.gen
) @raise (see RandomToken.gen
)
# File lib/random_token.rb, line 129 def genf(arg, options = {}) gen(arg, { :friendly => true }.merge(options)) end
An old method for downward compatibility and it should be discarded. Use “gen” instead. @param arg (see RandomToken.gen
) @param options (see RandomToken.gen
) @return (see RandomToken.gen
) @raise (see RandomToken.gen
)
# File lib/random_token.rb, line 153 def get(arg, options = {}) gen(arg, options) end
An old method for downward compatibility and it should be discarded. Use “gen” instead. @param arg (see RandomToken.gen
) @param options (see RandomToken.gen
) @return (see RandomToken.gen
) @raise (see RandomToken.gen
)
# File lib/random_token.rb, line 163 def strf(arg, options = {}) gen(arg, options) end
Private Class Methods
Decide how to generate/count token according to the arg type.
# File lib/random_token.rb, line 170 def arg_dispatcher(arg, options, count = false) options = check_opt(options) unless block_given? raise RandomTokenError.new( "No block is given when calling arg_dispatcher.") end if arg.is_a?(Integer) run_by_length(arg, options) do |length, seeds| yield(length, seeds) end elsif arg.is_a?(String) result = run_by_pattern(arg, options) do |length, seeds| yield(length, seeds) end return result.join # TODO: Add count feature =begin if count return result.delete_if { |x| x.is_a?(String) }.inject(0, :*) else return result.join end =end else raise RandomTokenError.new(:invalid_gen_arg, arg) end end
Check options
# File lib/random_token.rb, line 259 def check_opt(opts) SUPPORTED_OPTS.each do |key, value| if opts[key] && opts.keys.include?(value[:abbr]) raise RandomTokenError.new(:duplicated_option, opts) end opts.merge!(key => opts[value[:abbr]]) if opts[value[:abbr]] if value[:value] && opts[key] && !value[:value].include?(opts[key]) raise RandomTokenError.new(:invalid_option_value, opts) end end opts end
Generate seeds according to the :seed options
# File lib/random_token.rb, line 273 def gen_seeds(opt) opt_seed = opt[:seed] default_opt = SEED_TYPES[:default] if opt_seed == nil || opt_seed.is_a?(Symbol) || opt_seed.is_a?(Fixnum) SEED_TYPES.each do |key, value| if ([key] + value[:abbr]).include?(opt_seed) opt.delete(:seed) opt = default_opt.merge(value).merge(opt) opt[:seed] = opt[:seed].map { |s| s.to_a }.flatten return seed_modifier(opt) end end raise RandomTokenError.new(:unknown_seed, opt_seed) elsif opt_seed.is_a?(Array) return seed_modifier(default_opt.merge(:case => :keep).merge(opt)) elsif opt_seed.is_a?(Hash) seeds = opt_seed.to_a.map {|s| (s.first * s.last).split(//)}.flatten return seed_modifier(default_opt. merge(opt). merge(:seed => seeds, :support_case => false, :support_friendly => false )) else raise RandomTokenError.new(:unknown_seed, opt_seed) end end
Generate/count token with a given length.
# File lib/random_token.rb, line 199 def run_by_length(length, options) if block_given? final_opt = gen_seeds(options) seeds = final_opt[:seed] length = length * final_opt[:byte_mult] if final_opt[:byte] yield(length, seeds) else raise RandomTokenError.new( "No block is given when calling run_by_length.") end end
Generate/count token with a format string.
# File lib/random_token.rb, line 212 def run_by_pattern(pattern, options = {}) unless block_given? raise RandomTokenError.new( "No block is given when calling run_by_pattern.") end if options[:byte] raise RandomTokenError.new(:format_not_support_byte, options) end in_arg = false result = [] length = '' pattern.split(//).each do |x| if x == '%' if in_arg result << x * (length == "" ? 1 : length.to_i) length = '' in_arg = false else in_arg = true end elsif ('0'..'9').include?(x) if in_arg length << x else result << x end elsif STRF_ARG_MAP.keys.include?(x) if in_arg seeds = gen_seeds(STRF_ARG_MAP[x].merge(options))[:seed] result << yield((length == "") ? 1 : length.to_i, seeds) length = '' in_arg = false else result << x end else if in_arg raise RandomTokenError.new(:invalid_strf_pattern, pattern) else result << x end end end result end
Modify seeds according to the :case, :friendly and :mask options
# File lib/random_token.rb, line 301 def seed_modifier(opt) if opt[:support_case] case_opt = opt[:case] || opt[:default_case] case case_opt when :up, :u cased_seed = opt[:seed].map { |s| s.upcase } when :down, :d, :lower, :l cased_seed = opt[:seed].map { |s| s.downcase } when :mixed, :m cased_seed = opt[:seed].map { |s| [s.upcase, s.downcase] }.flatten else # :keep, keep the seed case cased_seed = opt[:seed] end opt[:seed] = cased_seed.uniq else raise RandomTokenError.new(:not_support_case, opt) if opt[:case] != nil end if opt[:support_friendly] if opt[:friendly] || (opt[:friendly] == nil && opt[:mask]) masked_seed = opt[:seed].dup mask = opt[:mask] || MASK mask.each { |m| masked_seed.delete(m) } opt[:seed] = masked_seed elsif opt[:friendly] == false && opt[:mask] raise RandomTokenError.new(:false_friendly_with_given_mask, opt) end else if opt[:friendly] == true || opt[:mask] != nil raise RandomTokenError.new(:not_support_friendly, opt) end end raise RandomTokenError.new(:mask_remove_all_seeds, opt) if opt[:seed] == [] if opt[:support_byte] == false && opt[:byte] != nil raise RandomTokenError.new(:not_support_byte, opt) end opt end