2012-06-15 32 views
5

Mỗi đối tượng người dùng trong cơ sở dữ liệu của tôi có ID gia tăng (1, 2, 3, ...). URL để xem tiểu sử của người dùng chứa ID của đối tượng người dùng; ví dụ. http://www.example.com/users/1. Bằng cách này, mọi người có thể thấy có bao nhiêu người dùng trên trang web, tốc độ phát triển của userbase nhanh như thế nào. Tôi không muốn cung cấp thông tin đó.Cách tính ID cố định độ dài cố định tương tự như YouTube (ví dụ: 2WNrx2jq184)

Tôi muốn chuyển đổi ID gia tăng thành chuỗi dài cố định ở định dạng Base58, vì vậy URL sẽ trông giống như http://www.example.com/users/2WNrx2jq184 Ngoài ra, tôi cần chức năng đảo ngược chuyển đổi chuỗi trở lại ID ban đầu. Chức năng đảo ngược không nên dễ dàng để đảo ngược kỹ sư.

Mã Python tốt nhất tôi tìm thấy cho mục đích này là https://github.com/JordanReiter/django-id-obfuscator. Nó rất tốt, nhưng trong một số trường hợp, nó thêm một ký tự 0 và/hoặc ., dẫn đến các chuỗi không nằm trong Base58 và không có độ dài cố định. (Xem utils.py dòng 24 và 29.)

Làm cách nào tôi có thể cải thiện django-id-obfuscator để tạo ID cố định dài 58 hoặc làm cách nào để tạo ID bị xáo trộn bằng Python?

+1

Tôi đoán bạn muốn tránh tạo ra một số ngẫu nhiên và lưu trữ tài liệu tham khảo của nó để ID thực tế ở đâu đó trong kho dữ liệu? – Groo

+0

https://github.com/JordanReiter/django-id-obfuscator/blob/master/id_obfuscator/base58.py - điều này không giống như chứa '0' hoặc' .'. – eumiro

+1

@eumiro https://github.com/JordanReiter/django-id-obfuscator/blob/master/id_obfuscator/utils.py - nó xảy ra ở đây – Korneel

Trả lời

5

Nếu bạn muốn thực hiện đúng việc này, hãy lấy ID người dùng của bạn, dán nó với số 0 đứng đầu, sau đó mã hóa nó với cái gì đó như AES và mã hóa kết quả với base58. Để lấy lại ID, chỉ cần giải mã, giải mã và int() kết quả.

Vì vậy, để mã hóa:

>>> from Crypto.Cipher import AES 
>>> import base64 
>>> obj = AES.new('yoursecretkeyABC') 
>>> x = base64.encodestring(obj.encrypt("%016d"%1)) 
>>> x 
'tXDxMg1YGb1i0V29yCCBWg==\n' 

và giải mã

>>> int(obj.decrypt(base64.decodestring(x))) 
1 

Nếu bạn có thể sống với crypto yếu, bạn cũng có thể chỉ đơn giản là xor ID đệm với một chìa khóa:

>>> key = [33, 53, 2, 42] 
>>> id = "%04d" % 1 
>>> x = ''.join([chr(a^ord(b)) for a, b in zip(key, id)]) 
>>> x 
'\x11\x052\x1b' 
>>> int(''.join([chr(a^ord(b)) for a, b in zip(key, x)])) 
1 

Nhưng điều này kém an toàn hơn nhiều vì bạn không bao giờ nên sử dụng cùng một OTP cho nhiều thư. Ngoài ra, hãy đảm bảo khóa có độ dài bằng với ID đệm của bạn.

+0

https://en.bitcoin.it/wiki/Base58Check_encoding – StefanNch

+0

@StefanNch http://gitorious.org/bitcoin/python-base58/blobs/master/base58.py Tôi nghĩ rằng đây là những gì tôi cần để thay thế base64 với base58 – Korneel

+0

Bạn có nghĩ rằng chi phí của hoạt động này (base58 decrypt + AES giải mã) để chuyển đổi ID obfuscated trở lại ID ban đầu là hợp lý chỉ để ẩn chuỗi ID? Liệu hoạt động giải mã có được tối ưu hóa với chi phí của hoạt động mã hóa không? – Korneel

0

Đây là một câu hỏi cũ mà tôi tình cờ gặp phải. Gần đây tôi đã tìm thấy hashids Thư viện mà giải quyết vấn đề này và có sẵn cho một loạt các ngôn ngữ lập trình:

http://hashids.org

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