代码之家  ›  专栏  ›  技术社区  ›  PushCode

返回相同字符串的随机字符串生成器[重复]

  •  221
  • PushCode  · 技术社区  · 15 年前

    我开发了一个随机字符串生成器,但它的性能并不像我希望的那样好。我的目标是能够运行这两次,并生成两个不同的四字符随机字符串。但是,它只生成一个四字符随机字符串两次。

    下面是代码及其输出示例:

    private string RandomString(int size)
    {
        StringBuilder builder = new StringBuilder();
        Random random = new Random();
        char ch;
        for (int i = 0; i < size; i++)
        {
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));                 
            builder.Append(ch);
        }
    
        return builder.ToString();
    }
    
    // get 1st random string 
    string Rand1 = RandomString(4);
    
    // get 2nd random string 
    string Rand2 = RandomString(4);
    
    // create full rand string
    string docNum = Rand1 + "-" + Rand2;
    

    …输出如下:unt-unte …但看起来应该像这个UNT-FWNU

    如何确保两个明显随机的字符串?

    31 回复  |  直到 8 年前
        1
  •  303
  •   RCIX    15 年前

    您在方法中创建了随机实例,这使得它在快速连续调用时返回相同的值。我会这样做:

    private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
    private string RandomString(int size)
        {
            StringBuilder builder = new StringBuilder();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));                 
                builder.Append(ch);
            }
    
            return builder.ToString();
        }
    
    // get 1st random string 
    string Rand1 = RandomString(4);
    
    // get 2nd random string 
    string Rand2 = RandomString(4);
    
    // creat full rand string
    string docNum = Rand1 + "-" + Rand2;
    

    (代码的修改版本)

        2
  •  185
  •   LukeH    15 年前

    您正在实例化 Random 对象。

    这个 随机的 对象是 seeded from the system clock ,也就是说,如果您连续多次快速调用方法,每次都将使用相同的种子,这意味着它将生成相同的随机数序列,这意味着您将获得相同的字符串。

    要解决问题,请移动 随机的 在方法本身之外的实例(当您在它上面时,您可以摆脱对 Convert Floor NextDouble ):

    private readonly Random _rng = new Random();
    private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    private string RandomString(int size)
    {
        char[] buffer = new char[size];
    
        for (int i = 0; i < size; i++)
        {
            buffer[i] = _chars[_rng.Next(_chars.Length)];
        }
        return new string(buffer);
    }
    
        3
  •  134
  •   Ranvir    14 年前

    //一个非常简单的实现

    using System.IO;   
    public static string RandomStr()
    
    {
        string rStr = Path.GetRandomFileName();
        rStr = rStr.Replace(".", ""); // For Removing the .
        return rStr;
    }
    

    //现在只需调用randomstr()方法

        4
  •  49
  •   Spongeboy    12 年前

    只要使用的是ASP.NET 2.0或更高版本,也可以使用库调用- System.Web.Security.Membership.GeneratePassword 但它将包含特殊字符。

    获取至少有0个特殊字符的4个随机字符-

    Membership.GeneratePassword(4, 0)
    
        5
  •  20
  •   Abdul Munim    13 年前

    只为路过的人以及在一行代码中有随机字符串的内容

    int yourRandomStringLength = 12; //maximum: 32
    Guid.NewGuid().ToString("N").Substring(0, yourRandomStringLength);
    

    附:请记住 yourRandomStringLength 不能超过32作为 Guid 最大长度为32。

        6
  •  12
  •   Community datashaman    7 年前

    另一个版本的字符串生成器。简单,没有花哨的数学和神奇的数字。但使用一些指定允许字符的神奇字符串。

    更新: 我将生成器设置为静态的,因此在多次调用时它不会返回相同的字符串。但是,此代码是 线程安全 而且绝对是 密码安全 .

    用于密码生成 System.Security.Cryptography.RNGCryptoServiceProvider 应该使用。

    private Random _random = new Random(Environment.TickCount);
    
    public string RandomString(int length)
    {
        string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
        StringBuilder builder = new StringBuilder(length);
    
        for (int i = 0; i < length; ++i)
            builder.Append(chars[_random.Next(chars.Length)]);
    
        return builder.ToString();
    }
    
        7
  •  12
  •   oleksii    10 年前

    此解决方案是对 Random 班级。

    用法

    class Program
    {
        private static Random random = new Random(); 
    
        static void Main(string[] args)
        {
            random.NextString(10); // "cH*%I\fUWH0"
            random.NextString(10); // "Cw&N%27+EM"
            random.NextString(10); // "0LZ}nEJ}_-"
            random.NextString();   // "kFmeget80LZ}nEJ}_-"
        }
    }
    

    实施

    public static class RandomEx
    {
        /// <summary>
        /// Generates random string of printable ASCII symbols of a given length
        /// </summary>
        /// <param name="r">instance of the Random class</param>
        /// <param name="length">length of a random string</param>
        /// <returns>Random string of a given length</returns>
        public static string NextString(this Random r, int length)
        {
            var data = new byte[length];
            for (int i = 0; i < data.Length; i++)
            {
                // All ASCII symbols: printable and non-printable
                // data[i] = (byte)r.Next(0, 128);
                // Only printable ASCII
                data[i] = (byte)r.Next(32, 127);
            }
            var encoding = new ASCIIEncoding();
            return encoding.GetString(data);
        }
    
        /// <summary>
        /// Generates random string of printable ASCII symbols
        /// with random length of 10 to 20 chars
        /// </summary>
        /// <param name="r">instance of the Random class</param>
        /// <returns>Random string of a random length between 10 and 20 chars</returns>
        public static string NextString(this Random r)
        {
            int length  = r.Next(10, 21);
            return NextString(r, length);
        }
    }
    
        8
  •  10
  •   Zygimantas    11 年前

    还有一个选择:

    public System.String GetRandomString(System.Int32 length)
    {
        System.Byte[] seedBuffer = new System.Byte[4];
        using (var rngCryptoServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider())
        {
            rngCryptoServiceProvider.GetBytes(seedBuffer);
            System.String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            System.Random random = new System.Random(System.BitConverter.ToInt32(seedBuffer, 0));
            return new System.String(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
        }
    }
    
        9
  •  7
  •   Ami Luttwak    12 年前

    最好的解决方案是将随机数生成器与base64转换一起使用。

    public string GenRandString(int length)
    {
      byte[] randBuffer = new byte[length];
      RandomNumberGenerator.Create().GetBytes(randBuffer);
      return System.Convert.ToBase64String(randBuffer).Remove(length);
    }
    
        10
  •  4
  •   John T    15 年前

    这是因为每一个新的随机实例都是通过这么快的调用生成相同的数字。 继续创建一个新实例,只需调用next()并在方法之外声明随机类。

        11
  •  4
  •   Alex    11 年前

    一个Linq One衬垫,用于良好测量(假设 private static Random Random )

    public static string RandomString(int length)
    {
        return new string(Enumerable.Range(0, length).Select(_ => (char)Random.Next('a', 'z')).ToArray());
    }
    
        12
  •  3
  •   Fabrício Matté    15 年前

    您应该让一个类级随机对象在构造函数中启动一次,并在每次调用时重复使用(这将继续使用相同的伪随机数序列)。无参数构造函数已在内部为生成器植入environment.tickCount。

        13
  •  2
  •   animuson    12 年前

    我添加了使用ranvir解决方案选择长度的选项

    public static string GenerateRandomString(int length)
        {
            {
                string randomString= string.Empty;
    
                while (randomString.Length <= length)
                {
                    randomString+= Path.GetRandomFileName();
                    randomString= randomString.Replace(".", string.Empty);
                }
    
                return randomString.Substring(0, length);
            }
        }
    
        14
  •  2
  •   quantum    12 年前

    下面是我对当前接受的答案的修改,我认为它更快、更短:

    private static Random random = new Random();
    
    private string RandomString(int size) {
        StringBuilder builder = new StringBuilder(size);
        for (int i = 0; i < size; i++)
            builder.Append((char)random.Next(0x41, 0x5A));
        return builder.ToString();
    }
    

    注意我没有用所有的乘法, Math.floor() , Convert 等。

    编辑: random.Next(0x41, 0x5A) 可以更改为任何Unicode字符范围。

        15
  •  2
  •   AechoLiu    11 年前

    我的 RandomString() 方法生成随机字符串。

    private static readonly Random _rand = new Random();
    
    /// <summary>
    /// Generate a random string.
    /// </summary>
    /// <param name="length">The length of random string. The minimum length is 3.</param>
    /// <returns>The random string.</returns>
    public string RandomString(int length)
    {
        length = Math.Max(length, 3);
    
        byte[] bytes = new byte[length];
        _rand.NextBytes(bytes);
        return Convert.ToBase64String(bytes).Substring(0, length);
    }
    
        16
  •  2
  •   wener    11 年前

    我想这也可以接受和简单。

    Guid.NewGuid().ToString() 
    
        17
  •  1
  •   CGsoldier    14 年前

    如果要为强密码生成一个数字和字符字符串。

    private static Random random = new Random();
    
    private static string CreateTempPass(int size)
            {
                var pass = new StringBuilder();
                for (var i=0; i < size; i++)
                {
                    var binary = random.Next(0,2);
                    switch (binary)
                    {
                        case 0:
                        var ch = (Convert.ToChar(Convert.ToInt32(Math.Floor(26*random.NextDouble() + 65))));
                            pass.Append(ch);
                            break;
                        case 1:
                            var num = random.Next(1, 10);
                            pass.Append(num);
                            break;
                    }
                }
                return pass.ToString();
            }
    
        18
  •  1
  •   Devin Burke Robert Isaev    13 年前

    将“pushcode”和使用种子的答案组合为随机生成器。我需要它来创建一系列伪可读的“单词”。

    private int RandomNumber(int min, int max, int seed=0)
    {
        Random random = new Random((int)DateTime.Now.Ticks + seed);
        return random.Next(min, max);
    }
    
        19
  •  1
  •   Hugo    12 年前

    我创建了这个方法。

    它很好用。

    public static string GeneratePassword(int Lenght, int NonAlphaNumericChars)
        {
            string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
            string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
            Random rd = new Random();
    
            if (NonAlphaNumericChars > Lenght || Lenght <= 0 || NonAlphaNumericChars < 0)
                throw new ArgumentOutOfRangeException();
    
                char[] pass = new char[Lenght];
                int[] pos = new int[Lenght];
                int i = 0, j = 0, temp = 0;
                bool flag = false;
    
                //Random the position values of the pos array for the string Pass
                while (i < Lenght - 1)
                {
                    j = 0;
                    flag = false;
                    temp = rd.Next(0, Lenght);
                    for (j = 0; j < Lenght; j++)
                        if (temp == pos[j])
                        {
                            flag = true;
                            j = Lenght;
                        }
    
                    if (!flag)
                    {
                        pos[i] = temp;
                        i++;
                    }
                }
    
                //Random the AlphaNumericChars
                for (i = 0; i < Lenght - NonAlphaNumericChars; i++)
                    pass[i] = allowedChars[rd.Next(0, allowedChars.Length)];
    
                //Random the NonAlphaNumericChars
                for (i = Lenght - NonAlphaNumericChars; i < Lenght; i++)
                    pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)];
    
                //Set the sorted array values by the pos array for the rigth posistion
                char[] sorted = new char[Lenght];
                for (i = 0; i < Lenght; i++)
                    sorted[i] = pass[pos[i]];
    
                string Pass = new String(sorted);
    
                return Pass;
        }
    
        20
  •  1
  •   Maciej Zaleski    12 年前

    这里还有一个基于guid的想法。我用它来 Visual Studio performance test 生成只包含字母数字字符的随机字符串。

    public string GenerateRandomString(int stringLength)
    {
        Random rnd = new Random();
        Guid guid;
        String randomString = string.Empty;
    
        int numberOfGuidsRequired = (int)Math.Ceiling((double)stringLength / 32d);
        for (int i = 0; i < numberOfGuidsRequired; i++)
        {
            guid = Guid.NewGuid();
            randomString += guid.ToString().Replace("-", "");
        }
    
        return randomString.Substring(0, stringLength);
    }
    
        21
  •  1
  •   n00begon Priidu Neemre    12 年前

    Here is a blog post 这为生成随机单词、句子和段落提供了一个更强大的类。

        22
  •  1
  •   Konard    11 年前
    public static class StringHelpers
    {
        public static readonly Random rnd = new Random();
    
        public static readonly string EnglishAlphabet = "abcdefghijklmnopqrstuvwxyz";
        public static readonly string RussianAlphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
    
        public static unsafe string GenerateRandomUTF8String(int length, string alphabet)
        {
            if (length <= 0)
                return String.Empty;
            if (string.IsNullOrWhiteSpace(alphabet))
                throw new ArgumentNullException("alphabet");
    
            byte[] randomBytes = rnd.NextBytes(length);
    
            string s = new string(alphabet[0], length);
    
            fixed (char* p = s)
            {
                for (int i = 0; i < s.Length; i++)
                {
                    *(p + i) = alphabet[randomBytes[i] % alphabet.Length];
                }
            }
            return s;
        }
    
        public static unsafe string GenerateRandomUTF8String(int length, params UnicodeCategory[] unicodeCategories)
        {
            if (length <= 0)
                return String.Empty;
            if (unicodeCategories == null)
                throw new ArgumentNullException("unicodeCategories");
            if (unicodeCategories.Length == 0)
                return rnd.NextString(length);
    
            byte[] randomBytes = rnd.NextBytes(length);
    
            string s = randomBytes.ConvertToString();
            fixed (char* p = s)
            {
                for (int i = 0; i < s.Length; i++)
                {
                    while (!unicodeCategories.Contains(char.GetUnicodeCategory(*(p + i))))
                        *(p + i) += (char)*(p + i);
                }
            }
            return s;
        }
    }
    

    您还需要:

    public static class RandomExtensions
    {
        public static string NextString(this Random rnd, int length)
        {
            if (length <= 0)
                return String.Empty;
    
            return rnd.NextBytes(length).ConvertToString();
        }
    
        public static byte[] NextBytes(this Random rnd, int length)
        {
            if (length <= 0)
                return new byte[0];
    
            byte[] randomBytes = new byte[length];
            rnd.NextBytes(randomBytes);
            return randomBytes;
        }
    }
    

    而这:

    public static class ByteArrayExtensions
    {
        public static string ConvertToString(this byte[] bytes)
        {
            if (bytes.Length <= 0)
                return string.Empty;
    
            char[] chars = new char[bytes.Length / sizeof(char)];
            Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
            return new string(chars);
        }
    }
    
        23
  •  1
  •   Stefan Steiger Marco van de Voort    11 年前

    实际上,一个好的解决方案是为随机数生成器提供一个静态方法,它是线程安全的,不使用锁。

    这样,多个同时访问您的Web应用程序的用户就不会得到相同的随机字符串。

    这里有3个例子: http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx

    我用最后一个:

    public static class RandomGen3
    {
        private static RNGCryptoServiceProvider _global = 
            new RNGCryptoServiceProvider();
        [ThreadStatic]
        private static Random _local;
    
        public static int Next()
        {
            Random inst = _local;
            if (inst == null)
            {
                byte[] buffer = new byte[4];
                _global.GetBytes(buffer);
                _local = inst = new Random(
                    BitConverter.ToInt32(buffer, 0));
            }
            return inst.Next();
        }
    }
    

    然后你可以适当地消除

    Random random = new Random();
    

    只需调用randomgen3.next(),而您的方法可以保持静态。

        24
  •  1
  •   Toprak    11 年前

    对于随机字符串生成器:

    #region CREATE RANDOM STRING WORD
            char[] wrandom = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','R','S','T','U','V','X','W','Y','Z'};
            Random random = new Random();
            string random_string = "";
            int count = 12; //YOU WILL SPECIFY HOW MANY CHARACTER WILL BE GENERATE
            for (int i = 0; i < count; i++ )
            {
                random_string = random_string + wrandom[random.Next(0, 24)].ToString(); 
            }
            MessageBox.Show(random_string);
            #endregion
    
        25
  •  0
  •   WhyMe    11 年前

    我发现这更有用,因为它是一个扩展,它允许您选择代码的源代码。

    static string
        numbers = "0123456789",
        letters = "abcdefghijklmnopqrstvwxyz",
        lettersUp = letters.ToUpper(),
        codeAll = numbers + letters + lettersUp;
    
    static Random m_rand = new Random();
    
    public static string GenerateCode(this int size)
    {
        return size.GenerateCode(CodeGeneratorType.All);
    }
    
    public static string GenerateCode(this int size, CodeGeneratorType type)
    {
        string source;
    
        if (type == CodeGeneratorType.All)
        {
            source = codeAll;
        }
        else
        {
            StringBuilder sourceBuilder = new StringBuilder();
            if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Numbers)
                sourceBuilder.Append(numbers);
            if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Letters)
                sourceBuilder.Append(letters);
            if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.LettersUpperCase)
                sourceBuilder.Append(lettersUp);
    
            source = sourceBuilder.ToString();
        }
    
        return size.GenerateCode(source);
    }
    
    public static string GenerateCode(this int size, string source)
    {
        StringBuilder code = new StringBuilder();
        int maxIndex = source.Length-1;
        for (int i = 0; i < size; i++)
        {
    
            code.Append(source[Convert.ToInt32(Math.Round(m_rand.NextDouble() * maxIndex))]);
        }
    
        return code.ToString();
    }
    
    public enum CodeGeneratorType { Numbers = 1, Letters = 2, LettersUpperCase = 4, All = 16 };
    

    希望这有帮助。

        26
  •  0
  •   Jules    11 年前

    在我的情况下,密码必须包含:

    • 至少一个小写。
    • 至少一个大写。
    • 至少一位小数。
    • 至少一个特殊字符。

    这是我的代码:

        private string CreatePassword(int len)
        {
            string[] valid = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890", "!@#$%^&*()_+" };
            RNGCryptoServiceProvider rndGen = new RNGCryptoServiceProvider();
    
            byte[] random = new byte[len];
            int[] selected = new int[len];
    
            do
            {
                rndGen.GetNonZeroBytes(random);
    
                for (int i = 0; i < random.Length; i++)
                {
                    selected[i] = random[i] % 4;
                }
            } 
            while(selected.Distinct().Count() != 4);
    
            rndGen.GetNonZeroBytes(random);
    
            string res = "";
    
            for(int i = 0; i<len; i++)
            {
                res += valid[selected[i]][random[i] % valid[selected[i]].Length];
            }
            return res;
        }
    
        27
  •  0
  •   Mino    11 年前

    你好
    您可以使用mmlib.rapidprototyping nuget包中的wordGenerator或loremipsumGenerator。

    using MMLib.RapidPrototyping.Generators;
    public void WordGeneratorExample()
    {
       WordGenerator generator = new WordGenerator();
       var randomWord = generator.Next();
    
       Console.WriteLine(randomWord);
    } 
    

    Nuget site
    Codeplex project site

        28
  •  0
  •   JebaDaHut    10 年前

    如果您可以访问与Intel Secure Key兼容的CPU,则可以使用以下库生成真正的随机数和字符串: https://github.com/JebteK/RdRand https://www.rdrand.com/

    只需从下载最新版本 here ,包括jebtek.rdrand并为其添加using语句。那么,你需要做的就是:

    bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU
    string key = RdRandom.GenerateKey(10); //Generate 10 random characters
    

    此外,您还可以获得以下附加功能:

    string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys
    byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes
    uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int
    

    如果没有兼容的CPU来执行代码,只需使用rdrand.com上的restful服务。有了项目中包含的RDRandom包装库,您只需要这样做(注册时可以获得1000个免费调用):

    string ret = Randomizer.GenerateKey(<length>, "<key>");
    

    您还可以生成随机字节数组和无符号整数,如下所示:

    uint ret = Randomizer.GenerateUInt("<key>");
    byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
    
        29
  •  0
  •   Amin Ghaderi    10 年前

    另一个样本(在VS2013中测试):

        Random R = new Random();
        public static string GetRandomString(int Length)
        {
            char[] ArrRandomChar = new char[Length];
            for (int i = 0; i < Length; i++)
                ArrRandomChar[i] = (char)('a' + R.Next(0, 26));
            return new string(ArrRandomChar);
        }
    
        string D = GetRandomString(12);
    

    由本人实施。

        30
  •  0
  •   Konard    9 年前

    这是我的解决方案:

    private string RandomString(int length)
    {
        char[] symbols = { 
                                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'                             
                            };
    
        Stack<byte> bytes = new Stack<byte>();
        string output = string.Empty;
    
        for (int i = 0; i < length; i++)
        {
            if (bytes.Count == 0)
            {
                bytes = new Stack<byte>(Guid.NewGuid().ToByteArray());
            }
            byte pop = bytes.Pop();
            output += symbols[(int)pop % symbols.Length];
        }
        return output;
    }
    
    // get 1st random string 
    string Rand1 = RandomString(4);
    
    // get 2nd random string 
    string Rand2 = RandomString(4);
    
    // create full rand string
    string docNum = Rand1 + "-" + Rand2;