//-----------------------------------------------------------------------------
//
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// A copy of the License is located at
//
// http://aws.amazon.com/apache2.0
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
//
//-----------------------------------------------------------------------------
using System;
using System.Globalization;
using System.Linq;
using System.Threading;
namespace Amazon.XRay.Recorder.Core.Internal.Utils
{
///
/// An thread safe wrapper for System.Random
///
public static class ThreadSafeRandom
{
private static readonly Random _global = new Random();
private static readonly ThreadLocal _local = new ThreadLocal(() =>
{
int seed;
lock (_global)
{
seed = _global.Next();
}
return new Random(seed);
});
///
/// Generate a random hex number
///
/// Digits of the hex number
/// The generated hex number
public static string GenerateHexNumber(int digits)
{
if (digits < 0)
{
throw new ArgumentException("Length can't be a negative number.", nameof(digits));
}
byte[] bytes = new byte[digits / 2];
ThreadSafeRandom.NextBytes(bytes);
string hexNumber = string.Concat(bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)).ToArray());
if (digits % 2 != 0)
{
hexNumber += ThreadSafeRandom.Next(16).ToString("x", CultureInfo.InvariantCulture);
}
return hexNumber;
}
///
/// Thread safe version of System.Random.NextDouble().
/// Returns a random floating-point number that is greater than or equal to 0.0, and less than 1.0.
///
/// A double-precision floating point number that is greater than or equal to 0.0, and less than 1.0.
public static double NextDouble()
{
return _local.Value.NextDouble();
}
///
/// Fills the elements of a specified array of bytes with random numbers
///
/// An array of bytes to contain random numbers
private static void NextBytes(byte[] buffer)
{
_local.Value.NextBytes(buffer);
}
///
/// Returns a non-negative random integer that is less than the specified maximum
///
/// Max value of the random integer
/// A 32-bit signed integer that is greater than or equal to 0, and less than maxValue
private static int Next(int maxValue)
{
return _local.Value.Next(maxValue);
}
}
}