2015-09-21 14 views
8

Tôi đã xem xét các câu hỏi tương tự về cách tạo số ngẫu nhiên trong python. Ví dụ: Similar Question - nhưng tôi không có vấn đề rằng hàm ngẫu nhiên trả về cùng một giá trị mỗi lần.random.choice() trả về cùng một giá trị trong cùng một giây, làm thế nào để tránh nó?

Trình tạo ngẫu nhiên của tôi hoạt động tốt, vấn đề là nó trả về cùng một giá trị khi gọi hàm tại, điều tôi nghĩ, cùng một giây không thể xóa được.

Mã của tôi trông như thế này

def getRandomID(): 
    token = '' 
    letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" 
    for i in range(1,36): 
     token = token + random.choice(letters) 
    return token 

Như tôi đã đề cập chức năng này trả về giá trị khác nhau khi được gọi ở trên thời điểm khác nhau nhưng trả về giá trị tương tự khi gọi hàm cùng một lúc. Làm cách nào để tránh sự cố này?

Tôi sử dụng chức năng này trong máy chủ back-end để tạo ID duy nhất cho người dùng ở đầu trước để chèn vào cơ sở dữ liệu để tôi không thể kiểm soát khoảng thời gian khi điều này xảy ra. Tôi phải có mã thông báo ngẫu nhiên để ánh xạ người dùng trong cơ sở dữ liệu để có thể chèn chúng một cách chính xác với hàng đợi trong cơ sở dữ liệu.

+0

giống như nó trả lại cùng một id khi được gọi bởi hai người dùng cùng một lúc ?? – Hackaholic

+9

Tôi khuyên bạn nên sử dụng 'uuid' để tạo id người dùng ngẫu nhiên. – hjpotter92

+0

Hackaholic - chính xác, nó trả về cùng một "mã thông báo" giống như chuỗi ký tự ngẫu nhiên khi được gọi bởi hai người dùng. –

Trả lời

4

Bạn có thể có thể cải thiện tình hình bằng cách sử dụng random.SystemRandom() như sau:

import random 

sys_random = random.SystemRandom() 

def getRandomID(): 
    token = '' 
    letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" 
    for i in range(1,36): 
     token = token + sys_random.choice(letters) 
    return token 

print getRandomID() 

này cố gắng sử dụng os.urandom() chức năng mà tạo ra số ngẫu nhiên từ các nguồn được cung cấp bởi hệ điều hành.

+0

Tôi nghĩ điều này đã giải quyết được vấn đề ngay từ cái nhìn đầu tiên. Tôi sẽ cố gắng thực hiện một thử nghiệm quy mô lớn hơn, nơi tôi có thể xác nhận rằng giải pháp hoạt động! –

1
def getRandomID(n): 

    import datetime 
    import random 

    random.seed(datetime.datetime.now()) 

    letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" 

    idList = [ ''.join([random.choice(letters) for j in range(1,36)]) for i in range(n)] 

    return idList 

kịch bản này trong các thử nghiệm thứ 3 của 10 triệu id lần nữa đã làm cho họ tất cả độc đáo

thay đổi vòng lặp for để liệt kê hiểu đã tăng tốc khá một chút.

>>> listt = getRandomID(10000000) 
>>> print(len(listt)) 
10000000 

>>> sofIds = set(listt) 
>>> print(len(sofIds)) 
10000000 

kịch bản này sử dụng hoán vị với sự lặp lại: 62 chọn 36, tổng lý thuyết số id là khá lớn đó là pow (62,36)

59720078628458064562952815512525677808980550940333281573339136 
+0

Vui lòng xem xét chỉnh sửa bài đăng của bạn để thêm giải thích thêm về mã của bạn và tại sao nó sẽ giải quyết vấn đề. Một câu trả lời mà hầu hết chỉ chứa mã (ngay cả khi nó hoạt động) thường không giúp OP hiểu được vấn đề của họ. Từ những gì tôi có thể thấy, điều này là dư thừa mặc dù vì đây là những gì (tôi tin) Python thường sử dụng làm cơ sở cho hạt giống của nó. Và ngay cả khi nó không, điều này sẽ vẫn cung cấp cùng một hạt giống cùng một lúc dẫn đến cùng một đầu ra. – SuperBiasedMan

+0

Bạn không muốn gọi 'random.seed' từ bên trong thường trình tạo ra các số ngẫu nhiên. Bạn sẽ (đôi khi, không xác định) kết thúc với cùng một giá trị quay lại từ 'datetime.now' trong các cuộc gọi tiếp theo, điều này sẽ gây ra' random.choice' để trả về các chuỗi giống hệt nhau. –

1

Một lựa chọn khác sẽ được cập nhật hạt giống với kết quả trước đó để có chuỗi giả ngẫu nhiên. Một lựa chọn sẽ là kết quả XOR old_seed hoặc chỉ là kết quả.

Các vấn đề liên quan