在Ruby中生成许多独特的令牌

时间:2017-09-15 07:50:38

标签: arrays ruby performance set unique

我需要为两个代码列表生成许多唯一代码,这些代码彼此不匹配并且是唯一代码。 它的长度必须是七个字符。

但是我对我的最终解决方案不满意,我必须让他彻夜难眠。

  • 我本来希望使用一个集合(因为集合比数组更快),但是我无法将所选集合中的集合分成两部分,就像我可以使用数组一样。

    < / LI>
  • 我想要并行化标记创建,但它会暗示管理共享代码数组以检查unicity,以及所涉及的所有锁定问题。

以下是我使用的代码:

# n is the token length, quantity the number of tokens I want.
def gen_codes(n=7, quantity=10)
  tokens = []
  quantity.times do |q|
    token = [*('a'..'z'), *('A'..'Z'), *(0..9)].sample(7).join
    while tokens.include?(token)
      token = [*('a'..'z'), *('A'..'Z'), *(0..9)].sample(7).join
    end
    tokens << token
  end
  tokens
end

CODES1 = 750e3.to_i
CODES2 = 250e3.to_i

puts "Generating codes"

codes = gen_codes(7, CODES1+CODES2)
codes2 = codes[0, CODES2]
codes1 = codes[CODES2, CODES1]

File.open('codes1.txt', 'w+') do |f|
  f.puts codes1
end

File.open('codes2.txt', 'w+') do |f|
  f.puts codes2
end

有没有人有更好的解决方案?

2 个答案:

答案 0 :(得分:4)

这应该有效:

require 'set'

alphabet = [*('a'..'z'), *('A'..'Z'), *(0..9)]

CODES1 = 750_000
CODES2 = 250_000

set = Set.new
set << alphabet.sample(7).join until set.size == CODES1 + CODES2
codes = set.to_a

codes1 = codes[0...CODES1]
codes2 = codes[CODES1..-1]

File.write('codes1.txt', codes1)
File.write('codes2.txt', codes2)

我的系统大约需要4秒钟。

答案 1 :(得分:0)

如果令牌中包含A-Z, a-z, 0-9, “+”, “/” and “=”,则可以使用SecureRandom。它快速随机:

require 'set'
require 'securerandom'

length = 7
total = 1_000_000
batch = 1000

tokens = Set.new
(total/batch).times do
  SecureRandom.base64(batch*length).scan(/.{#{length}}/).each do |token|
    tokens << token
  end
end

tokens现在包含大约1333000个独特令牌,这足以满足您的需求。