Is using Random and OrderBy a good shuffle algorithm?

前端 未结 12 1705
-上瘾入骨i
-上瘾入骨i 2020-11-21 11:41

I have read an article about various shuffle algorithms over at Coding Horror. I have seen that somewhere people have done this to shuffle a list:

var r = ne         


        
12条回答
  •  春和景丽
    2020-11-21 12:12

    I found Jon Skeet's answer to be entirely satisfactory, but my client's robo-scanner will report any instance of Random as a security flaw. So I swapped it out for System.Security.Cryptography.RNGCryptoServiceProvider. As a bonus, it fixes that thread-safety issue that was mentioned. On the other hand, RNGCryptoServiceProvider has been measured as 300x slower than using Random.

    Usage:

    using (var rng = new RNGCryptoServiceProvider())
    {
        var data = new byte[4];
        yourCollection = yourCollection.Shuffle(rng, data);
    }
    

    Method:

    /// 
    /// Shuffles the elements of a sequence randomly.
    /// 
    /// A sequence of values to shuffle.
    /// An instance of a random number generator.
    /// A placeholder to generate random bytes into.
    /// A sequence whose elements are shuffled randomly.
    public static IEnumerable Shuffle(this IEnumerable source, RNGCryptoServiceProvider rng, byte[] data)
    {
        var elements = source.ToArray();
        for (int i = elements.Length - 1; i >= 0; i--)
        {
            rng.GetBytes(data);
            var swapIndex = BitConverter.ToUInt32(data, 0) % (i + 1);
            yield return elements[swapIndex];
            elements[swapIndex] = elements[i];
        }
    }
    

提交回复
热议问题