计算字符串的校验和

本文关键字:校验和 字符串 计算 | 更新日期: 2023-09-27 18:28:42

我得到了一个任意长度的字符串(比如说5到2000个字符),我想为它计算校验和。

要求

  • 每次对字符串进行计算时,都必须返回相同的校验和
  • 校验和必须唯一(无冲突)
  • 我无法存储以前的ID以检查冲突

我应该使用哪种算法?

更新:

  • 是否有一种合理且独特的方法?即碰撞的可能性非常小
  • 校验和应为字母数字
  • 字符串是unicode
  • 字符串实际上是应该翻译的文本,校验和与每次翻译一起存储(因此翻译后的文本可以与原始文本匹配)
  • 校验和的长度对我来说并不重要(越短越好)

更新2

假设我得到了以下字符串"Welcome to this website. Navigate using the flashy but useless menu above"

该字符串在视图中的使用方式与linux中的gettext类似。即用户只写(在剃刀视图中)

@T("Welcome to this website. Navigate using the flashy but useless menu above")

现在我需要一种识别该字符串的方法,这样我就可以从数据源获取它(数据源有几种实现)。必须使用整个字符串作为密钥似乎有点低效,因此我正在寻找一种从中生成密钥的方法。

计算字符串的校验和

这是不可能的。

如果不能存储以前的值,则无法创建小于字符串中信息的唯一校验和。

更新:

术语";"相当独特";没有意义,要么它是独一无二的,要么它不是。

为了获得相对较低的哈希冲突风险,可以使用相当大的哈希代码。

MD5算法例如产生一个16字节的散列码。使用某些保留所有字符的编码将字符串转换为字节数组,例如UTF-8,使用MD5类计算哈希代码,然后使用BitConverter类将哈希代码字节数组转换为字符串:

string theString = "asdf";
string hash;
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) {
  hash = BitConverter.ToString(
    md5.ComputeHash(Encoding.UTF8.GetBytes(theString))
  ).Replace("-", String.Empty);
}
Console.WriteLine(hash);

输出:

912EC803B2CE49E4A541068D495AB570

您可以为此使用加密哈希函数。其中大部分在.Net 中可用

例如:

var sha1 = System.Security.Cryptography.SHA1.Create();
byte[] buf = System.Text.Encoding.UTF8.GetBytes("test");
byte[] hash= sha1.ComputeHash(buf, 0, buf.Length);
//var hashstr  = Convert.ToBase64String(hash);
var hashstr = System.BitConverter.ToString(hash).Replace("-", "");

注意:这是对原始问题的回答。

假设您希望校验和存储在固定大小的变量(即整数)中,则无法满足第二个约束。

校验和必须是唯一的(无冲突)

您无法避免冲突,因为不同的字符串将多于可能的校验和值。

我意识到这篇文章实际上很古老,但我偶然发现了它,并且在过去遇到过几乎相同的问题。我们需要查找一个nvarchar(8000)字段。

我们的解决方案是使用讨厌的查找字段的CHECKSUM创建一个持久化的计算列。我们有一个自动递增的ID字段,并键入(校验和,ID)

从表中读取时,我们编写了一个proc,它获取查找文本,计算校验和,然后获取校验和相等和文本相等的位置。

您可以根据上面的答案在应用程序级别轻松地执行校验和部分,并手动存储它们,而不是使用我们以DB为中心的解决方案。但关键是要获得一个大小合理的索引键,这样您的文本比较就可以针对一桶冲突而不是整个数据集进行。

祝你好运!

为了保证唯一性,对于几乎无限大的字符串,将可变长度字符串视为一组串联的子字符串,每个子字符串的长度为"x个字符"。您的哈希函数只需要确定最大子字符串长度的唯一性,然后生成一系列校验和数字来生成值。可以将其视为具有一组校验和数字的等效网络IP地址。

碰撞的问题是假设碰撞会强制使用较慢的搜索方法来解决每次碰撞。如果与哈希对象的数量相比,它们的可能冲突数量微不足道,那么作为一个整体,额外的开销将变为NIL。冲突是由于表的大小小于对象的最大数量。这种情况不一定是这样,因为表可能有"洞",并且表中的每个对象在碰撞时都可能有对象的引用计数。只有当此计数大于1时,才会发生冲突或同一子字符串的多个实例。