Hacker News new | ask | show | jobs
by zrail 4326 days ago
Interesting. Effectively it's base62 encoding with a fixed salt. I think saying "encrypt" and "decrypt" is sort of misleading, even though you call the non-cryptographic nature of the hashing in the README files.

For my own products I do something a little different. Instead, when I create a record I generate a random number (with Ruby's SecureRandom module) and store the base32 encoding in the database. With the universe set at 1bil, this reliably generates a random 6 character string that I can safely show to the customer.

Edit: base62, not base82

3 comments

You're storing 6-char base-32 values, so 1073741824 possibilities, but you've got 50-50 chance of collision after 38582 values - that's not a lot, the birthday paradox bites again! Using much larger random values or hashes gives you a better safety margin.
I also have a unique constraint on the value and re-run the generator if there's a collision.
That is something that hashid avoids.
> this reliably generates a random 6 character string that I can safely show to the customer

Are you sure about that? You might want to consider a smaller alphabet, with vowels and ambiguous letters/numerals (0/O, 1/l/I) omitted. That has two advantages: you won't accidentally generate an identifier containing meaningful words (notably profanity), and the identifiers become easier to unambiguously transcribe and interpret. And you'll still reliably get a 6-character identifier as long as you have at least 32 symbols to use.

That's a fair point. So far there hasn't been any transcribing necessary because I have the customers reply to their receipt emails if they have a problem, but that's definitely something to consider if you have to do phone support.
It's also useful for anything where they might retype the string. (Even if you tell them to copy/paste, some people will still retype.) Not that this necessarily applies to you, but for others considering similar schemes, avoiding I/1/l and such can be really handy.
Base82? You mean base62 - 26(letters) x 2 (other case) +10 (digits)? Or am I missing something?
Nope, you're exactly right. Need more coffee.