【问题标题】:Class For generating Random Code生成随机码的类
【发布时间】:2014-05-19 10:26:33
【问题描述】:

我写了这个类来生成一个随机代码,它不应该创建任何两个重复的数字。 我想知道,在这段代码中,我们发生碰撞的可能性有多大?

 public string MyRandom()
 {
    Random r = new Random();
    int x = r.Next(1000);//Max range
    PersianCalendar pc = new PersianCalendar();
     string _myrandom = pc.GetMonth(DateTime.Now).ToString() + pc.GetDayOfMonth(DateTime.Now).ToString() + pc.GetHour(DateTime.Now).ToString() + pc.GetMinute(DateTime.Now).ToString() + pc.GetSecond(DateTime.Now).ToString() + pc.GetMilliseconds(DateTime.Now).ToString() + x.ToString();

    return _myrandom;
 }

【问题讨论】:

  • 如果您在循环中调用它,则很可能会发生碰撞。您需要删除该随机变量并将其粘贴到方法之外或为其提供方法参数。旁注:我会将DateTime.Now 存储在一个变量中,它并不像人们想象的那样便宜
  • 我没有在循环中使用那个类,这个生成器用于命名在我的应用程序中上传的照片。
  • 我假设因为我在其中使用 GetMilliseconds,我们从来没有发生过冲突,这不对吗?
  • @user3117091 好吧,不。如果您有多个线程同时尝试保存文件,则可以保证发生冲突。认真阅读 L-Three 发布的内容。 stackoverflow.com/questions/1654887/…

标签: c# asp.net datetime random calendar


【解决方案1】:

如果我们这样做

List<string> s = new List<string>();

for(int i = 0; i < 100; i++)
{
    s.Add(MyRandom());
}

为什么? 在循环中创建随机类时,您可以获得重复的随机数。 More Info

解决方案: 在循环外创建随机实例。

【讨论】:

  • 谢谢,但我只在我想保存我的照片并且我需要一个唯一的名称时才调用它,怎么样?
【解决方案2】:

使用更强大的方法(例如RNGCryptoServiceProvider)更安全,您可以找到几个使用示例。一般来说,纯随机生成不可能是很高的并发负载,而是将其概率降低到一个合理的量。

【讨论】:

    【解决方案3】:

    首先,因为您正在以您的方式使用日期,所以每年只有一毫秒可能重复 _myrandom 字符串。

    在每年的那一毫秒内,命中您已经生成的随机字符串的几率下降到变量 x,并且与您在该毫秒内生成的其他随机字符串的数量直接相关(以及之前每个毫秒的前几毫秒)年)。例如,如果您去年在该毫秒内创建了 10 个随机字符串,而在前一年创建了 4 个,那么今年重复的机会是 14:999,即大约 1.4% 的机会。

    当然,如果你每毫秒生成 1000 个字符串,重复的机会是 100%。

    事实上,由于 C# 随机数生成器不会产生真正的随机数,因此重复的可能性略高。这是一个伪随机数,因此发生碰撞的可能性更高。


    我看到您在上面的 cmets 中写道:“此生成器用于命名在我的应用程序中上传的照片”,这使得您不太可能每毫秒生成 1000 多个名称。通常,每当您以这种方式使用随机数生成器时,最好以两种方式之一进行一些错误检查: 1. 进攻或 2. 防守。

    进攻性将等待错误(两个相同的文件名)发生然后处理它(可能再次运行您的随机生成器,直到不抛出错误)。防御性方法是检查文件中的所有文件名,或保留所有文件名,以检查您的新文件名是否相同,然后再尝试保存它。这更加无懈可击(因为您不依赖于抛出错误),但计算成本要高得多。

    【讨论】:

    • 这可能更安全 - 是的。但同样,如果您每毫秒生成的名称超过 1 个,那么您可能会发生冲突。如果你从不打算EVER每毫秒生成2,你甚至不需要随机数,但如果你有可能在一毫秒内生成2,我建议您执行某种检查以防止潜在的错误。
    • 我认为即使我每毫秒创建 2 个名称,该 x 变量也会防止冲突,或者至少会减少冲突?
    • 它会大大减少碰撞的机会,是的,但它不会阻止碰撞。如果你每毫秒生成 2 个字符串,那么发生碰撞的几率就在 0.1% 以上。如果有任何发生碰撞的可能性,我建议您在尝试保存之前进行错误处理或采取预防措施检查碰撞。
    • 所以我可以将生成的 _myrandom 保存在一个数组中,并在每次分配给照片之前检查它
    • 你可以这样做,或者遍历目录中当前所有文件的名称来检查冲突。当然,您实际上需要做的就是检查与该毫秒生成的所有随机数 (x) 是否发生冲突(如果您还将年份添加到字符串中,这会更容易,因为您可以每毫秒清空一次数组并且不需要为明年存储它)。或者,您可以捕获“文件名已存在”错误并尝试创建一个不存在的新文件名。
    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    相关资源
    最近更新 更多