I'm trying to generate URLs for my database objects. <a href="http://agiliq.com/books/djangodesignpatterns/misc.html#do-not-use-primary-keys-in-urls" rel="nofollow">I've read</a> 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?
<strong>UPDATE:</strong> I ended up using the bitwise XOR masking method suggested by David below, and it works wonderfully. Thanks to everyone for your input.Answer1:
First, "don't use primary keys in URLs" is only a very weak guideline. <em>If</em> you are using incremental integer IDs <em>and</em> 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 <em>highly</em> 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.