我目前使用MD5哈希值,但我想找到的东西,将创建一个使用刚刚[AZ] [AZ]一个较短的散列[0-9]。 它仅需要大约5-10个字符长。
有什么在那里,已经这样做了?
更新:
我喜欢的CRC32散列。 是否有.NET计算它的一个干净的方式?
UPDATE2:
我使用的是从乔提供的链接CRC32功能。 我怎么能转换成UINT上面定义的角色?
我目前使用MD5哈希值,但我想找到的东西,将创建一个使用刚刚[AZ] [AZ]一个较短的散列[0-9]。 它仅需要大约5-10个字符长。
有什么在那里,已经这样做了?
更新:
我喜欢的CRC32散列。 是否有.NET计算它的一个干净的方式?
UPDATE2:
我使用的是从乔提供的链接CRC32功能。 我怎么能转换成UINT上面定义的角色?
.NET字符串对象具有的GetHashCode()函数。 它返回一个整数。 将其转换为十六进制,然后到8个字符长的字符串。
像这样:
string hashCode = String.Format("{0:X}", sourceString.GetHashCode());
更多的是: http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx
更新:从上面这个答案的链接添加了备注:
GetHashCode的的行为是依赖于它的实现,这可能会从公共语言运行库的一个版本到另一个改变。 出现这种情况的一个原因是提高的GetHashCode的性能。
如果两个字符串对象相等时,GetHashCode方法返回相同的值。 然而,并不是每一个唯一的字符串值独特的哈希码值。 不同的字符串可以返回相同的散列码。
注释呼叫者
通过的GetHashCode返回的值是依赖于平台的 。 它不同于在.NET Framework的32位和64位版本。
你的目标是创建一个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);
}
使用密码号发电机将使其很难为人们预测你生成,我认为重要的是你的字符串。
然后,可以将8字节的随机数转换成使用字符在字母表中的字符串。 这基本上是碱计算(从基站256到基座62)的变化。
我不认为URL缩短服务使用哈希,我认为他们只是有一个与每一个新的URL增加,存储在数据库中运行的字母数字字符串。 如果你确实需要使用散列函数看看这个链接: 一些散列函数而且,有点offtopic但根据您正在使用的这个可能是什么有趣: 编码恐怖的文章
只取的条目的ID的Base36(不区分大小写)或Base64。
因此,可以说,我想用Base36:
(ID - Base36)
1 - 1
2 - 2
3 - 3
10 - 一个
11 - B
12 - Visual C
...
10000 - 7PS
22000 - GZ4
34000 - Q8C
...
百万 - LFLS
2345000 - 1E9EW
6000000 - 3KLMO
你可以把这些更短,如果你用的base64去但随后URL的将是区分大小写的。 你可以看到你仍然可以得到你的好,整齐的字母数字键和一个保证不会有冲突!
因为你需要从短版一一对一映射到实际值不能使用短哈希。 对于短哈希碰撞的几率会高得离谱。 普通,长哈希的,不会是非常人性化的(而且即使对于碰撞的机会将可能是足够小的话,它仍然不会感到“权利”对我来说)。
TinyURL.com 似乎使用一个递增的数被转换成底座36 (0-9,AZ)。
您可以通过编码它们的字母数字减少从MD5哈希的字符数。 每个MD5字符通常表示为十六进制,所以这是16个可能的值。 [A-ZA-Z0-9]包括62个可能的值,因此你可以通过取4个MD5值编码每个值。
编辑:
这里是采用一个数(4个十六进制位长),并返回[0-9A-ZA-Z]的函数。 这应该给你如何实现它的想法。 请注意,可能有一些问题与类型; 我没有测试此代码。
char num2char( unsigned int x ){
if( x < 26 ) return (char)('a' + (int)x);
if( x < 52 ) return (char)('A' + (int)x - 26);
if( x < 62 ) return (char)('0' + (int)x - 52);
if( x == 62 ) return '0';
if( x == 63 ) return '1';
}
首先,我看到一些随机的不同号码的列表。 然后,我选择每个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));
}
}
您可以使用CRC32,它是8个字节长,类似MD5。 唯一值将加时间戳的实际价值支持。
因此,它会像http://foo.bar/abcdefg12 。
如果你正在寻找从半成品产生微小的唯一哈希库,我强烈推荐http://hashids.org/net/ 。 我用它在许多项目和它的作品充满了想象。 您还可以指定自己的角色自定义设置的哈希值。
如果你不关心加密强度,任何的CRC功能就行了。
维基百科列出一堆不同的散列函数,其中包括输出的长度。 它们的输出转换成[AZ] [AZ] [0-9]是微不足道的。
你可以使用Base64的十六进制,而不是你的编码MD5哈希码,这样你使用完全相同的字符[AZ] [AZ] [0-9]得到一个较短的网址。
有一个叫精彩,但古老的程序btoa
其使用大写和小写字母,数字和两个额外的字符转换二进制ASCII。 另外还有MIME base64编码; 大多数Linux系统可能有一个程序调用base64
或base64encode
。 无论是一个会给你从32位CRC很短的,可读的字符串。
你可以采取的MD5哈希的第一个字母数字字符5-10。