-
Notifications
You must be signed in to change notification settings - Fork 174
Closed
Description
I have a reproducable bug in which certain input does create a valid hashid, but the Decode fails!
Repro code where the result is empty, instead of equal to the source:
var hashId = new Hashids(salt: "0Q6wKupsoahWD5le", alphabet: "abcdefghijklmnopqrstuvwxyz1234567890!", seps: "cfhistu");
var source = new long[] { 35887507618889472L, 30720L, Int64.MaxValue };
var encoded = hashId.EncodeLong(source);
var result = hashId.DecodeLong(encoded);
// ASSERT result == source FAILS
(Both the first (35887507618889472L
) and the last (Int64.MaxValue
) long values fail here)
After some investigation of my own, it turns out the root cause is the use of the Math.Pow
function in the Unhash function. Due to its double
nature, it is subject to rounding errors.
Proposed solution: update the Unhash
function with the following code:
private long Unhash(string input, string alphabet)
{
long number = 0;
var alphabetLength = new System.Numerics.BigInteger(alphabet.Length);
for (var i = 0; i < input.Length; i++)
{
var pos = (long)alphabet.IndexOf(input[i]);
number += (pos * (long)System.Numerics.BigInteger.Pow(alphabetLength, input.Length - i - 1));
}
return number;
}
Metadata
Metadata
Assignees
Labels
No labels