C# 如何生成URL中使用的唯一12位字母数字键
有没有一种方法可以生成唯一的字母数字键(12位数字)用于C#中的URL?我有一组彼此唯一的字符串,但不能直接使用它们,因为它们可能会更改,因此URL将中断。我有两种方法- a) 使用数据库表本身的主键,该主键对应于具有上述字符串集的行,但这似乎是一个安全问题,因为它将公开db结构 b) 使用Guid,但它不依赖于数据C# 如何生成URL中使用的唯一12位字母数字键,c#,asp.net-mvc,C#,Asp.net Mvc,有没有一种方法可以生成唯一的字母数字键(12位数字)用于C#中的URL?我有一组彼此唯一的字符串,但不能直接使用它们,因为它们可能会更改,因此URL将中断。我有两种方法- a) 使用数据库表本身的主键,该主键对应于具有上述字符串集的行,但这似乎是一个安全问题,因为它将公开db结构 b) 使用Guid,但它不依赖于数据 任何帮助都将不胜感激。简短回答:否 你所尝试的是不可能的。您必须跟踪已创建的ID。这就是数据库对递增的索引列所做的 所有这些,以及其他一些答案 在fiddle中,我们对第一个示例中
任何帮助都将不胜感激。简短回答:否 你所尝试的是不可能的。您必须跟踪已创建的ID。这就是数据库对递增的索引列所做的 所有这些,以及其他一些答案 在fiddle中,我们对第一个示例中的主键进行哈希运算。因为只有完整的散列在计算上是不可行的,每个输入都不唯一,而且因为我们使用的是散列的子字符串,所以不能保证唯一性,但它可能很接近 以下是MSDN对哈希唯一性的看法 加密散列函数的特性是,在计算上不可能找到散列为相同值的两个不同输入 在第二个例子中,我们使用的是时间,据我所知,递增时间保证是唯一的,所以如果你可以相信时间是准确的,这将起作用。但是,如果要依赖服务器时间之类的外部资源,那么可能应该在数据库表或简单的平面文件中使用自动递增索引
using System;
using System.Text;
using System.Security.Cryptography;
public class Program
{
public static void Main()
{
UseAHash();
UseTime();
}
public static void UseAHash()
{
var primaryKey = 123345;
HashAlgorithm algorithm = SHA1.Create();
var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(primaryKey.ToString()));
StringBuilder sb = new StringBuilder();
for (var i = 0; i < 6; ++i)
{
sb.Append(hash[i].ToString("X2"));
}
Console.WriteLine(sb);
}
public static void UseTime()
{
StringBuilder builder = new StringBuilder();
// use universal to avoid daylight to standard time change.
var now = DateTime.Now.ToUniversalTime();
builder.Append(now.DayOfYear.ToString("D3"));
builder.Append(now.Hour.ToString("D2"));
builder.Append(now.Minute.ToString("D2"));
builder.Append(now.Second.ToString("D2"));
builder.Append(now.Millisecond.ToString("D3"));
Console.WriteLine("Length: " + builder.Length);
Console.WriteLine("Result: " + builder);
}
}
使用系统;
使用系统文本;
使用System.Security.Cryptography;
公共课程
{
公共静态void Main()
{
UseAHash();
使用时间();
}
公共静态void UseAHash()
{
var primaryKey=123345;
HashAlgorithm=SHA1.Create();
var hash=algorithm.ComputeHash(Encoding.UTF8.GetBytes(primaryKey.ToString());
StringBuilder sb=新的StringBuilder();
对于(变量i=0;i<6;++i)
{
sb.Append(hash[i].ToString(“X2”);
}
(某人);
}
公共静态void UseTime()
{
StringBuilder=新的StringBuilder();
//使用“通用”可避免日光到标准时间的变化。
var now=DateTime.now.ToUniversalTime();
Append(now.DayOfYear.ToString(“D3”);
builder.Append(now.Hour.ToString(“D2”);
builder.Append(now.Minute.ToString(“D2”);
builder.Append(现在是.Second.ToString(“D2”);
Append(现在是.毫秒.ToString(“D3”);
Console.WriteLine(“长度:+builder.Length”);
Console.WriteLine(“结果:+builder”);
}
}
您可以使用数据库中的密钥为随机生成器设定种子,并使用该种子创建密钥:
int id = 42;
string chars = "2345679abcdefghjkmnpqrstuvwxyz";
Random rnd = new Random(id);
string key = new String(Enumerable.Range(0, 12).Select(n => chars[rnd.Next(chars.Length)]).ToArray());
注意:这不保证是唯一的。但是我测试了从1到10000000的值,没有重复项。简单。创建一个新GUID,从数据库中为其分配一个实体,然后将其添加到数据库表中
public class FooGuid
{
[Key] public Guid Url { get; set; }
public Foo Foo { get; set; }
}
Guid urlpart = ...
Foo foo = dbContext.FooGuids
.Where(f => f.Url == urlpart)
.Select(f => f.Foo)
.Single();
它必须是唯一的还是伪唯一的?即使是
GUID
也不是唯一的,事实上也是如此。这可能是重复的:这是我不希望使用Guid的另一个原因,因为它必须在链接中使用,而链接必须是唯一的,原因很明显。如果它只需要在数据库中是唯一的,那么使用主键但对其进行散列(或类似的过程)可能是一个好方法。出于好奇,您知道与使用主键的SHA1散列然后获取前12个字符的方法相比,创建唯一的12个字符字符串的几率是低还是高吗?@ShaunLuttin:散列代码是专门为提供良好的分布而设计的,所以一般来说,这会降低碰撞风险。OP要求的是唯一的12位字母数字键。@SriramSakthivel好的。我知道。问题是什么?当问题是关于唯一性时,您如何建议哈希?你不知道散列冲突吗?你的编辑:即使是完整的散列也不能保证是唯一的。例如,两个完全不同的输入字符串可以产生相同的哈希。@SriramSakthivel足够公平。它可能不是完全独一无二的;这只是计算上不可行的。这就是为什么时间做事的方式可能更好。