A small .NET package to generate YouTube-like IDs from numbers.
It converts numbers like 347
into strings like yr8
, or array of numbers like [27, 986]
into 3kTMd
. You can also decode those IDs back. This is useful in bundling several parameters into one, hiding actual IDs, or simply using them as short string IDs.
The original author of the Hashids algoritm has rebranded and created a new algoritm called "sqids", you can read more about why here.. A .NET version of sqids has already been created and can be found here.
This library have more or less been considered feature complete since its creation 2012 and will remain available and accept pull requests for bug fixes etc. but no new features will be added.
int
and long
)
alphabet - separators - 1
.Install the package with NuGet
Install-Package hashids.net
using HashidsNet;
You can pass a unique salt value so your hashes differ from everyone else's. I use "this is my salt" as an example.
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(12345);
hash
is now going to be:
NkK9
If your id is stored as a Int64
you need to use "EncodeLong".
var hashids = new Hashids("this is my salt");
var hash = hashids.EncodeLong(666555444333222L);
hash
is now going to be:
KVO9yy1oO5j
Notice during decoding, same salt value is used:
var hashids = new Hashids("this is my salt");
numbers = hashids.Decode("NkK9");
numbers
is now going to be:
[ 12345 ]
var hashids = new Hashids("this is my salt");
numbers = hashids.DecodeLong("KVO9yy1oO5j");
numbers
is now going to be:
[ 666555444333222L ]
By default, Decode and DecodeLong will return an array. If you need to decode just one id you can use the following helper functions:
var hashids = new Hashids("this is my pepper");
number = hashids.DecodeSingle("NkK9");
number
is now going to be:
12345
var hashids = new Hashids("this is my pepper");
if (hashids.TryDecodeSingle("NkK9", out int number)) { // Decoding hash successfull. }
number
is now going to be:
12345
You can handle the exception to see what went wrong with the decoding:
var hashids = new Hashids("this is my pepper");
try
{
number = hashids.DecodeSingle("NkK9");
}
catch (NoResultException) { // Decoding the provided hash has not yielded any result. }
number
is now going to be:
12345
var hashids = new Hashids("this is my pepper");
number = hashids.DecodeSingleLong("KVO9yy1oO5j");
number
is now going to be:
666555444333222L
var hashids = new Hashids("this is my pepper");
if (hashids.TryDecodeSingleLong("NkK9", out long number)) { // Decoding hash successfull. }
number
is now going to be:
666555444333222L
var hashids = new Hashids("this is my pepper");
try
{
number = hashids.DecodeSingleLong("KVO9yy1oO5j");
}
catch (NoResultException) { // Decoding the provided hash has not yielded any result. }
number
is now going to be:
666555444333222L
Decoding will not work if salt is changed:
var hashids = new Hashids("this is my pepper");
numbers = hashids.Decode("NkK9");
numbers
is now going to be:
[]
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(683, 94108, 123, 5);
hash
is now going to be:
aBMswoO2UB3Sj
var hashids = new Hashids("this is my salt");
var numbers = hashids.Decode("aBMswoO2UB3Sj")
numbers
is now going to be:
[ 683, 94108, 123, 5 ]
Here we encode integer 1, and set the minimum hash length to 8 (by default it's 0 -- meaning hashes will be the shortest possible length).
var hashids = new Hashids("this is my salt", 8);
var hash = hashids.Encode(1);
hash
is now going to be:
gB0NV05e
var hashids = new Hashids("this is my salt", 8);
var numbers = hashids.Decode("gB0NV05e");
numbers
is now going to be:
[ 1 ]
Here we set the alphabet to consist of: "abcdefghijkABCDEFGHIJK12345"
var hashids = new Hashids("this is my salt", 0, "abcdefghijkABCDEFGHIJK12345")
var hash = hashids.Encode(1, 2, 3, 4, 5)
hash
is now going to be:
Ec4iEHeF3
The primary purpose of hashids is to obfuscate ids. It's not meant or tested to be used for security purposes or compression. Having said that, this algorithm does try to make these hashes unguessable and unpredictable:
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(5, 5, 5, 5);
You don't see any repeating patterns that might show there's 4 identical numbers in the hash:
1Wc8cwcE
Same with incremented numbers:
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
hash
will be :
kRHnurhptKcjIDTWC3sx
var hashids = new Hashids("this is my salt");
hashids.Encode(1); // => NV
hashids.Encode(2); // => 6m
hashids.Encode(3); // => yD
hashids.Encode(4); // => 2l
hashids.Encode(5); // => rD
var hashids = new Hashids("this is my salt");
var hash = hashids.EncodeHex("DEADBEEF");
hash
is now going to be:
kRNrpKlJ
var hashids = new Hashids("this is my salt");
var hex = hashids.DecodeHex("kRNrpKlJ");
hex
is now going to be:
DEADBEEF
v.1.7.0
netstandard2.0
, net6.0
, net7.0
.v.1.6.1
v.1.6.0
v1.5.0
net461
target.readonly
and Span<T>
usage.System.Memory
to replace internal ReadOnlySpan<T>
class.1.4.1
Microsoft.Extensions.ObjectPool
with internal implementation.1.4.0
net461
, net5.0
, netstandard2.0
1.3.0
1.2.2
1.2.1
1.2.0Added
1.1.2
1.1.1
1.1.0
long
via new functions to not introduce breaking changes.
EncodeLong
for encodes.DecodeLong
for decodes.IHashids
for people who want an interface to work with.1.0.1
1.0.0
Several public functions marked obsolete and renamed versions added, to be more appropriate:
Encrypt()
changed to Encode()
Decrypt()
changed to Decode()
EncryptHex()
changed to EncodeHex()
DecryptHex()
changed to DecodeHex()
Hashids was designed to encode integers, primary ids at most. We've had several requests to encrypt sensitive data with Hashids and this is the wrong algorithm for that. So to encourage more appropriate use, encrypt/decrypt
is being "downgraded" to encode/decode
.
0.3.4
0.3.3
EncryptHex
and DecryptHex
0.1.4