如何生成 8 位的唯一数字
本文关键字:唯一 数字 何生成 | 更新日期: 2023-09-27 17:57:20
我正在使用此代码生成一个 8 位的唯一数字。
byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToUInt32(buffer, 8).ToString();
此代码是否真的生成一个唯一的数字,或者它可能会再次重复相同的数字?
GUID 不仅仅是一个随机数;它由段组成。如果在同一台计算机上生成 guid,则某些段根本不会更改。通过仅使用原始 128 位中的 64 位,您将破坏 guid 的结构,并且很可能破坏生成数字的唯一性。
此问题包含有关 guid 唯一性的更多信息,请查看此链接,了解有关为什么在需要唯一编号时仅使用部分 guid 是不好的的详细信息。
如果需要将重复限制在绝对最小值,增量计数器将为您提供所需的内容。如果应用程序使用多个线程或进程,则计数器可能很难(甚至不可能)正确实现。
这是 GUID 设计的目的领域,在多台计算机上是唯一的。因此,如果要求跨计算机的唯一性,则应使用 GUID。整个指南。
任何随机序列都必然会发生一些冲突。这只是时间问题。 使用生日悖论公式,使用 100,000,000 个可能的值(8 位数字),您仅与 10,000 个元素发生碰撞的几率约为 40%,与 30,000 个元素发生碰撞的几率约为 99%。(有关计算器,请参见此处)。
如果确实需要随机序列,则不应将 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);
}
您也可以使用随机数生成器并将其放置在某个位置,以避免每次都创建一个新的。
这是另一个版本
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");
}
它保证是独一无二的!
我的第一个答案没有解决唯一性问题。我的第二个是:
static int counter;
public static int GetUniqueNumber()
{
return counter++;
}
如果要在应用重新启动期间具有唯一编号,则需要在每次 GetUniqueNumber 调用后将计数器的值保留到数据库或其他位置。
值的范围太小。递增计数器是最好的解决方案,就像在ERP系统中一样 - 您将第一个客户编号设置为1000,下一个是1001,1002,...,99999999。否则,如果从这些数字中获取随机数(或 GUID 的一部分),则会再次命中相同的数字。根据您的应用,迟早会发生,但保证会比仅仅迭代它们更早发生。
此方法将生成一个随机字符串,它不依赖于 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% 唯一的序列,您必须保留旧的生成值并检查新创建的值的单性。
如果你想要一个介于 10000000 和 99999999 之间的唯一数字,请从 10000000 开始一个整数,然后开始递增它。生成顺序排序的数字的随机性不亚于任何其他生成的序列,并且更容易生成。
和年( 4 位)的组合,那么它将是 12 位,但始终是唯一的 no。
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;
System.Threading.Thread.Sleep(1);
long code = (long)DateTime.UtcNow.Subtract(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
或
System.Threading.Thread.Sleep(1000);
long code = (long)DateTime.UtcNow.Subtract(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;