2017-09-15 1 views
2

서로 일치 할 수없고 고유 코드가 될 수있는 두 개의 코드 목록에 대해 많은 고유 코드를 생성해야했습니다. 길이는 7 자 여야합니다.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 
    

    사람이 더 나은 솔루션이 있습니까 : 여기

내가 사용하는 코드입니다?

+0

'로트'란 무엇입니까? –

+0

Include 대신 이진 검색을 사용 하시겠습니까? 이는 O (n) 시간 복잡도입니다. 이진 검색 [here] (https://ruby-doc.org/core-2.4.1/Array.html#method-i-bsearch)을 사용하여 중복을 확인할 수 있습니다 –

답변

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 초 정도 걸립니다.

+2

유일성 검사를 피하기 위해'Set' 사용하기 매우 과소 평가 된 멋진 트릭 이죠? – mudasobwa

+1

@mudasobwa 또는 '값 => 참'쌍인 '해시'. ('Set'이 아마 두포 아래에 있고 체크하지 않은 것입니다) – Stefan

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 이제 사용자의 요구에 충분 약 1,333,000 고유의 토큰이 포함되어 있습니다.

관련 문제