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