用于生成唯一数字的 C# 按位操作

标签 c# algorithm c#-4.0 unique bit-manipulation

我试图在 DateTime 刻度和递增数字的帮助下在 C# 中生成唯一值。 伪代码:

  1. 从 DateTime.Now 滴答中取出最后 43 位有效位(我们将其命名为 A)
  2. 从递增序列中取出最后 21 位(我们将其命名为“B”)
  3. 左移“A”21 次(我们将其命名为“C”)
  4. 在 A 和 C 中进行二元或运算

我运行了生成 200 万个数字并插入到具有唯一约束集的数据库列的测试,它运行成功。

这是执行此操作的代码片段:

    private static long _sequence = 1;
    public static long GetUniqueNumber()
        {
            const int timeShift = 21;            
            var dateTime = DateTime.Now.Ticks;
            const long dateTimeMask = ~(0L) >> timeShift; 
            const long sequenceMask = ((~(0L) >> (64 - timeShift))); 
            var seq = Interlocked.Increment(ref _sequence);
            var dateTimeNo = (dateTimeMask & dateTime) << timeShift;
            var seqNum = (seq & sequenceMask);    
            var num = dateTimeNo | seqNum;
            return num;
        }

我有两个问题: 1. 这个逻辑是否足以生成唯一数字? 2. 我发现一些生成的数字是'-ve',我不明白。

欢迎任何帮助/建议/改进。

最佳答案

Is this logic good enough to generate unique numbers

在什么范围内是独一无二的?跨多台计算机/进程/AppDomain?当然不是。在单个 AppDomain 中?并不真地。生成 200 万个数字无关紧要 - 只是测试您的序列部分是否有效。 (221 刚刚超过 200 万。)

如果您可以在 DateTime.Now 的粒度内调用 GetUniqueNumber 221+1 次(这可能是 ~10- 15ms)然后你会得到一个重复。您是否测量过您的计算机调用它的速度有多快?

那么这 43 位将在 2<​​sup>43 滴答的时间内重复......或者至少如果你有一个足够细粒度的时钟。 (粒度迟早会对您不利。)

I find that some generated numbers are '-ve' which I didn't understand.

每当 dateTimeNo 设置了它的最高位(共 43 个)时,您将得到一个设置了最高位的 long - 这意味着它将是否定的。

编辑:另请注意,您的换档已损坏。这:

const long dateTimeMask = ~(0L) >> timeShift;

执行了一个符号扩展移位 - 所以你只是以 ~0L 结束。

简而言之:使用Guid.NewGuid .这就是它的用途。

关于用于生成唯一数字的 C# 按位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9902153/

相关文章:

c# - NLog "final"规则的 Serilog 替代方案

algorithm - 3路和2路合并排序不失一般性?

.net - 单击后如何保持打开 rad 菜单?

wpf - 没有任何焦点的键绑定(bind)

c# - JavaScriptSerializer.Deserialize - 如何更改字段名称

c# - OnTriggerEnter 不适用于 Unity3D

algorithm - 如何计算覆盖网格中占用的单元格所需的最小矩形数量?

c++ - 范围树构建

c# - 套接字缓冲区大小 : pros and cons of bigger vs smaller

c# - .NET Core 3.1 中具有自定义策略的 IdentityServer4 LocalApi