web-dev-qa-db-ja.com

同じ文字列を返すランダム文字列ジェネレーター

ランダムな文字列ジェネレータを開発しましたが、期待どおりには動作しません。私の目標は、これを2回実行して、2つの異なる4文字のランダムな文字列を生成できるようにすることです。ただし、4文字のランダム文字列を2回生成するだけです。

これがコードとその出力例です。

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;

...そして、出力は次のようになります。UNTE-UNTE ...しかし、このUNTE-FWNUのように見えるはずです。

2つの明確にランダムな文字列をどのようにして確保できますか?

222
PushCode

メソッドにRandomインスタンスを作成しているため、すばやく連続して呼び出されたときに同じインスタンスが返されます。私はこのようなことをするだろう:

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;

(あなたのコードの修正版)

304
RCIX

メソッド内でRandomオブジェクトをインスタンス化しています。

Randomオブジェクトは システムクロックからシードされます です。つまり、あなたがあなたのメソッドを連続して数回呼び出すと、毎回同じシードを使うことになり、同じシーケンスを生成することになります。これは、あなたが同じ文字列を得ることを意味します。

この問題を解決するには、Randomインスタンスをメソッド自体の外側に移動します(その間、ConvertFloorおよび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);
}
186
LukeH

//非常にシンプルな実装

using System.IO;   
public static string RandomStr()

{
    string rStr = Path.GetRandomFileName();
    rStr = rStr.Replace(".", ""); // For Removing the .
    return rStr;
}

//これでRandomStr()メソッドを呼び出すだけです

134
Ranvir

Asp.Net 2.0以上を使用している限り、ライブラリ呼び出し - System.Web.Security.Membership.GeneratePassword を使用することもできますが、特殊文字が含まれます。

0個以上の特殊文字を含む4つのランダムな文字を取得するには

Membership.GeneratePassword(4, 0)
49
Spongeboy

たった1行のコードでランダムな文字列を何にするのか、何をするのか

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

PS:yourRandomStringLengthの長さは最大32であるため、Guidは32を超えることはできないことに注意してください。

20
Abdul Munim

この解決法は 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);
    }
}
12
oleksii

文字列ジェネレータのさらに別のバージョン。空想の数学と魔法の数字なしでシンプル。しかし、許可された文字を指定する魔法の文字列があります。

更新:ジェネレータを静的にしたので、複数回呼び出されても同じ文字列を返しません。しかし、このコードはnotthread-safeであり、間違いなくnot暗号的に安全

パスワードの生成には 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();
}
12
Maksym Davydov

もう1つオプションがあります。

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());
    }
}
10
Zygimantas

最善の解決策は、base64変換と共に乱数ジェネレータを使用することです。

public string GenRandString(int length)
{
  byte[] randBuffer = new byte[length];
  RandomNumberGenerator.Create().GetBytes(randBuffer);
  return System.Convert.ToBase64String(randBuffer).Remove(length);
}
7
Ami Luttwak

private static Random Randomを仮定して)良い測定のためのLINQワンライナー...

public static string RandomString(int length)
{
    return new string(Enumerable.Range(0, length).Select(_ => (char)Random.Next('a', 'z')).ToArray());
}
4
AlexFoxGill

これは、Randomの新しい各インスタンスが、それほど速く呼び出されてから同じ数を生成しているためです。 しないでください新しいインスタンスを作り続け、next()を呼び出してメソッドの外側であなたのランダムクラスを宣言するだけです。

4
John T

コンストラクタ内で1回開始され、各呼び出しで再利用される1つのクラスレベルのRandomオブジェクトを用意する必要があります(これは同じ一連の擬似乱数の続きです)。パラメータなしのコンストラクタは、ジェネレータ内部にEnvironment.TickCountをすでにシードしています。

3
Kenan E. K.

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);
        }
    }
2
João Miguel

ランダムな文字列を生成するための私の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);
}
2
AechoLiu

私もこれが許容され、簡単であるかもしれないと思う.

Guid.NewGuid().ToString() 
2
wener

現在受け入れられている答えを修正したものがありますが、もう少し早くて短いと思います。

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文字に変更できます。

2
quantum
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);
    }
}
1
Konard

そして、これがGUIDに基づくもう一つのアイデアです。英数字のみを含むランダムな文字列を生成するために Visual Studioのパフォーマンステスト に使用しました。

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);
}
1
Maciej Zaleski

実際のところ、良い解決策は、スレッドセーフであり、ロックを使用しない、乱数ジェネレータのための静的メソッドを持つことです。

そのため、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()を呼び出すだけで、メソッドは静的なままになります。

1
Stefan Steiger

強力なパスワード用に数字と文字の文字列を生成したい場合。

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();
        }
1
CGsoldier

このメソッドを作りました。

それは素晴らしい仕事です。

public static string GeneratePassword(int Lenght, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "[email protected]#$%^&*()_-+=[{]};:<>|./?";
        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;
    }
1
Hugo

ランダム文字列ジェネレータの場合

#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
1
Toprak

「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);
}
1
Ideogram

これはブログ記事です これはランダムな単語、文、段落を生成するためのもう少し堅牢なクラスを提供します。

1
Nick Olsen

私の状況では、パスワードには次のものを含める必要があります。

  • 少なくとも1つの小文字。
  • 少なくとも1つの大文字。
  • 少なくとも1つの10進数.
  • 少なくとも1つの特殊文字.

これが私のコードです:

    private string CreatePassword(int len)
    {
        string[] valid = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890", "[email protected]#$%^&*()_+" };
        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;
    }
0
Jules

Intel Secure Key互換のCPUにアクセスできる場合は、これらのライブラリを使用して実際の乱数と文字列を生成できます。 https://github.com/JebteK/RdRandhttps://www.rdrand.com/

最新のバージョンを こちら からダウンロードし、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>");
0
JebaDaHut

こんにちは
MMLib.RapidPrototyping nugetパッケージのWordGeneratorまたはLoremIpsumGeneratorを使用できます。

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

   Console.WriteLine(randomWord);
} 

ナゲットサイト
Codeplexプロジェクトサイト

0
Mino

これは拡張機能であり、コードのソースを選択することができるため、これはより役立つことがわかりました。

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 };

お役に立てれば。

0
WhyMe

別のサンプル(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);

自分で実装した。

0
Amin Ghaderi

そして、もう一つのバージョン:私はテストでランダムな擬似株式シンボルを生成するためにこのメソッドを使いました:

Random Rand = new Random();
Func<char> randChar = () => (char)Rand.Next(65, 91); // upper case ascii codes
Func<int,string> randStr = null;
    randStr = (x) => (x>0) ? randStr(--x)+randChar() : ""; // recursive

使用法:

string str4 = randStr(4);// generates a random 4 char string
string strx = randStr(Rand.next(1,5)); // random string between 1-4 chars in length

あなたは、ASCIIコードの代わりに、位置による文字の "許可され​​た"配列で使用するためにrandChar関数を再定義することができます:

char[] allowedchars = {'A','B','C','1','2','3'};
Func<char> randChar = () => allowedchars[Rand.Next(0, allowedchars.Length-1)];
0
cramroop

これが私の解決策です:

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;
0
ADM-IT