创建短哈希的最佳方法是什么,类似于小的Url呢?

Arr*_*n S 43 .net c# hash short-url

我目前正在使用MD5哈希,但我想找到一些会创建一个只使用[az] [AZ] [0-9]的较短哈希的东西.它只需要大约5-10个字符长.

那里有什么东西已经做到了吗?

更新:

我喜欢CRC32哈希.在.NET中有一种干净的计算方法吗?

UPDATE2:

我正在使用Joe提供的链接中的CRC32功能.如何将uInt转换为上面定义的字符?

Vla*_*lad 51

.NET字符串对象具有GetHashCode()函数.它返回一个整数.将其转换为十六进制,然后转换为8个字符长的字符串.

像这样:

string hashCode = String.Format("{0:X}", sourceString.GetHashCode());
Run Code Online (Sandbox Code Playgroud)

更多内容:http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx

更新:在上面的链接中添加了对此答案的评论:

GetHashCode的行为取决于其实现,该实现可能从公共语言运行库的一个版本更改为另一个版本.可能发生这种情况的原因是为了提高GetHashCode的性能.

如果两个字符串对象相等,则GetHashCode方法返回相同的值.但是,每个唯一字符串值都没有唯一的哈希码值.不同的字符串可以返回相同的哈希码.

来电者须知

GetHashCode返回的值取决于平台.它在32位和64位版本的.NET Framework上有所不同.

  • String.GetHashCode的唯一问题是它将在不同的平台上生成不同的值(32位与64位).如果您希望不同的应用程序生成和使用哈希代码,则需要小心. (8认同)
  • 正如Brenda所说,GetHashCode()在32和64系统上是不同的.并且,.net 1.1和2.0 CLR之间甚至是不同的.但最重要的是,GetHashCode()不保证是唯一的!您可以从两个不同的字符串中获取相同的哈希值(我知道,它在生产环境中发生在我身上). (6认同)
  • 这是一个非常糟糕的主意,因为为给定类生成哈希码的确切算法是一个永远不应该持久化的实现细节,因为它可以在.NET版本之间进行更改.事实上,它在.NET版本之间发生了变化. (4认同)

Sco*_*ski 35

您的目标是创建URL缩短器还是创建哈希函数?

如果您的目标是创建URL缩短器,那么您不需要哈希函数.在这种情况下,您只需要预先生成一系列加密安全随机数,然后将每个要编码的URL分配给序列中的唯一编号.

您可以使用以下代码执行此操作:

using System.Security.Cryptography;

const int numberOfNumbersNeeded = 100;
const int numberOfBytesNeeded = 8;
var randomGen = RandomNumberGenerator.Create();
for (int i = 0; i < numberOfNumbersNeeded; ++i)
{
     var bytes = new Byte[numberOfBytesNeeded];
     randomGen.GetBytes(bytes);
}
Run Code Online (Sandbox Code Playgroud)

使用加密数字生成器将使人们很难预测您生成的字符串,我认为这对您很重要.

然后,您可以使用字母表中的字符将8字节随机数转换为字符串.这基本上是基础计算的变化(从基数256到基数62).

  • *"人们难以预测你生成的字符串,我认为这对你很重要"* - 啊哈,这可能是真的,给定Arron的*"它只需要大约5-10个字符"*.这不会像TinyURL.com那样,所以现在是时候Arron给了我们更多的细节! (2认同)

jör*_*örg 16

我不认为URL缩短服务使用哈希值,我认为它们只有一个运行的字母数字字符串,每个新URL都会增加并存储在数据库中.如果你真的需要使用哈希函数看一下这个链接:一些哈希函数 还有一点offtopic但是根据你正在做的事情这可能很有趣:Coding Horror article


Kin*_*tor 12

只需使用条目ID的Base36(不区分大小写)或Base64.

所以,假设我想使用Base36:

(ID - Base36)
1 - 1
2 - 2
3 - 3
10 - A
11 - B
12 - C
...
10000 - 7PS
22000 - GZ4
34000 - Q8C
...
1000000 - LFLS
2345000 - 1E9EW
6000000 - 3KLMO

如果你使用base64,你可以保持这些更短但后面的URL将区分大小写.你可以看到你仍然得到你漂亮,整洁的字母数字键,并保证不会发生碰撞!

  • 我喜欢这个。:) +1 但是我们如何在 .net 中快速做到这一点? (2认同)

Arj*_*jan 7

您不能使用哈希,因为您需要从短版本到实际值的一对一映射.对于短哈希,碰撞的可能性太高.正常的,长的哈希,不会非常用户友好(即使碰撞的可能性很小,那么它仍然不会对我感觉"正确").

TinyURL.com 似乎使用递增的数字转换为Base 36(0-9,AZ).


Fil*_*sky 5

首先,我得到一个随机不同数字的列表。然后我char从基本字符串中选择每个,追加并返回结果。我选择 5 个字符,这将相当于基于 62 的 6471002 个排列。第二部分是检查数据库以查看是否存在,如果不保存短网址。

 const string BaseUrlChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

 private static string ShortUrl
 {
     get
     {
         const int numberOfCharsToSelect = 5;
         int maxNumber = BaseUrlChars.Length;

         var rnd = new Random();
         var numList = new List<int>();

         for (int i = 0; i < numberOfCharsToSelect; i++)
             numList.Add(rnd.Next(maxNumber));

         return numList.Aggregate(string.Empty, (current, num) => current + BaseUrlChars.Substring(num, 1));
      } 
  }
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢它可以让您轻松控制字符,允许您排除视觉上不明确的字符,例如 0、O、l、I、1 等。 (2认同)