Nếu tôi đọc chính xác câu hỏi của bạn, bạn muốn tạo một số mã thông báo nhận dạng tùy ý phải có tối đa 21 ký tự. Nó có cần phải có khả năng chống đoán cao không? Ví dụ bạn đưa ra không phải là "mạnh mẽ về mặt sắc thái" ở chỗ nó có thể được đoán bằng cách tìm kiếm ít hơn 1/2 của toàn bộ không gian phím có thể.
Bạn không nói nếu các ký tự có thể là tất cả 256 ký tự ASCII, hoặc nếu nó cần được giới hạn, ví dụ, ASCII có thể in (33-127, bao gồm) hoặc phạm vi nhỏ hơn.
Có mô-đun Python được thiết kế cho UUID s (Số nhận dạng duy nhất của Đại học). Bạn có thể muốn uuid4 tạo ra một UUID ngẫu nhiên và sử dụng hỗ trợ hệ điều hành nếu có (trên Linux, Mac, FreeBSD và các khả năng khác).
>>> import uuid
>>> u = uuid.uuid4()
>>> u
UUID('d94303e7-1be4-49ef-92f2-472bc4b4286d')
>>> u.bytes
'\xd9C\x03\xe7\x1b\xe4I\xef\x92\xf2G+\xc4\xb4(m'
>>> len(u.bytes)
16
>>>
16 byte ngẫu nhiên là rất unguessable, và không có nhu cầu sử dụng đầy đủ 21 byte API của bạn cho phép, nếu tất cả các bạn muốn là phải có một định danh đục unguessable.
Nếu bạn không thể sử dụng các byte thô như vậy, đó có thể là một ý tưởng tồi vì khó sử dụng trong nhật ký và các thông báo gỡ lỗi khác và khó so sánh hơn bằng mắt, sau đó chuyển đổi byte thành một thứ dễ đọc hơn, như sử dụng mã hóa base-64, với kết quả được cắt nhỏ xuống 21 (hoặc bất kỳ) byte nào:
>>> u.bytes.encode("base64")
'2UMD5xvkSe+S8kcrxLQobQ==\n'
>>> len(u.bytes.encode("base64"))
25
>>> u.bytes.encode("base64")[:21]
'2UMD5xvkSe+S8kcrxLQob'
>>>
Điều này mang lại cho bạn chuỗi chuỗi ngẫu nhiên có độ dài cực kỳ cao 21.
Bạn có thể không thích '+' hoặc '/' có thể nằm trong chuỗi base-64, vì không thoát đúng cách có thể ảnh hưởng đến URL. Vì bạn đã nghĩ để sử dụng "ngẫu nhiên 3 ký tự", tôi không nghĩ rằng đây là một lo lắng của bạn. Nếu có, bạn có thể thay thế các ký tự đó bằng một thứ khác ('-' và '.' Có thể hoạt động) hoặc xóa chúng nếu có.
Như những người khác đã chỉ ra, bạn có thể sử dụng .encode ("hex") và nhận được hex tương đương, nhưng đó chỉ là 4 bit ngẫu nhiên/ký tự * 21 ký tự tối đa cho bạn 84 bit ngẫu nhiên thay vì gấp đôi. Mỗi bit tăng gấp đôi keyspace của bạn, làm cho không gian tìm kiếm lý thuyết nhiều, nhỏ hơn nhiều. Với hệ số 2E24 nhỏ hơn.
Không gian phím của bạn vẫn có kích thước 2E24, ngay cả với mã hóa hex, vì vậy tôi nghĩ rằng đó là một mối quan tâm lý thuyết. Tôi sẽ không lo lắng về những người thực hiện các cuộc tấn công bạo lực đối với hệ thống của bạn.
Sửa:
P.S .: Các chức năng sử dụng uuid.uuid4 libuuid nếu có. Điều đó có entropy của nó từ os.urandom (nếu có) nếu không từ thời điểm hiện tại và địa chỉ MAC ethernet cục bộ. Nếu libuuid không có sẵn thì hàm uuid.uuid4 lấy các byte trực tiếp từ os.urandom (nếu có) nếu không nó sẽ sử dụng mô-đun ngẫu nhiên. Các mô-đun ngẫu nhiên sử dụng một hạt giống mặc định dựa trên os.urandom (nếu có) nếu không một giá trị dựa trên thời gian hiện tại. Probing diễn ra cho mọi cuộc gọi chức năng, vì vậy nếu bạn không có os.urandom thì chi phí sẽ lớn hơn một chút so với bạn mong đợi.
Gửi tin nhắn về nhà? Nếu bạn biết bạn có os.urandom thì bạn có thể làm
os.urandom(16).encode("base64")[:21]
nhưng nếu bạn không muốn lo lắng về tính khả dụng thì hãy sử dụng mô-đun uuid.
Bạn phải suy nghĩ SHA1. MD5 là 32 chữ số thập lục phân. – kmkaplan