using System.Security.Cryptography;
using System.Text;

namespace PlcSiemens.Core.Common
{
    /// <summary>随机数</summary>
    public static class Rand
    {
        private static readonly RandomNumberGenerator Rnd;

        static Rand()
        {
            Rnd = new RNGCryptoServiceProvider();
        }

        /// <summary>返回一个小于所指定最大值的非负随机数</summary>
        /// <param name="max">返回的随机数的上界（随机数不能取该上界值）</param>
        /// <returns></returns>
        public static int Next(int max = int.MaxValue)
        {
            if (max <= 0) throw new ArgumentOutOfRangeException("max");

            return Next(0, max);
        }

        /// <summary>返回一个指定范围内的随机数</summary>
        /// <param name="min">返回的随机数的下界（随机数可取该下界值）</param>
        /// <param name="max">返回的随机数的上界（随机数不能取该上界值）</param>
        /// <returns></returns>
        public static int Next(int min, int max)
        {
            if (max <= min) throw new ArgumentOutOfRangeException("max");

            var buf = new byte[4];
            Rnd.GetBytes(buf);

            var n = BitConverter.ToInt32(buf, 0);
            if (min == int.MinValue && max == int.MaxValue) return n;
            if (min == 0 && max == int.MaxValue) return Math.Abs(n);
            if (min == int.MinValue && max == 0) return -Math.Abs(n);

            var num = max - min;
            return (int)(((num * (uint)n) >> 32) + min);
        }

        /// <summary>返回指定长度随机字节数组</summary>
        public static byte[] NextBytes(int count)
        {
            var buf = new byte[count];
            Rnd.GetBytes(buf);
            return buf;
        }

        /// <summary>返回指定长度随机字符串</summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string NextString(int length)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < length; i++)
            {
                var ch = (char)Next(' ', 0x7F);
                sb.Append(ch);
            }

            return sb.ToString();
        }
    }
}
