hashids

Generate short unique ids from integers


available in JavaScript, Ruby, Python, Java, PHP, Perl, CoffeeScript, Objective-C, C++11, Go, Lua, Elixir, ColdFusion, Groovy and for Node.js & .NET

Hashids started from a need to have short unguessable ids. md5 hashes are too long and base64 is guessable. So, we made Hashids.

Today it's used in url shortening, bundling integers into a short id, or simply as unique identifiers.

Check out the fiddle.

JavaScript version

var hashids = new Hashids("this is my salt"),
  id = hashids.encode(1, 2, 3),
  numbers = hashids.decode(id);

Implementation by Ivan Akimovhttps://github.com/ivanakimov/hashids.js
Also check out:

Features

  1. Creates short unique ids.
  2. Allows custom alphabet as well as salt — so ids are unique only to you.
  3. Incremental input is mangled to stay unguessable.
  4. Code is tiny (~300 lines), fast and does not depend on external libraries.

Compatibility table

Current stable version across implementations is 1.0. We're in the process of updating all versions to 1.0, so please be patient. Versions are tagged as major.minor.patch — we try to follow SemVer but be sure to check the changelog of each library for details.

Since produced ids might differ after updates, be sure to include exact version of Hashids, so you don't unknowingly change your existing ids. For example for npm use:

JSON"dependencies": {
  "hashids": "1.0.0"
}

And not: "hashids": "~1.0.0"

  • JavaScript
    Ruby
    Python
    Java
    PHP
    Perl
    CoffeeScript
    Objective-C
    C++11
    Go
    Lua
    Elixir
    ColdFusion
    Groovy
    Node.js
    .Net
  • 1.0.* (current stable)
  • 0.3.* (old release)

How does it work?

Hashids works similarly to the way integers are converted to hex, but with a few exceptions:

  1. The alphabet is not base16, but base base62 by default.
  2. The alphabet is also shuffled based on salt.

This JavaScript function shows regular conversion of integers to hex. It's part of Hashids (although this is a modified example):

JavaScriptfunction toHex(input) {
  
  var hash = "",
    alphabet = "0123456789abcdef",
    alphabetLength = alphabet.length;
  
  do {
    hash = alphabet[input % alphabetLength] + hash;
    input = parseInt(input / alphabetLength, 10);
  } while (input);
  
  return hash;
  
}

#%@&$!!11

bouncercat awesomed by cameronmcefee

We need ids to be nice and friendly especially if they end up being in the URL. Therefore, the algorithm tries to avoid generating most common English curse words by never placing the following letters next to each other:

c,s,f,h,u,i,t

And their uppercase equivalents. This is done by using them as separators.

So, since letters like "F" and "u" cannot be next to each other in a generated id, the f-bomb is not possible (no matter what your salt value is).

Are there any alternatives?

Yes, there are a few and you should pick the most appropriate for the job. Hashids is not a perfect solution for everything.

  1. Base64 encode. This is the most straightforward approach — most languages have these functions. If you don't need all the fancy extras Hashids offers, this method will work just fine. It's faster too. Read more.
  2. Generate ids based on timestamp. If you can afford certain degree of collisions, you could compose an id that's built on the fly. Use a counter (if you have one) + timestamp (even better if in milliseconds) + some system value (either an IP address or some machine id) + a random integer. Many big companies implement this approach because it works well in distributed systems. These ids are generated independently of each other and the risk of collisions is so tiny it's negligible.
  3. Check out how others do it:

    - How does Instagram generate ids?

  4. Know of another method? Tell me @IvanAkimov or ivanbarreleyecom

What not to do

  1. Do not encode strings. We've had several requests to add this feature — it seems so easy to add. We will not add this feature for security purposes, doing so encourages people to encode sensitive data, like passwords. This is the wrong tool for that.
  2. Do not encode sensitive data. This means passwords, emails, any kind of personal user data. This is not a true encryption algorithm. There are people that dedicate their lives to cryptography and there are plenty of more appropriate algorithms: bcrypt, md5, aes, sha1, blowfish. Here's a full list.

Collisions

There is no collisions because the method is based off of integer to hex conversion. As long as you don't change constructor arguments midway, the generated output will stay unique to your salt.

You can also test this by generating a billion ids and checking for collisions. Be sure to account for your alphabet, since default alphabet is case-sensitive (aaa is different than AAA).

Why "hashids"?

Originally the project referred to generated ids as hashes, and obviously the name hashids has the word hash in it. Technically, these generated ids cannot be called hashes since a cryptographic hash has one-way mapping (cannot be decrypted).

However, when people search for a solution, like a "youtube hash" or "bitly short id", they don't really care what's one-way and what's not. So hashids became a term on its own — an id that's used to obfuscate numbers.

How to decode

There is no way to decode the output without knowing the salt (refer to how hashids works). The only known way is to use a brute-force attack. However, since integers behind the ids are of so little value to an attacker, there's not much reason to try and extract them in the first place.

How to contribute

If you've found a bug, please open a github issue in the appropriate repository. Bonus points if you submit a pull request with it.

If an implementation in your favorite language is missing, feel free to port it over from one of the existing versions. There's still plenty of languages to contribute in: C, D, Swift, Rust, Julia, Erlang, Haskell, Scheme, Tcl, Lolcode?

We try to keep the library versions compatible. If you see an outdated version in an existing implementation, please open a github issue in that repository — show your +1 support for that issue.

If you have a new library, plugin or extension ping me @IvanAkimov. You can also reach me at ivanbarreleyecom

codercat by cameronmcefee

Contributors

Many thanks to the numerous folks that have implemented the different versions, plugins, extensions as well as to those that have suggested general improvements.

License

All hashids libraries are under MIT license. You can use them in open source projects and commercial products. Don't break the Internet. Kthxbye.