raddevon
raddevon

Reputation: 3340

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.

Upvotes: 6

Views: 3468

Answers (1)

David Wolever
David Wolever

Reputation: 154504

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.

Upvotes: 14

Related Questions