Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django: How do I hash a URL from the database object's primary key?

I'm trying to generate URLs for my database objects. I've read I should not use the primary key for URLs, and a stub is not a good option for this particular model. Based on the advice in that link, I played around with zlib.crc32() in a Python interpreter and found that values often return negative numbers which I don't want in my URLs. Is there a better hash I should be using to generate my URLs?

UPDATE: I ended up using the bitwise XOR masking method suggested by David below, and it works wonderfully. Thanks to everyone for your input.

like image 719
raddevon Avatar asked May 11 '12 23:05

raddevon


1 Answers

First, "don't use primary keys in URLs" is only a very weak guideline. If you are using incremental integer IDs and you don't want to reveal those numbers, then you could obfuscate them a little bit. For example, you could use: masked_id = entity.id ^ 0xABCDEFAB and unmasked_id = masked_id ^ 0xABCDEFAB.

Second, the article you linked to is highly suspicious. I would not trust it. First, CRC32 is a one-way hashing function: it's impossible (in general) to take a CRC32 hash and get back the string used to create that hash. You'll notice that he doesn't show you how to look up a Customer given the CRC32 of their pk. Second, the code in the article doesn't even make sense. The zlib.crc32 function expects a byte string, while Customer.id will be an integer.

Third, be careful if you want to use a slug for a URL: if the slug changes, your URLs will also change. This may be okay, but it's something you'll need to consider.

like image 159
David Wolever Avatar answered Nov 10 '22 03:11

David Wolever