overview
This article shares for. NET developers a lightweight open source encryption (short ID generation) tool library that encodes numbers into strings-** Hashids.net **.
Whether in front-end or back-end programming development, you will encounter scenarios where the system automatically generates some codes or IDs, and the generated codes or IDs are required to be non-duplicate (extremely low repetition rate).
前端开发中,常用的有nanoid。而后端开发中,常用的技术则有:自增 ID,雪花 ID,GUID 等。其中,自增 ID 在中小型系统中使用比较常见,它占用的存储空间相对较小,检索速度相对较快,但它不适用于分布式系统的构建,而雪花 ID 和 GUID 等占用字节较多,占用存储空间较大,检索速度相对较慢,但后两者适用于分布式的系统构建。
另外,还有一些场景,为了隐藏后端的真实 ID,在显示到客户端时,对真实 ID 进行加密处理,将真实的数字加密生成一个短的字符串,比如国外知名视频网站油管的视频地址类似https://www.yt.com/watch?v=yVd7vbeFj-g,其中的参数v的值yVd7vbeFj-g即为一个加密的字符串。
In the development of programs such as. NET,. NET Core,. NET 5\6\7\8, if you want to generate similar encrypted strings, this article recommends ** Hashids.net **, an open source short ID generation (encryption) class library for. NET developers.
Hashids.net Features and Features
Hashids.net可以将数字转换成字符串,比如将347转换成yr8,或者将数字数组[27, 986]转换成3kTMd。当然,你也可以将转换后的字符串再次转换成数字或者数字数组。这在将多个参数捆绑成一个参数、隐藏实际 ID 或简单地将它们用作短字符串 ID 时非常有用。
Hashids.net mainly has the following features:
- Convert integers to unique short IDs (only positive integers including zeros are supported)
- Generate non-speculative, non-contiguous ids for self-increasing IDs
- Support for single numbers or arrays of numbers
- Allow custom letters and salt
- Allow specification of minimum hash length
Installation of Hashids.net
Hashid.net is released as NuGet package, so there are the following installation methods:
** 1. NuGet command line **
Install-Package Hashids.net
** 2. NuGet Package Management Tool **
Right-click ** dependencies ** in the project, as shown in the figure:

然后,在打开的 NuGet 程序包管理界面输入关键字Hashids.net,在搜索到的结果中选中Hashids.net类库组件并安装,如图:

