Guid.NewGuid()VS来自Random.Next一个随机字符串发生器() [英] Guid.NewGuid() VS a random string generator from Random.Next()

查看:192
本文介绍了Guid.NewGuid()VS来自Random.Next一个随机字符串发生器()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和我的同事正在讨论在数据库中使用的这些方法自动生成用户ID和文章ID的识别:



可以选择使用单个实例随机的,并采取了一些有用的参数,以便它可以为各种串根的情况下(即由4位数字的管脚20位的字母数字IDS)被重用。下面的代码:

  //这是针对服务器实例
类RandomStringGenerator $ B $的寿命创建一次b {
公共常量字符串ALPHANUMERIC_CAPS =ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890;
公共常量字符串ALPHA_CAPS =ABCDEFGHIJKLMNOPQRSTUVWXYZ;
公共常量字符串NUMERIC =1234567890;

随机兰特=新的随机();
公共字符串GetRandomString(INT长度,则params的char []字符)
{
字符串s =;
的for(int i = 0; I<长度;我+ +)
S + =字符[rand.Next()%chars.Length]

返回小号;
}
}

和另一个选择就是使用:

  Guid.NewGuid(); 



看的Guid.NewGuid MSDN上



我们俩都知道, Guid.NewGuid( )将努力满足我们的需要,但我宁愿使用自定义的方法。它做同样的事情,但有更多的控制。



我的同事认为,由于自定义的方法已经熟了自己,它更可能产生冲突。我承认我不完全了解随机实施的,但我相信这只是随机的Guid.NewGuid()。自定义方法的典型用法可能是:



  RandomStringGenerator stringGen =新RandomStringGenerator(); 
字符串ID = stringGen.GetRandomString(20,RandomStringGenerator.ALPHANUMERIC_CAPS.ToCharArray());

修改1:




  • 我们正在使用的不具有自动递增(或类似)功能生成密钥Azure的表。

  • 一些答案​​这里只是告诉我使用NewGuid(),因为这是它是制造。我在寻找一个更深入的理由,为什么炮制方法可能更容易产生冲突给予同样的自由度为GUID的。



编辑2:



我们也采用炮制方法生成后的ID,不同于会话令牌,需要使自己显得漂亮摆放在我们的网站(如 http://mywebsite.com/14983336 )的网址,所以GUID是不是这里的选项,但是冲突仍然被避免。


解决方案

我要寻找一个更深度原因至于为什么炮制方法更可能以相同的自由度作为一个GUID来产生碰撞。




初,正如其他人所指出的,随机不是线程安全的;用它从多个线程可能会导致其损坏其内部数据结构,使其始终产生相同的序列。



二,随机基于当前时间播种。 随机的两个实例在同一毫秒内创建(记得,一毫秒等于几的亿的现代硬件处理器周期)将具有相同的种子,因此会产生相同的序列。



第三,我撒谎了。 随机不去籽基于当前的时间;它是基于的时间机器量一直活跃的接种。种子是一个32位的数字,并且由于粒度以毫秒为单位,直到它环绕的只有几个星期。但是,这不是问题;问题是:在其中创建随机的该实例的时间极有可能是机器的开机几分钟内。每次你关机后再开机一台机器,或在集群带来新机在网上,有将随机的实例创建了一个小窗口,出现这种情况的更多,更大的可能性是,你会得到一个种子。你收到



随着其他曾经说过:如果你想为你的数据库中的主键,然后的让数据库生成你的主键的;让数据库完成其工作。如果你想有一个全局唯一标识符和使用GUID ;这就是他们的东西。



最后,如果你有兴趣了解更多有关的GUID的使用和滥用,那么你可能想读我的GUID指南系列;第一部分是在这里:



http://blogs.msdn.com/b/ericlippert/archive/2012/04/24/guid-guide-part-one.aspx


My colleague and I are debating which of these methods to use for auto generating user ID's and post ID's for identification in the database:

One option uses a single instance of Random, and takes some useful parameters so it can be reused for all sorts of string-gen cases (i.e. from 4 digit numeric pins to 20 digit alphanumeric ids). Here's the code:

// This is created once for the lifetime of the server instance
class RandomStringGenerator
{
    public const string ALPHANUMERIC_CAPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    public const string ALPHA_CAPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public const string NUMERIC = "1234567890";

    Random rand = new Random();
    public string GetRandomString(int length, params char[] chars)
    {
        string s = "";
        for (int i = 0; i < length; i++)
            s += chars[rand.Next() % chars.Length];

        return s;
    }
}

and the other option is simply to use:

Guid.NewGuid();

see Guid.NewGuid on MSDN

We're both aware that Guid.NewGuid() would work for our needs, but I would rather use the custom method. It does the same thing but with more control.

My colleague thinks that because the custom method has been cooked up ourselves, it's more likely to generate collisions. I'll admit I'm not fully aware of the implementation of Random, but I presume it is just as random as Guid.NewGuid(). A typical usage of the custom method might be:

RandomStringGenerator stringGen = new RandomStringGenerator();
string id = stringGen.GetRandomString(20, RandomStringGenerator.ALPHANUMERIC_CAPS.ToCharArray());

Edit 1:

  • We are using Azure Tables which doesn't have an auto increment (or similar) feature for generating keys.
  • Some answers here just tell me to use NewGuid() "because that's what it's made for". I'm looking for a more in depth reason as to why the cooked up method may be more likely to generate collisions given the same degrees of freedom as a Guid.

Edit 2:

We were also using the cooked up method to generate post ID's which, unlike session tokens, need to look pretty for display in the url of our website (like http://mywebsite.com/14983336), so guids are not an option here, however collisions are still to be avoided.

解决方案

I am looking for a more in depth reason as to why the cooked up method may be more likely to generate collisions given the same degrees of freedom as a Guid.

First, as others have noted, Random is not thread-safe; using it from multiple threads can cause it to corrupt its internal data structures so that it always produces the same sequence.

Second, Random is seeded based on the current time. Two instances of Random created within the same millisecond (recall that a millisecond is several million processor cycles on modern hardware) will have the same seed, and therefore will produce the same sequence.

Third, I lied. Random is not seeded based on the current time; it is seeded based on the amount of time the machine has been active. The seed is a 32 bit number, and since the granularity is in milliseconds, that's only a few weeks until it wraps around. But that's not the problem; the problem is: the time period in which you create that instance of Random is highly likely to be within a few minutes of the machine booting up. Every time you power-cycle a machine, or bring a new machine online in a cluster, there is a small window in which instances of Random are created, and the more that happens, the greater the odds are that you'll get a seed that you had before.

As other have said: if you want a primary key for your database then have the database generate you a primary key; let the database do its job. If you want a globally unique identifier then use a guid; that's what they're for.

And finally, if you are interested in learning more about the uses and abuses of guids then you might want to read my "guid guide" series; part one is here:

http://blogs.msdn.com/b/ericlippert/archive/2012/04/24/guid-guide-part-one.aspx

这篇关于Guid.NewGuid()VS来自Random.Next一个随机字符串发生器()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