Hashid: Upgrading Elixir from 1.6 to 1.7 changed results

Hi guys,

I recently upgraded an app I’m working on from Elixir 1.6 to 1.7 and we use a package called Hashids for some SMS stuff (GitHub - alco/hashids-elixir: Stringify your ids · GitHub). When upgrading, the encoded and decoded values changed and thus my tests failed.

  1. test decoding to a number (Cipher.TokenTest)
    test/token_test.exs:18
    Assertion with == failed
    code: assert decoded == @number
    left: 4837
    right: 1276
    stacktrace:
    test/token_test.exs:20: (test)

  2. test encoding a number (Cipher.TokenTest)
    test/token_test.exs:13
    Assertion with == failed
    code: assert encoded == @hash
    left: “5d44”
    right: “9kn7”
    stacktrace:
    test/token_test.exs:15: (test)

I was just wondering why that might’ve happened?

Nothing that I’m immediately seeing as an issue, and it’s own tests are passing on 1.7, so I think we’d need a reproduceable example then? :slight_smile:

Please show us your test code so that we have something to work with. Also which exact Erlang and Elixir versions are you running?

Elixir 1.6 and 1.7

As an example:

alphabet = "123456789abcdefghijklmnopqrstuvwxyz"
min_length =  4
hasher = Hashids.new(alphabet: alphabet, min_len: min_length)

Hashids.encode(hasher, 1276)
= "9kn7" # in 1.6

Hashids.encode(hasher, 1276)
= "5d44" # in 1.7

I’m mostly curious as to what part of 1.7 caused this change. If you try this yourself you might get different string values.

1.7.0-otp-21.0.1

iex(1)> alphabet = "123456789abcdefghijklmnopqrstuvwxyz"
"123456789abcdefghijklmnopqrstuvwxyz"
iex(2)> min_length =  4
4
iex(3)> hasher = Hashids.new(alphabet: alphabet, min_len: min_length)
%Hashids{
  a_len: 24,
  alphabet: '56789abdegjklmnopqrvwxyz',
  g_len: 3,
  guards: '234',
  min_len: 4,
  s_len: 8,
  salt: [],
  seps: 'cfhistu1'
} 
iex(4)> Hashids.encode(hasher, 1276)
"9kn7"

1.7.3-otp-21.0.1

iex(1)> alphabet = "123456789abcdefghijklmnopqrstuvwxyz"
"123456789abcdefghijklmnopqrstuvwxyz"
iex(2)> min_length =  4
4
iex(3)> hasher = Hashids.new(alphabet: alphabet, min_len: min_length)
%Hashids{
  a_len: 24,
  alphabet: '56789abdegjklmnopqrvwxyz',
  g_len: 3,
  guards: '234',
  min_len: 4,
  s_len: 8,
  salt: [],
  seps: 'cfhistu1'
} 
iex(4)> Hashids.encode(hasher, 1276)
"9kn7"

1.6.6-otp-21.0.1

iex(1)> alphabet = "123456789abcdefghijklmnopqrstuvwxyz"
"123456789abcdefghijklmnopqrstuvwxyz"
iex(2)> min_length =  4
4
iex(3)> hasher = Hashids.new(alphabet: alphabet, min_len: min_length)
%Hashids{
  a_len: 24,
  alphabet: '56789abdegjklmnopqrvwxyz',
  g_len: 3,
  guards: '234',
  min_len: 4,
  s_len: 8,
  salt: [],
  seps: 'cfhistu1'
} 
iex(4)> Hashids.encode(hasher, 1276)
"9kn7"

EDIT: /me is still compiling OTP 21.1.1, hold on…

1.7.3-otp-21.1.1

iex(1)> alphabet = "123456789abcdefghijklmnopqrstuvwxyz"
"123456789abcdefghijklmnopqrstuvwxyz"
iex(2)> min_length =  4
4
iex(3)> hasher = Hashids.new(alphabet: alphabet, min_len: min_length)
%Hashids{
  a_len: 24,
  alphabet: '56789abdegjklmnopqrvwxyz',
  g_len: 3,
  guards: '234',
  min_len: 4,
  s_len: 8,
  salt: [],
  seps: 'cfhistu1'
} 
iex(4)> Hashids.encode(hasher, 1276)
"9kn7"

So nope, doesn’t seem I can replicate what you are seeing having tried 3 different elixir versions as well as 2 OTP versions.

What is your OS? Are you able to replicate it in a docker image (please share it if so!)? What specific versions of Elixir and OTP?