如何生成唯一的8位数?

时间:2011-05-23 22:09:39

标签: c# numbers unique

我正在使用此代码生成一个8位数的唯一编号。

byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToUInt32(buffer, 8).ToString();

此代码是否真的生成一个唯一的数字,或者它可能会再次重复相同的数字?

9 个答案:

答案 0 :(得分:9)

任何随机序列都必然会发生一些碰撞。这只是时间问题。使用具有100,000,000个可能值(8位数)的生日悖论公式,您与仅10,000个元素发生碰撞的可能性大约为40%,99%具有30,000个元素。 (see here for a calculator)。

如果您确实需要随机序列,则不应为此目的使用GUID。 GUID具有非常特定的结构,只能作为一个整体。很容易创建一个随机的8位序列发生器。这应该给你一个8位数的序列:

 public string Get8Digits()
 {
   var bytes = new byte[4];
   var rng = RandomNumberGenerator.Create();
   rng.GetBytes(bytes);
   uint random = BitConverter.ToUInt32(bytes, 0) % 100000000;
   return String.Format("{0:D8}", random);
 }

您也可以将RandomNumberGenerator放在某处,以避免每次都创建一个新的。

答案 1 :(得分:9)

GUID不仅仅是一个随机数;它由细分组成。如果在同一台计算机上生成guid,则某些段将不会发生任何变化。通过仅使用原始128位的64位,您将破坏guid的结构,并且最有可能打破生成的数字的唯一性。

这个question有更多关于guids唯一性的信息,请查看this link以及更多信息,了解如果您需要一个唯一的数字,为什么只使用部分guid是不好的。

如果您需要将重复限制在绝对最小值,增量计数器将为您提供所需的功能。如果您的应用程序使用多个线程或进程,则计数器可能很难(甚至不可能)正确实现。

这是guids设计的领域,在多台机器上是独一无二的。因此,如果需要跨机器的唯一性,则应使用guids。整个指南。

答案 2 :(得分:4)

这是另一个版本

public static string GetFormNumber()
    {
        byte[] buffer = Guid.NewGuid().ToByteArray();
        var FormNumber = BitConverter.ToUInt32(buffer, 0) ^ BitConverter.ToUInt32(buffer, 4) ^ BitConverter.ToUInt32(buffer, 8) ^ BitConverter.ToUInt32(buffer, 12);
        return FormNumber.ToString("X");

    }

它确保独一无二!

答案 3 :(得分:3)

我的第一个答案没有解决唯一性问题。我的第二个做了:

static int counter;
public static int GetUniqueNumber()
{ 
    return counter++; 
}

如果您希望在重新启动应用程序时拥有唯一的数字,则需要在每次GetUniqueNumber调用之后将计数器的值保存到数据库或其他位置。

答案 4 :(得分:2)

值的范围太小。递增计数器是最佳解决方案,如在ERP系统中 - 您将第一个客户编号设置为1000,下一个客户编号为1001,1002,...,99999999。否则,如果您从这些中获得一个随机数(或GUID的一部分),您将再次使用相同的数字。取决于您的应用程序,迟早会发生,但保证比尽快迭代它们更快。

答案 5 :(得分:2)

这个方法会生成一个随机字符串,它不依赖于Random方法,也比guid approch要好得多:

public static string gen_Digits(int length)
{
    var rndDigits = new System.Text.StringBuilder().Insert(0, "0123456789", length).ToString().ToCharArray();
    return string.Join("", rndDigits.OrderBy(o => Guid.NewGuid()).Take(length));
}

您可以增加长度以减少碰撞几率,但要拥有100%唯一序列,您必须保留旧生成的值并检查新创建的值以进行统一。

答案 6 :(得分:1)

如果您想要一个介于10000000和99999999之间的唯一编号,请从10000000开始一个整数,然后开始递增它。生成顺序排序的数字并不比任何其他生成的序列更随机,并且更容易生成。

答案 7 :(得分:0)

如果你将no表示为日(2digit),小时(2digit),分钟(2digit),second(2digit)和year(4位)的组合,那么它将是12位数,但总是唯一的。 / p>

 DateTime _now = DateTime.Now;
 string _dd = _now.ToString("dd"); //
 string _mm = _now.ToString("MM");
 string _yy = _now.ToString("yyyy");
 string _hh = _now.Hour.ToString();
 string _min = _now.Minute.ToString();
 string _ss = _now.Second.ToString();

 string _uniqueId= _dd+ _hh+ _mm+_min+_ss + _yy;

答案 8 :(得分:0)

System.Threading.Thread.Sleep(1);
long code = (long)DateTime.UtcNow.Subtract(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;

OR

System.Threading.Thread.Sleep(1000);
long code = (long)DateTime.UtcNow.Subtract(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;