2012-06-15 5 views
5

Cada objeto de usuario en mi base de datos tiene una ID incremental (1, 2, 3, ...). La URL para ver el perfil de un usuario contiene la ID del objeto del usuario; p.ej. http://www.example.com/users/1. De esta forma, todos pueden ver cuántos usuarios hay en el sitio web, qué tan rápido crece la base de usuarios, etc. No quiero dar esa información.Cómo calcular una identificación ofuscada corta de longitud fija similar a YouTube (por ejemplo, 2WNrx2jq184)

Me gustaría convertir el ID incremental a una cadena de longitud fija en formato Base58, por lo que la URL se vería como http://www.example.com/users/2WNrx2jq184 Además, necesito la función inversa que convierte la cadena de nuevo a la ID original. La función inversa no debe ser fácil de aplicar ingeniería inversa.

El mejor código de Python que encontré para este propósito es https://github.com/JordanReiter/django-id-obfuscator. Es muy bueno, pero en algunos casos agrega un carácter 0 y/o ., lo que conduce a cadenas que no están en Base58 y que no son de longitud fija. (Ver utils.py líneas 24 y 29.)

¿Cómo puedo mejorar django-id-Ofuscador a resultar en base58 de longitud fija identificadores ofuscado, o cómo puedo crear tales identificaciones ofuscado en Python?

+1

supongo que se quiere evitar la creación de un número aleatorio y el almacenamiento de su referencia a la ID real en algún lugar de ¿la base de datos? – Groo

+0

https://github.com/JordanReiter/django-id-obfuscator/blob/master/id_obfuscator/base58.py - esto no parece contener '0' o' .'. – eumiro

+1

@eumiro https://github.com/JordanReiter/django-id-obfuscator/blob/master/id_obfuscator/utils.py - sucede aquí – Korneel

Respuesta

5

Si desea hacer esto correctamente, tome su ID de usuario, empújela con ceros a la izquierda, luego encripte con algo como AES y codifique el resultado con base58. Para recuperar la ID, simplemente decodifique, descifre y int() el resultado.

Así que para el cifrado:

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

y descifrado

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

Si se puede vivir con cripto débil, puede también simplemente xor el ID de acolchado con una clave:

>>> 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 

Pero esto es mucho menos seguro ya que nunca debe usar la misma OTP para múltiples mensajes. También asegúrese de que la clave tenga la misma longitud que su identificación acolchada.

+0

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

+0

@StefanNch http://gitorious.org/bitcoin/python-base58/blobs/master/base58.py Creo que esto es lo que necesito para reemplazar base64 con base58 – Korneel

+0

¿Cree que el costo de esta operación (descifrar base58 + descifrar AES) para convertir la ID ofuscada a la ID original se justifica solo para ocultar la secuencia de ID? ¿Se podría optimizar la operación de descifrado al costo de la operación de cifrado? – Korneel

0

Esta es una pregunta antigua que me encontré. poco encontré la Biblioteca hashids que resuelve este problema y está disponible para una amplia gama de lenguajes de programación:

http://hashids.org

Cuestiones relacionadas