【问题标题】:Generate a unique id生成唯一标识
【发布时间】:2012-07-03 14:33:14
【问题描述】:

我是一名大学生,我们的任务是创建一个搜索引擎。当添加到边界时,我很难生成分配给每个 url 的唯一 ID。我曾尝试使用 SHA-256 散列算法以及 Guid。这是我用来实现 guid 的代码:

public string generateID(string url_add)
{
    long i = 1;

    foreach (byte b in Guid.NewGuid().ToByteArray())
    {
        i *= ((int)b + 1);
    }

    string number = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 1000000000);

    return number;
}

【问题讨论】:

  • 一个 GUID 必然是全局唯一的(因此得名),所以我不明白这个问题。
  • 我认为他担心的是他希望 ID 基于 URL 是唯一的,因此 URL 的单向哈希到唯一 ID。在这种情况下,SHA1 可以工作。
  • 总是有object.GetHashCode()。虽然我认为这不能保证是独一无二的。
  • @RichardTowers 这几乎可以保证不是唯一的
  • 简单回答:return url_add;

标签: c# asp.net .net uniqueidentifier


【解决方案1】:

为什么不直接使用 ToString?

public string generateID()
{
    return Guid.NewGuid().ToString("N");
}

如果您希望它基于 URL,您只需执行以下操作:

public string generateID(string sourceUrl)
{
    return string.Format("{0}_{1:N}", sourceUrl, Guid.NewGuid());
}

如果您想隐藏 URL,您可以在 sourceURL 上使用某种形式的 SHA1,但我不确定这会实现什么。

【讨论】:

  • 这行得通...我最初希望 id 基于 url 但这似乎工作正常。它是否能够生成大量唯一密钥?因为搜索引擎会处理大量的网址
  • 这将能够产生大约5,316,911,983,139,663,491,615,228,241,121,400,000 唯一值。
  • 非常感谢!这绰绰有余,因为当从边境检索 url 时,它们会被删除
  • 谢谢!基于网址也可以!我认为基于 url 将使其更加独特,并且减少碰撞的机会!非常感谢!!!
  • 哦,不!再次测试了基于 url 的代码,它没有工作......但第一个工作得非常好!
【解决方案2】:

为什么不使用GUID

Guid guid = Guid.NewGuid();
string str = guid.ToString();

【讨论】:

    【解决方案3】:

    这是一个类似于 id 生成器的“YouTube-video-id”,例如"UcBKmq2XE5a"

    StringBuilder builder = new StringBuilder();
    Enumerable
       .Range(65, 26)
        .Select(e => ((char)e).ToString())
        .Concat(Enumerable.Range(97, 26).Select(e => ((char)e).ToString()))
        .Concat(Enumerable.Range(0, 10).Select(e => e.ToString()))
        .OrderBy(e => Guid.NewGuid())
        .Take(11)
        .ToList().ForEach(e => builder.Append(e));
    string id = builder.ToString();
    

    它创建大小为 11 个字符的随机 ID。您也可以增加/减少它,只需更改 Take 方法的参数即可。

    0.001% 的重复次数为 1 亿次。

    【讨论】:

    • 您认为可以将此订单号用于电子商务吗?使用该方法是否有可能两个订单将获得相同的 id?考虑到可能会有 1K 或 10K 订单/天?
    • 我不建议在您的情况下使用上述方法。最好的选择是使用 Guid。也看看这个github.com/dotnet/aspnetcore/blob/master/src/Servers/Kestrel/…
    • 在我的情况下,如果我改写一下,我需要一些与您的解决方案完全相同的东西(大约 8 个字符的字母数字字符串),以便在电子商务应用程序中将其用作 OrderNo,我刚刚将您的解决方案添加到我的项目中 + 检查数据库中的重复项,如果是,则生成一个新的。 CorrelationIdGenerator 类适合我的场景吗?
    【解决方案4】:

    为什么我们不能如下创建一个唯一的 id。

    我们可以使用 DateTime.Now.Ticks 和 Guid.NewGuid().ToString() 组合在一起,形成一个唯一的 id。

    随着 DateTime.Now.Ticks 添加,我们可以找出创建唯一 ID 的日期和时间(以秒为单位)。

    请看代码。

    var ticks = DateTime.Now.Ticks;
    var guid = Guid.NewGuid().ToString();
    var uniqueSessionId = ticks.ToString() +'-'+ guid; //guid created by combining ticks and guid
    
    var datetime = new DateTime(ticks);//for checking purpose
    var datetimenow = DateTime.Now;    //both these date times are different.
    

    我们甚至可以获取唯一id中的tick部分,并在以后检查日期和时间以供将来参考。

    【讨论】:

      【解决方案5】:

      如果您想使用 sha-256(guid 会更快),那么您需要执行类似的操作

      SHA256 shaAlgorithm = new SHA256Managed();
      byte[] shaDigest = shaAlgorithm.ComputeHash(ASCIIEncoding.ASCII.GetBytes(url));
      return BitConverter.ToString(shaDigest);
      

      当然,它不一定是 ascii,也可以是任何其他类型的哈希算法

      【讨论】:

      • 我会避免使用 ASCII 来支持一些 unicode 编码。给定您的代码,很容易找到冲突。
      • 我知道,这是因为我目前正在使用旧系统,所以我使用 ascii :)
      • 我希望 id 基于 url 是唯一的。这就是我想生成代码的方式
      【解决方案6】:

      这个问题似乎已经得到解答,但为了完整起见,我会添加另一种方法。

      您可以使用基于 Twitter 的Snowflake id 生成器的唯一 ID 号生成器。 C#实现可以在here找到。

      var id64Generator = new Id64Generator();
      
      // ...
      
      public string generateID(string sourceUrl)
      {
          return string.Format("{0}_{1}", sourceUrl, id64Generator.GenerateId());
      }
      

      请注意,该方法的一个非常好的特性是可以在独立节点上拥有多个生成器(可能对搜索引擎有用),生成实时的全局唯一标识符。

      // node 0
      var id64Generator = new Id64Generator(0);
      
      // node 1
      var id64Generator = new Id64Generator(1);
      
      // ... node 10
      var id64Generator = new Id64Generator(10);
      

      【讨论】:

      • 感谢您的提示!正是我想要的。
      • github.com/RobThree/IdGen 有一个带有代码的 NuGet,它也有类似的基于雪花的 id。 FlakeId 的 codeplex 代码是否归您所有?如果可以的话,我想把它放到 github 上做一个 nuget?
      • @dotnetguy,是的,我拥有那个。当然,你可以跟随 github 迁移和 nuget 包。
      【解决方案7】:

      我们可以这样做

      string TransactionID = "BTRF"+DateTime.Now.Ticks.ToString().Substring(0, 10);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-06
        • 1970-01-01
        • 2011-08-06
        • 1970-01-01
        • 2017-10-20
        • 1970-01-01
        相关资源
        最近更新 更多