Use of Hashids.net
Import the namespace of Hashids.net
using HashidsNet;
Encoding individual digits
实例化Hashids对象时,你可以传递一个唯一的盐值,这样你的哈希值就不同于其他人的哈希值。这里使用this is my salt作为例子。
var Hashids = new Hashids("this is my salt");
var hash = hashids.Encode(12345);
运行结果为:NkK9
如果要转换一个Int64类型的数字,则需要调用EncodeLong()方法,如下:
var hashids = new Hashids("this is my salt");
var hash = hashids.EncodeLong(666555444333222L);
运行结果为:KVO9yy1oO5j
decoding
** Hashids.net ** provides the ability to decode encoded strings, but the same salt value as the encoding is used when decoding:
var hashids = new Hashids("this is my salt");
numbers = hashids.Decode("NkK9");
运行结果为:[ 12345 ]
var hashids = new Hashids("this is my salt");
numbers = hashids.DecodeLong("KVO9yy1oO5j");
运行结果为:[ 666555444333222L ]
Decoding using different salt values
If the salt value at the time of decoding is not the same as at the time of encoding, decoding will fail:
var hashids = new Hashids("this is my pepper");
numbers = hashids.Decode("NkK9");
运行结果为:[]
Encoding multiple numbers
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(683, 94108, 123, 5);
运行结果为:aBMswoO2UB3Sj
Decoding after encoding multiple numbers
var hashids = new Hashids("this is my salt");
var numbers = hashids.Decode("aBMswoO2UB3Sj")
运行结果为:[ 683, 94108, 123, 5 ]
Specifies the minimum hash length after encoding
The following example encodes the integer 1 and sets the minimum hash length to 8(0 by default-which means the hash will be the shortest possible length).
var hashids = new Hashids("this is my salt", 8);
var hash = hashids.Encode(1);
运行结果为:gB0NV05e
decoding
var hashids = new Hashids("this is my salt", 8);
var numbers = hashids.Decode("gB0NV05e");
运行结果为:[ 1 ]
Custom hash letters
以下示例指定了自定义的哈希字母为abcdefghijkABCDEFGHIJK12345:
var hashids = new Hashids("this is my salt", 0, "abcdefghijkABCDEFGHIJK12345")
var hash = hashids.Encode(1, 2, 3, 4, 5)
运行结果为:Ec4iEHeF3
Randomness of Hashids.net
Hashids.net的主要目的是混淆 ID,此外,它还可以让有规律的数字变得不可猜测和不可预测。
coded repeated digits
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(5, 5, 5, 5);
编码后,你不会看到任何重复的模式来表明哈希中有 4 个相同的数字,运行结果为:1Wc8cwcE。
coded sequential number
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
运行结果为:kRHnurhptKcjIDTWC3sx
coded self-increasing digit
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
coded hexadecimal
var hashids = new Hashids("this is my salt");
var hash = hashids.EncodeHex("DEADBEEF");
运行结果为:kRNrpKlJ
decoding hexadecimal
var hashids = new Hashids("this is my salt");
var hex = hashids.DecodeHex("kRNrpKlJ");
运行结果为:DEADBEEF
How about encrypting a string to make a short string?
The following is the webmaster extension long string to short string method introduction
In fact, it is very simple. Use the original string that needs to be encrypted as salt and fix the encrypted number, so that it is easy to achieve:
public static string GetHashids(this string sourceStr, int number = 9)
{
var hashids = new Hashids(sourceStr);
return hashids.Encode(number);
}
The unit test is as follows: For example, encrypt the alias of this article [Is-it-possible-to-use-it-as-a-short-link-generator-Hashidsnet]
[TestClass]
public class HashHelperUnitTest
{
[TestMethod]
public void Hashids_Success()
{
var blogPostSlugStr = "Is-it-possible-to-use-it-as-a-short-link-generator-Hashidsnet";
var encodeStr1 = blogPostSlugStr.GetHashids();
var encodeStr2 = blogPostSlugStr.GetHashids();
Assert.AreEqual(encodeStr1, encodeStr2);
}
}
After encryption, the alias is: [6Q]. You can open a browser to visit the short link address of this article and try it: https://www.example.com. dotnet9.com/6Q
** Note: This is not the original intention of this library, but it is a good idea to convert long strings into short strings. Haha, remember that this is irreversible. **
small knowledge
There are many ways to convert a long string into a short string. General practice:
- Use a database to store short strings and original strings. You can define your own rules for short strings, such as starting from 1, reading the database every time the value is taken, and taking the long string according to the short string or taking the short string according to the long string.
Advantages: The short string corresponds to the original string one by one, allowing two-way conversion to be realized, and no duplicate short strings will appear.
Disadvantages: You need to read and write the database frequently, which has a certain impact on the performance of the database.
- Convert long strings to short strings using an algorithm. Some algorithms are reversible and some are irreversible.
No database storage is required, but the length may be slightly longer.
- Example reversible algorithm (C#):
public static string ShortenString(string longString)
{
byte[] bytes = Encoding.UTF8.GetBytes(longString);
string shortString = Convert.ToBase64String(bytes);
return shortString;
}
public static string RestoreString(string shortString)
{
byte[] bytes = Convert.FromBase64String(shortString);
string longString = Encoding.UTF8.GetString(bytes);
return longString;
}
- Example irreversible algorithm (C#):
public static string ShortenString(string longString)
{
using (SHA256 sha256 = SHA256.Create())
{
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(longString));
string shortString = Convert.ToBase64String(hashBytes);
return shortString;
}
}
- Differences:
- Reversible algorithms can restore the original string through a short string, but irreversible algorithms cannot restore it.
- Reversible algorithms generate short strings of longer lengths, while irreversible algorithms generate short strings of shorter lengths.
- Using an algorithm to automatically generate short strings does not require frequent reading and writing to the database, and has good performance, but there may be a problem of short string conflicts, that is, different long strings may generate the same short string.
Finally, a complete list of unit tests I hope will be useful to you:
using HashidsNet;
using System.Security.Cryptography;
using System.Text;
namespace Dotnet9.Commons.Test;
[TestClass]
public class HashHelperUnitTest
{
public static string GetHashids(string sourceStr, int number = 9)
{
var hashids = new Hashids(sourceStr);
return hashids.Encode(number);
}
[TestMethod]
public void Hashids_Success()
{
var blogPostSlugStr = "Is-it-possible-to-use-it-as-a-short-link-generator-Hashidsnet";
var encodeStr1 = GetHashids(blogPostSlugStr);
var encodeStr2 = GetHashids(blogPostSlugStr);
Assert.AreEqual(encodeStr1, encodeStr2);
}
[TestMethod]
public void Hashids_Best_Success()
{
var blogPostSlugStr = "Is-it-possible-to-use-it-as-a-short-link-generator-Hashidsnet";
var encodeStr1 = blogPostSlugStr.GetHashids();
var encodeStr2 = ShortenString(blogPostSlugStr);
var encodeStr3 = ShortenString2(blogPostSlugStr);
Assert.IsTrue(encodeStr1.Length < encodeStr2.Length, "Hashids生成的短字符串比Base64还短");
Assert.IsTrue(encodeStr1.Length < encodeStr3.Length, "Hashids生成的短字符串还是短那么一点点");
}
public static string ShortenString(string longString)
{
byte[] bytes = Encoding.UTF8.GetBytes(longString);
string shortString = Convert.ToBase64String(bytes);
return shortString;
}
public static string RestoreString(string shortString)
{
byte[] bytes = Convert.FromBase64String(shortString);
string longString = Encoding.UTF8.GetString(bytes);
return longString;
}
public static string ShortenString2(string longString)
{
using (SHA256 sha256 = SHA256.Create())
{
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(longString));
string shortString = Convert.ToBase64String(hashBytes);
return shortString;
}
}
}
Most of this article quotes Zhihu's original article:
Original title: Sharing. NET/. NET 5 lightweight open source encryption (short ID generation) tool class library for encoding numbers into strings--hashids.net
Original link: codedefault.com/p/lightweight-open-source-project-hashids-net-for-generating-short-ids-from-numbers