在 Ruby 中生成大量独特的令牌
Generating a LOT of unique tokens in Ruby
我需要为两个代码列表生成很多唯一代码,它们不能相互匹配并且是唯一代码。
它的长度必须是七个字符。
但我对我的最终解决方案不满意,我不得不让 运行 整晚。
我本来想使用集合(因为集合比数组快),但我不能像使用数组那样在所选索引处将集合分成两部分。
我想并行化令牌创建,但这意味着管理共享代码数组以检查唯一性,以及所有涉及的锁问题。
这是我使用的代码:
# 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
有没有人有更好的解决方案?
这应该有效:
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 秒。
如果令牌中有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 个独特的令牌,这足以满足您的需求。
我需要为两个代码列表生成很多唯一代码,它们不能相互匹配并且是唯一代码。 它的长度必须是七个字符。
但我对我的最终解决方案不满意,我不得不让 运行 整晚。
我本来想使用集合(因为集合比数组快),但我不能像使用数组那样在所选索引处将集合分成两部分。
我想并行化令牌创建,但这意味着管理共享代码数组以检查唯一性,以及所有涉及的锁问题。
这是我使用的代码:
# 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
有没有人有更好的解决方案?
这应该有效:
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 秒。
如果令牌中有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 个独特的令牌,这足以满足您的需求。