概要:概要
この記事では、. NET開発者向けに、数値を文字列にエンコードするための、軽量でオープンソースの暗号化ツールであるHashids.net ** を紹介します。
フロントエンドまたはバックエンドのプログラミング開発において、システムが何らかのエンコーディングまたはIDを自動的に生成させるシナリオがあり、生成されたエンコーディングまたはIDが反復しない(繰り返し率が極めて低い)ことが要求される。
前端开发中,常用的有nanoid。而后端开发中,常用的技术则有:自增 ID,雪花 ID,GUID 等。其中,自增 ID 在中小型系统中使用比较常见,它占用的存储空间相对较小,检索速度相对较快,但它不适用于分布式系统的构建,而雪花 ID 和 GUID 等占用字节较多,占用存储空间较大,检索速度相对较慢,但后两者适用于分布式的系统构建。
另外,还有一些场景,为了隐藏后端的真实 ID,在显示到客户端时,对真实 ID 进行加密处理,将真实的数字加密生成一个短的字符串,比如国外知名视频网站油管的视频地址类似https://www.yt.com/watch?v=yVd7vbeFj-g,其中的参数v的值yVd7vbeFj-g即为一个加密的字符串。
NET、. NET Core、. NET 5\6\7\8などのプログラム開発で同様の暗号化文字列を生成したい場合は、. NET開発者向けのオープンソースのShort ID 生成(暗号化)ライブラリ ** Hashids.net ** をお勧めします。
Hashids.netの機能と機能
Hashids.net可以将数字转换成字符串,比如将347转换成yr8,或者将数字数组[27, 986]转换成3kTMd。当然,你也可以将转换后的字符串再次转换成数字或者数字数组。这在将多个参数捆绑成一个参数、隐藏实际 ID 或简单地将它们用作短字符串 ID 时非常有用。
Hashids.netには以下の機能がある。
- 整数を一意のショートIDに変換するゼロを含む正の整数のみをサポート
- 自己インクリメントIDの推測不可能な不連続IDの生成
- 単一の数値または数値配列のサポート
- カスタム文字と塩を許可する
- 最小ハッシュ長を指定できます。
Hashids.netのインストール
Hashid.netはNuGetパッケージとして公開されているため、以下のインストール方法があります。
** 1. NuGetコマンドライン ***
Install-Package Hashids.net
-
- NuGetパッケージ管理ツール **
図のように、プロジェクト内の ** 依存関係 ** を右クリックします。

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

Hashids.netの利用
Hashids.netのネームスペースのインポート
using HashidsNet;
個々の数字をエンコードする
实例化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
デコーディング
** Hashids.net ** はエンコードされた文字列を逆デコードする機能を提供しますが、デコードにはエンコードと同じsalt値が必要です。
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 ]
異なる塩分値を使用してデコードする
デコード時のソルト値がエンコード時と同じでない場合、デコードは失敗します。
var hashids = new Hashids("this is my pepper");
numbers = hashids.Decode("NkK9");
运行结果为:[]
複数の数字をエンコード
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(683, 94108, 123, 5);
运行结果为:aBMswoO2UB3Sj
複数のデジタル符号化後の復号法
var hashids = new Hashids("this is my salt");
var numbers = hashids.Decode("aBMswoO2UB3Sj")
运行结果为:[ 683, 94108, 123, 5 ]
エンコード後の最小ハッシュ長を指定する
次の例では、整数 1を符号化し、最小ハッシュ長を8に設定します(デフォルトでは0です。つまり、ハッシュは可能な限り最短の長さになります)。
var hashids = new Hashids("this is my salt", 8);
var hash = hashids.Encode(1);
运行结果为:gB0NV05e
デコーディング
var hashids = new Hashids("this is my salt", 8);
var numbers = hashids.Decode("gB0NV05e");
运行结果为:[ 1 ]
カスタムハッシュ文字
以下示例指定了自定义的哈希字母为abcdefghijkABCDEFGHIJK12345:
var hashids = new Hashids("this is my salt", 0, "abcdefghijkABCDEFGHIJK12345")
var hash = hashids.Encode(1, 2, 3, 4, 5)
运行结果为:Ec4iEHeF3
Hashids.netのランダム性
Hashids.net的主要目的是混淆 ID,此外,它还可以让有规律的数字变得不可猜测和不可预测。
重複する数字を符号化
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(5, 5, 5, 5);
编码后,你不会看到任何重复的模式来表明哈希中有 4 个相同的数字,运行结果为:1Wc8cwcE。
コード化された番号
var hashids = new Hashids("this is my salt");
var hash = hashids.Encode(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
运行结果为: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
16進数のエンコード
var hashids = new Hashids("this is my salt");
var hash = hashids.EncodeHex("DEADBEEF");
运行结果为:kRNrpKlJ
16進数のデコード
var hashids = new Hashids("this is my salt");
var hex = hashids.DecodeHex("kRNrpKlJ");
运行结果为:DEADBEEF
文字列を暗号化して短い文字列にする方法は?
以下は、長文字列を短い文字列に拡張する方法です。
実際には、塩として暗号化する必要がある元の文字列、暗号化番号は固定されているので、簡単に実装できます:
public static string GetHashids(this string sourceStr, int number = 9)
{
var hashids = new Hashids(sourceStr);
return hashids.Encode(number);
}
単体テストは次のようになります。例えば、この記事の別名(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);
}
}
別名暗号化後:【6Q】,可开ブラウザ访问本文短リンク先试试:https//dotnet9.com/6Q。
**注:これはライブラリの本来の意図ではありませんが、長い文字列を短い文字列に変換するのは良いアイデアです。
知識が少ない。
長い文字列を短い文字列に変換する方法はいくつかありますが、一般的な方法は:
- データベースを使用して短い文字列と元の文字列を格納し、短い文字列は1から値を取る、値を取るたびにデータベースを読む、短い文字列に応じて長い文字列を取る、長い文字列に応じて短い文字列を取るなどのルールを独自に定義することができます。
利点:短い文字列は元の文字列と1対1に対応し、双方向変換を実現でき、短い文字列の繰り返しはありません。
欠点:データベースへの頻繁な読み書きが必要で、データベースのパフォーマンスに一定の影響があります。
- 長い文字列を短い文字列に変換するアルゴリズムは可逆的なアルゴリズムもあれば不可逆的なアルゴリズムもあります
データベースストレージは必要ありませんが、長さが少し長くなることがあります。
- 可逆アルゴリズムの例(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;
}
- 不可逆アルゴリズムの例(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;
}
}
- 違いは:
- 可逆アルゴリズムは短い文字列で元の文字列に復元できるが、不可逆アルゴリズムは復元できない。
- 可逆アルゴリズムは長い長さの短い文字列を生成するが、非可逆アルゴリズムは短い文字列を生成する。
- アルゴリズムを使用して短い文字列を自動的に生成すると、データベースを頻繁に読み書きする必要がなく、パフォーマンスは向上しますが、短い文字列の競合、すなわち異なる長い文字列が同じ短い文字列を生成する可能性があるという問題があります。
最後に、完全な単体テストのリストが役立ちます:
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;
}
}
}
この記事のほとんどは元の記事から引用される:
前题:共有. NET/. NET 5軽量オープンソースの数値を文字列にエンコードする暗号化ショートID 生成ツールクラスライブラリ-hashids.net
原文へのリンク:https//codedefault.com/p/lightweight-open-source-project-hashids-net-for-generating-short-ids-from-numbers