ランダムな文字列ジェネレータを開発しましたが、期待どおりには動作しません。私の目標は、これを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つの明確にランダムな文字列をどのようにして確保できますか?
メソッドに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;
(あなたのコードの修正版)
メソッド内でRandom
オブジェクトをインスタンス化しています。
Random
オブジェクトは システムクロックからシードされます です。つまり、あなたがあなたのメソッドを連続して数回呼び出すと、毎回同じシードを使うことになり、同じシーケンスを生成することになります。これは、あなたが同じ文字列を得ることを意味します。
この問題を解決するには、Random
インスタンスをメソッド自体の外側に移動します(その間、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);
}
//非常にシンプルな実装
using System.IO;
public static string RandomStr()
{
string rStr = Path.GetRandomFileName();
rStr = rStr.Replace(".", ""); // For Removing the .
return rStr;
}
//これでRandomStr()メソッドを呼び出すだけです
Asp.Net 2.0以上を使用している限り、ライブラリ呼び出し - System.Web.Security.Membership.GeneratePassword
を使用することもできますが、特殊文字が含まれます。
0個以上の特殊文字を含む4つのランダムな文字を取得するには
Membership.GeneratePassword(4, 0)
たった1行のコードでランダムな文字列を何にするのか、何をするのか
int yourRandomStringLength = 12; //maximum: 32
Guid.NewGuid().ToString("N").Substring(0, yourRandomStringLength);
PS:yourRandomStringLength
の長さは最大32であるため、Guid
は32を超えることはできないことに注意してください。
この解決法は 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);
}
}
文字列ジェネレータのさらに別のバージョン。空想の数学と魔法の数字なしでシンプル。しかし、許可された文字を指定する魔法の文字列があります。
更新:ジェネレータを静的にしたので、複数回呼び出されても同じ文字列を返しません。しかし、このコードは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();
}
もう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());
}
}
最善の解決策は、base64変換と共に乱数ジェネレータを使用することです。
public string GenRandString(int length)
{
byte[] randBuffer = new byte[length];
RandomNumberGenerator.Create().GetBytes(randBuffer);
return System.Convert.ToBase64String(randBuffer).Remove(length);
}
(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());
}
これは、Randomの新しい各インスタンスが、それほど速く呼び出されてから同じ数を生成しているためです。 しないでください新しいインスタンスを作り続け、next()を呼び出してメソッドの外側であなたのランダムクラスを宣言するだけです。
コンストラクタ内で1回開始され、各呼び出しで再利用される1つのクラスレベルのRandomオブジェクトを用意する必要があります(これは同じ一連の擬似乱数の続きです)。パラメータなしのコンストラクタは、ジェネレータ内部にEnvironment.TickCountをすでにシードしています。
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);
}
}
ランダムな文字列を生成するための私の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);
}
私もこれが許容され、簡単であるかもしれないと思う.
Guid.NewGuid().ToString()
現在受け入れられている答えを修正したものがありますが、もう少し早くて短いと思います。
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文字に変更できます。
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);
}
}
そして、これが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);
}
実際のところ、良い解決策は、スレッドセーフであり、ロックを使用しない、乱数ジェネレータのための静的メソッドを持つことです。
そのため、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()を呼び出すだけで、メソッドは静的なままになります。
強力なパスワード用に数字と文字の文字列を生成したい場合。
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();
}
このメソッドを作りました。
それは素晴らしい仕事です。
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;
}
ランダム文字列ジェネレータの場合
#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
「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);
}
これはブログ記事です これはランダムな単語、文、段落を生成するためのもう少し堅牢なクラスを提供します。
私の状況では、パスワードには次のものを含める必要があります。
これが私のコードです:
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;
}
Intel Secure Key互換のCPUにアクセスできる場合は、これらのライブラリを使用して実際の乱数と文字列を生成できます。 https://github.com/JebteK/RdRand と https://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>");
こんにちは
MMLib.RapidPrototyping nugetパッケージのWordGeneratorまたはLoremIpsumGeneratorを使用できます。
using MMLib.RapidPrototyping.Generators;
public void WordGeneratorExample()
{
WordGenerator generator = new WordGenerator();
var randomWord = generator.Next();
Console.WriteLine(randomWord);
}
これは拡張機能であり、コードのソースを選択することができるため、これはより役立つことがわかりました。
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 };
お役に立てれば。
別のサンプル(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);
自分で実装した。
そして、もう一つのバージョン:私はテストでランダムな擬似株式シンボルを生成するためにこのメソッドを使いました:
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)];
これが私の解決策です:
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;