난수 생성기는 하나의 난수 만 생성
다음과 같은 기능이 있습니다.
//Function to get random number
public static int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
내가 부르는 방법 :
byte[] mac = new byte[6];
for (int x = 0; x < 6; ++x)
mac[x] = (byte)(Misc.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);
런타임 중에 디버거로 해당 루프를 실행하면 다른 값이 표시됩니다 (원하는 값). 그러나 해당 코드 아래에 중단 점을 두 줄이면 "mac"배열의 모든 구성원이 동일한 값을 갖습니다.
왜 그럴까요?
할 때마다 new Random()
시계를 사용하여 초기화됩니다. 즉, 타이트한 루프에서 동일한 값을 여러 번 얻습니다. 단일 Random
인스턴스를 유지 Next
하고 동일한 인스턴스 에서 계속 사용해야 합니다.
//Function to get a random number
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return random.Next(min, max);
}
}
편집 (댓글 참조) : lock
여기에 왜 필요한 가요?
기본적으로 인스턴스 Next
의 내부 상태를 변경합니다 Random
. 여러 스레드에서 동시에이 작업을 수행하는 경우 "우리는 결과를 훨씬 더 무작위로 만들었습니다"라고 주장 할 수 있지만 실제로 수행하는 작업은 잠재적으로 내부 구현을 깨뜨리는 것이며 동일한 숫자를 얻기 시작할 수도 있습니다. 다른 스레드에서 수도 와 수도 있지 - 문제. 하지만 내부적으로 일어나는 일에 대한 보장은 더 큰 문제입니다. 스레드 안전성을 보장 Random
하지 않기 때문 입니다. 따라서 두 가지 유효한 접근 방식이 있습니다.
- 다른 스레드에서 동시에 액세스하지 않도록 동기화
Random
스레드마다 다른 인스턴스 사용
어느 쪽이든 괜찮을 수 있습니다. 그러나 동시에 여러 호출자로부터 단일 인스턴스를 뮤텍스하는 것은 문제를 요구하는 것입니다.
는 lock
이러한 방법의 첫 번째 (간단) 달성; 그러나 다른 접근 방식은 다음과 같습니다.
private static readonly ThreadLocal<Random> appRandom
= new ThreadLocal<Random>(() => new Random());
그러면 스레드 단위이므로 동기화 할 필요가 없습니다.
애플리케이션 전체에서 쉽게 재사용 할 수 있도록 정적 클래스가 도움이 될 수 있습니다.
public static class StaticRandom
{
private static int seed;
private static ThreadLocal<Random> threadLocal = new ThreadLocal<Random>
(() => new Random(Interlocked.Increment(ref seed)));
static StaticRandom()
{
seed = Environment.TickCount;
}
public static Random Instance { get { return threadLocal.Value; } }
}
그런 다음 다음과 같은 코드와 함께 정적 임의 인스턴스를 사용할 수 있습니다.
StaticRandom.Instance.Next(1, 100);
Mark의 솔루션은 매번 동기화해야하므로 비용이 많이들 수 있습니다.
스레드 별 스토리지 패턴을 사용하여 동기화 필요성을 해결할 수 있습니다.
public class RandomNumber : IRandomNumber
{
private static readonly Random Global = new Random();
[ThreadStatic] private static Random _local;
public int Next(int max)
{
var localBuffer = _local;
if (localBuffer == null)
{
int seed;
lock(Global) seed = Global.Next();
localBuffer = new Random(seed);
_local = localBuffer;
}
return localBuffer.Next(max);
}
}
두 가지 구현을 측정하면 상당한 차이를 확인할 수 있습니다.
여기 에서 내 대답 :
올바른 솔루션을 반복 하십시오 .
namespace mySpace
{
public static class Util
{
private static rnd = new Random();
public static int GetRandom()
{
return rnd.Next();
}
}
}
따라서 다음을 호출 할 수 있습니다.
var i = Util.GetRandom();
all throughout.
If you strictly need a true stateless static method to generate random numbers, you can rely on a Guid
.
public static class Util
{
public static int GetRandom()
{
return Guid.NewGuid().GetHashCode();
}
}
It's going to be a wee bit slower, but can be much more random than Random.Next
, at least from my experience.
But not:
new Random(Guid.NewGuid().GetHashCode()).Next();
The unnecessary object creation is going to make it slower especially under a loop.
And never:
new Random().Next();
Not only it's slower (inside a loop), its randomness is... well not really good according to me..
I would rather use the following class to generate random numbers:
byte[] random;
System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider();
prov.GetBytes(random);
1) As Marc Gravell said, try to use ONE random-generator. It's always cool to add this to the constructor: System.Environment.TickCount.
2) One tip. Let's say you want to create 100 objects and suppose each of them should have its-own random-generator (handy if you calculate LOADS of random numbers in a very short period of time). If you would do this in a loop (generation of 100 objects), you could do this like that (to assure fully-randomness):
int inMyRandSeed;
for(int i=0;i<100;i++)
{
inMyRandSeed = System.Environment.TickCount + i;
.
.
.
myNewObject = new MyNewObject(inMyRandSeed);
.
.
.
}
// Usage: Random m_rndGen = new Random(inMyRandSeed);
Cheers.
Every time you execute
Random random = new Random (15);
It does not matter if you execute it millions of times, you will always use the same seed.
If you use
Random random = new Random ();
You get different random number sequence, if a hacker guesses the seed and your algorithm is related to the security of your system - your algorithm is broken. I you execute mult. In this constructor the seed is specified by the system clock and if several instances are created in a very short period of time (milliseconds) it is possible that they may have the same seed.
If you need safe random numbers you must use the class
System.Security.Cryptography.RNGCryptoServiceProvider
public static int Next(int min, int max)
{
if(min >= max)
{
throw new ArgumentException("Min value is greater or equals than Max value.");
}
byte[] intBytes = new byte[4];
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
rng.GetNonZeroBytes(intBytes);
}
return min + Math.Abs(BitConverter.ToInt32(intBytes, 0)) % (max - min + 1);
}
Usage:
int randomNumber = Next(1,100);
just declare the Random class variable like this:
Random r = new Random();
// ... Get three random numbers.
// Here you'll get numbers from 5 to 9
Console.WriteLine(r.Next(5, 10));
if you want to get different random number each time from your list then use
r.Next(StartPoint,EndPoint) //Here end point will not be included
Each time by declaring Random r = new Random()
once.
There are a lot of solutions, here one: if you want only number erase the letters and the method receives a random and the result length.
public String GenerateRandom(Random oRandom, int iLongitudPin)
{
String sCharacters = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
int iLength = sCharacters.Length;
char cCharacter;
int iLongitudNuevaCadena = iLongitudPin;
String sRandomResult = "";
for (int i = 0; i < iLongitudNuevaCadena; i++)
{
cCharacter = sCharacters[oRandom.Next(iLength)];
sRandomResult += cCharacter.ToString();
}
return (sRandomResult);
}
참고URL : https://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number
'Nice programing' 카테고리의 다른 글
TINYTEXT, TEXT, MEDIUMTEXT 및 LONGTEXT 최대 저장 크기 (0) | 2020.09.29 |
---|---|
C ++ 11에서 T && (이중 앰퍼샌드)는 무엇을 의미합니까? (0) | 2020.09.29 |
hr 요소의 색상 변경 (0) | 2020.09.29 |
setTimeout 또는 setInterval? (0) | 2020.09.29 |
JavaScript에서 문자열을 Base64로 어떻게 인코딩 할 수 있습니까? (0) | 2020.09.29 |