ランダムかつ重複しないように文字列を生成する(Ruby)
あることのために必要だったので、複数の文字列をランダムかつ重複しないように生成するメソッドを書いてみました。
こんな感じです。
$ irb irb(main):001:0> require_relative "generate_random_strings" => true irb(main):002:0> Utils.generate_random_strings(40) => ["kk", "cm", "aq", "vf", "zf", "uh", "qv", "pv", "bb", "jp", "td", "ri", "mr", "hq", "gy", "pe", "ta", "ot", "ob", "km", "zu", "cz", "sf", "qo", "zt", "uq", "tc", "fd", "xq", "ki", "po", "w", "dj", "ks", "mw", "am", "zr", "az", "iy", "gv"]
重複しない 40個の文字列(アルファベット小文字)が生成されて Array で返ります。文字の長さは最小になるようになっているので、長さ 1 と 2 の文字列が入り混じっています。
文字列の長さを指定して呼ぶこともできます。
irb(main):003:0> Utils.generate_random_strings(40, 4) => ["bakz", "aipi", "prgo", "cwfw", "qqkv", "lgtt", "neid", "jjjz", "cjst", "tdfd", "sguf", "nkqk", "bvpl", "tldk", "qszi", "qfvj", "mnjy", "epsd", "abix", "ldap", "lijm", "jqzl", "gclu", "fxxe", "tcxc", "rayu", "rcsn", "aitp", "focj", "ngxd", "ouxc", "reze", "svxc", "ppaz", "roeb", "qgdt", "mhdw", "ewap", "fxjb", "mmrx"]
長さ 4 のランダムな文字列が 40個返りました。
コード。
generate_random_strings.rb
module Utils def repeated_permutation(a, b) a ** b end def generate_random_strings(num, string_length = nil) table = [*"a".."z"] limit = [0, 26, 702, 18278, 475254, 12356630] result = [] generate_string1 = ->(n, l) { st = "" l.times do a, n = n % 26, n / 26 st = table[a] + st end st } generate_string2 = ->(n) { idx = limit.find_index {|i| i > n} generate_string1.(n - limit[idx - 1], idx) } if string_length and 26 < string_length raise "Given length of strings too big." end num_table = Set.new if string_length n = Utils.repeated_permutation(26, string_length) raise "Given length of strings too small." if n < num while num_table.size < num num_table << rand(n) end num_table.each {|i| result << generate_string1.(i, string_length)} else idx = limit.find_index {|i| i >= num} raise "Result Array too big." unless idx while num_table.size < num num_table << rand(limit[idx]) end num_table.each {|i| result << generate_string2.(i)} end result end module_function :repeated_permutation, :generate_random_strings end
Gem 化
Gem 'kaki-utils' に同梱しました。$ gem install kaki-utils や Bundler でインストールできます。
$ bundle exec irb irb(main):001:0> require 'kaki/utils' => true irb(main):002:0> Utils.generate_random_strings(40) => ["qv", "kj", "wf", "ch", "ds", "hp", "ro", "oj", "xa", "dz", "vv", "zz", "fh", "rf", "tr", "gw", "cf", "yx", "ep", "pr", "tl", "sn", "ar", "ao", "ij", "pl", "my", "gy", "sk", "yk", "to", "hq", "wj", "vf", "jh", "pu", "cg", "gq", "wu", "dx"]
みたいな感じ。