Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version upgrade from 1.3.0 to 1.4.0 produce different hashes #48

Closed
tanek100 opened this issue Feb 17, 2022 · 6 comments
Closed

Version upgrade from 1.3.0 to 1.4.0 produce different hashes #48

tanek100 opened this issue Feb 17, 2022 · 6 comments
Assignees

Comments

@tanek100
Copy link

tanek100 commented Feb 17, 2022

Problem

Version upgrade should not change hash, if salt, alphabet, minimum length have not been changed. Tested with .NET 6 console application.

Results:

v1.4.0

HashID encode: id1: 500, id2: 60123, Encoded: qyrFRr7jCY, Should Be: 58QtxV6Qsw
HashID decode: qyrFRr7jCY, Decoded: [500,60123,0]

v1.3.0

HashID encode: id1: 500, id2: 60123, Encoded: 58QtxV6Qsw, Should Be: 58QtxV6Qsw
HashID decode: 58QtxV6Qsw, Decoded: [500,60123,0]

Code to reproduce

using System.Text.Json;

const string SALT = "OhMySaltiestSalt+2!!!!";
const string ALPHABET = "bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ3456789";
const int MINUMUM_LENGTH = 10;
const string DEFAULT_SEPS = "cfhistuCFHISTU";

var id1 = 500;
var id2 = 60123;

HashidsNet.Hashids hashids = new HashidsNet.Hashids(SALT, MINUMUM_LENGTH, ALPHABET, DEFAULT_SEPS);
string hashid = hashids.Encode(id1, id2, 0);
string shouldBe = "58QtxV6Qsw";

Console.WriteLine($"HashID encode: id1: {id1}, id2: {id2}, Encoded: {hashid}, Should Be: {shouldBe}");
Console.WriteLine($"HashID decode: {hashid}, Decoded: {JsonSerializer.Serialize(hashids.Decode(hashid))}");
@manigandham
Copy link
Collaborator

Hey @tanek100

Thanks for reporting. Version 1.3.0 was released in 2019 and several bugs have been fixed since then. The correct hashcode is qyrFRr7jCY which is produced by v1.4.0.

Hashids uses a common algorithm with implementations in many languages so the others can be used to compare. Here's the canonical Javascript version also resulting in qyrFRr7jCY

import Hashids from "hashids";

const hashids = new Hashids(
  /* salt: */ "OhMySaltiestSalt+2!!!!",
  /* minLength: */ 10,
  /* alphabet: */ "bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ3456789",
  /* seps: */ "cfhistuCFHISTU"
);

const value = hashids.encode([500, 60123, 0]);
const decoded = hashids.decode(value);

console.log(`${decoded} => ${value}`);
document.getElementById("app").innerHTML = `${decoded} => ${value}`;

Live test on codesandbox: https://codesandbox.io/s/hashids-demo-forked-z9tbpj?file=/src/index.ts

@manigandham manigandham self-assigned this Feb 21, 2022
@ZimM-LostPolygon
Copy link

ZimM-LostPolygon commented Jan 11, 2023

@manigandham Just updated from 1.3.0 to 1.6.1, and this is a huge problem. This is a breaking change that completely invalidates all the IDs generated previously, which also means that old IDs generated by 1.3.0 can't be decoded anymore. And since this is a breaking change, I feel like the version number should've been bumped to 2.x.x...

What is the suggested upgrade path here? Is there any way to force 1.4.0+ to use the legacy algorithm that is consistent with 1.3.0? It seems like everyone using 1.3.0 are now stuck with it for eternity.

@tanek100
Copy link
Author

I used old version on webapi to double check if old code and updated my package to new version. I first check if code gets decoded with the new version, if not then check from webapi. When the web api is no longer needed (takes about a year to fase out all the old codes in our case), i can remove the dependency and move on.

@ZimM-LostPolygon
Copy link

ZimM-LostPolygon commented Jan 11, 2023

In my case, all the generated IDs are fixed forever, so that's not an option, unfortunately...

@manigandham
Copy link
Collaborator

@ZimM-LostPolygon

The version was originally incremented to 2.0.0 but reverted back in #29 discussion. Unfortunately too late to change that now.

Can't add a "legacy" option since that version had too many bugs and it would be too much complexity to add back into this library. However if you need 1.3.0, you can include code from that version directly in your project. It's a single file/class and self-contained so you can rename it to HashidsLegacy and use it alongside the new versions.

Here's the file from that 1.3.0 tag: https://github.com/ullmark/hashids.net/blob/78486e39f90979beb892db8b0961fe95d33f931c/src/Hashids.net/Hashids.cs

@ullmark
Copy link
Owner

ullmark commented Jan 12, 2023

@ZimM-LostPolygon @manigandham Yes, to elaborate a bit: AFAIK, the 1.4.0 upgrade never meant to change anything regarding the encoding, it was a bug that unit tests never caught (An old bug not introduced there?). So it would have been weird to bump to 2.0.0 there maybe.

But also as I wrote in the PR @manigandham linked; at the time https://hashids.org/ contained a list of which ports of Hashids had upgraded the algoritm (The early versions produced different "hash"-strings) by referring to a "version" and displayed that in a table. So I felt we couldn't go bananas and be on version 5 or something, when all the other ports used a different strategy.

That table have since been removed, so maybe we could be more true to Semver now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants