Generated hashid size

645 Views Asked by At

Today I am generating the hashid as follows:

const Hashids = require('hashids');

const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

let number = 1419856
let hash = new Hashids('Salto do Pedro', 6, ALPHABET).encode(number)
console.log("Hash:", hash, ". Number:", number, ". Size:", hash.length)

So what is printed on the console is:

[Running] node "c:\Users\pedro\Desktop\teste\testPedro.js"
Hash: YMMMMM . Number: 1419856 . Size: 6

[Done] exited with code=0 in 0.258 seconds

However, if I change the variable 'number' to number 1419857 the result is:

[Running] node "c:\Users\pedro\Desktop\teste\testPedro.js"
Hash: DRVVVVV . Number: 1419857 . Size: 7

[Done] exited with code=0 in 0.245 seconds

My doubt is: The alphabet I am going through has 26 characters and I defined that the minimum size of the hashid would be 6 characters, the maximum hashid that I would have available with 6 characters would not be 308.915.776 (26 * 26 * 26 * 26 * 26 * 26 )? Why in the number 1.419.857 he already increased one more character in my hashid?

1

There are 1 best solutions below

0
Rush W. On

Good question. This might look intimidating but I would try to make it as simple as possible by understanding the math behind the code.

The Hashids constructor takes parameter - (salt, minLength, alphabet, seps)

Salt - String value which makes your ids unique in your project
MinLength - Number value which is the minimum length of id string you need
alphabet - String value (Input string)
seps - String value to take care of curse words

With this set, it tries to create a buffer array with Salt and random characters(taken based on salt,sep,alphabet passed) and shuffles the positions of each character.

Now, the below is the code which encodes the value based on the above character array

id = []
do {
    id.unshift(alphabetChars[input % alphabetChars.length])
    input = Math.floor(input / alphabetChars.length)
} while (input > 0)

Let's first take example 1 -

this.salt = 'Salto do Pedro'
this.minLength = 6
input = 1419856
// alphabetChars is the array which generates based on salt,alphabet and seps. (complex operations invol
alphabetChars = ["A","X","R","N","W","G","Q","O","L","D","V","Y","K","J","E","Z","M"]

Example 1

The final array is then joined by string and a lottery character (another some math operation calc) is appended at the start. This is returned as encoded string.

Let's first take example 2 -

this.salt = 'Salto do Pedro'
this.minLength = 6
input = 1419857
// alphabetChars is the array which generates based on salt,alphabet and seps. (complex operations invol
alphabetChars = ["V","R","Y","W","J","G","M","L","Z","K","O","D","E","A","Q","N","X"]

Example 2

Now this is the reason why you get +1 character extra if the number changes (because it ran a loop extra). It's the min length of the alphabet array which is monitored rather than max length, so you cannot be sure that you would be getting the same length by +1 characters always.

Hope it helps. If you want to dig in more - Here's the code for the library - https://github.com/niieani/hashids.js/blob/master/dist/hashids.js#L197