{"id":15,"date":"2020-06-04T07:44:17","date_gmt":"2020-06-04T07:44:17","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=15"},"modified":"2020-12-30T13:26:11","modified_gmt":"2020-12-30T13:26:11","slug":"random64-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/06\/04\/random64-cs\/","title":{"rendered":"Random64.cs"},"content":{"rendered":"\n<p>64 Bit RNG using <a href=\"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/07\/09\/rngjittersource-cs\/\" data-type=\"URL\" data-id=\"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/07\/09\/rngjittersource-cs\/\" target=\"_blank\" rel=\"noreferrer noopener\">RngJitterSource.cs<\/a><\/p>\n\n\n\n<p>Updated: Dec-26,2020<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Example Code:\nAdd a 256x256 panel to a form.\n\n            var lrng = new Random64(65536, 256, 2);\n            var g = panel1.CreateGraphics();\n            var bm  = new Bitmap(256, 256);\n            var buf = lrng.GetNextBoolArrayLimit(65536);\n            var ptr = 0;\n            for (var y = 0; y &lt; 256; y++)\n            for (var x = 0; x &lt; 256; x++)\n            {\n                var r = buf[ptr++];\n                if (r)\n                {\n                    bm.SetPixel(x, y, Color.White);\n                }\n                else\n                {\n                    bm.SetPixel(x, y, Color.Black);\n                }\n            }\n            g.DrawImageUnscaled(bm, 0, 0);<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Security.Cryptography;\n[Serializable]\npublic class Random64 : RandomNumberGenerator\n{\n    private byte[]          _buffer;\n    public  RngJitterSource _crng;\n    private double          _dBi;\n    private ulong           UpperLimit = ulong.MaxValue;\n    public Random64()\n    {\n        SetDataUse = 8;\n        _crng      = new RngJitterSource();\n    }\n    public Random64(int cacheSize)\n    {\n        SetDataUse = 8;\n        _crng      = new RngJitterSource(cacheSize * 8, 256, 256, 4);\n    }\n    public Random64(int cacheSize, int seedSize)\n    {\n        SetDataUse = 8;\n        _crng      = new RngJitterSource(cacheSize * 8, seedSize, 256, 4);\n    }\n    public Random64(int cacheSize, int seedSize, int dataSize, int sha3Size = 256, int sha3Rounds = 4)\n    {\n        SetDataUse = dataSize;\n        _crng      = new RngJitterSource(cacheSize * dataSize, seedSize, sha3Size, sha3Rounds);\n    }\n    public int SetDataUse\n    {\n        get => _buffer.Length;\n        set\n        {\n            var v = value;\n            if (v &lt; 1 || v > 8 || v == 3 || v == 5 || v == 6 || v == 7)\n                throw new ArgumentException($\"Value {v} must be either 1 or 2 or 4 or 8\");\n            switch (v)\n            {\n                case 1:\n                    _dBi       = 1.0D \/ byte.MaxValue;\n                    UpperLimit = byte.MaxValue;\n                    _buffer    = new byte[1];\n                    break;\n                case 2:\n                    _dBi       = 1.0D \/ ushort.MaxValue;\n                    UpperLimit = ushort.MaxValue;\n                    _buffer    = new byte[2];\n                    break;\n                case 4:\n                    _dBi       = 1.0D \/ uint.MaxValue;\n                    UpperLimit = uint.MaxValue;\n                    _buffer    = new byte[4];\n                    break;\n                case 8:\n                    _dBi       = 1.0D \/ ulong.MaxValue;\n                    UpperLimit = ulong.MaxValue;\n                    _buffer    = new byte[8];\n                    break;\n                default:\n                    _dBi       = 1.0D \/ ulong.MaxValue;\n                    UpperLimit = ulong.MaxValue;\n                    _buffer    = new byte[8];\n                    break;\n            }\n        }\n    }\n    public bool OddsOnly\n    {\n        get;\n        set;\n    }\n    private double Sample()\n    {\n        ulong Internal()\n        {\n            _crng.GetBytes(_buffer);\n            return BufferToLong(_buffer);\n        }\n        return Internal() * _dBi;\n    }\n    public ulong Next(ulong minValue, ulong maxValue)\n    {\n        var sa = Sample();\n        var fi = (double) (maxValue - minValue + minValue);\n        var n  = (ulong) (sa * fi);\n        n = !OddsOnly ? n : n | 1;\n        if (n &lt; minValue)\n            return Next(minValue, maxValue);\n        return n;\n    }\n    public ulong Next(ulong maxValue)\n    {\n        return Next(0, maxValue);\n    }\n    public ulong Next()\n    {\n        return Next(0, UpperLimit);\n    }\n    public unsafe double NextDouble()\n    {\n        var buf = new byte[8];\n        GetBytes(buf);\n        fixed (byte* ptr = buf)\n        {\n            return *(ulong*) ptr * _dBi * ulong.MaxValue;\n        }\n    }\n    public char[] GetNextCharArray(int size)\n    {\n        var xbc = new byte[1];\n        var ca  = new char[size];\n        var ptr = 0;\n        do\n        {\n            _crng.GetBytes(xbc);\n            var c = xbc[0];\n            if (c >= 32 &amp;&amp; c &lt;= 127)\n                ca[ptr++] = (char) c;\n        } while (ptr &lt; size);\n        return ca;\n    }\n    public char[] GetNextCharArrayX(int size)\n    {\n        var xbc = new byte[2];\n        var ca  = new char[size];\n        var ptr = 0;\n        do\n        {\n            _crng.GetBytes(xbc);\n            ca[ptr++] = Convert.ToChar(xbc.ToShort());\n        } while (ptr &lt; size);\n        return ca;\n    }\n    public byte[] GetNextByteArray(int size)\n    {\n        var ba = new byte[size];\n        _crng.GetBytes(ba);\n        return ba;\n    }\n    public bool[] GetNextBoolArrayLimit(int size)\n    {\n        var        ba = new bool[size];\n        const uint ll = uint.MaxValue >> 1;\n        for (var i = 0; i &lt; size; ++i)\n            ba[i] = Next(0, uint.MaxValue) > ll;\n        return ba;\n    }\n    public byte[] GetNextByteArrayLimit(int size, ulong minValue, ulong maxValue)\n    {\n        var ba = new byte[size];\n        for (var i = 0; i &lt; size; ++i)\n            ba[i] = (byte) Next(minValue, maxValue);\n        return ba;\n    }\n    public ushort[] GetNextUShortArrayLimit(int size, ulong minValue, ulong maxValue)\n    {\n        var ba = new ushort[size];\n        for (var i = 0; i &lt; size; ++i)\n            ba[i] = (ushort) Next(minValue, maxValue);\n        return ba;\n    }\n    public uint[] GetNextUIntArrayLimit(int size, ulong minValue, ulong maxValue)\n    {\n        var ba = new uint[size];\n        for (var i = 0; i &lt; size; ++i)\n            ba[i] = (uint) Next(minValue, maxValue);\n        return ba;\n    }\n    public ulong[] GetNextULongArrayLimit(int size, ulong minValue, ulong maxValue)\n    {\n        var ba = new ulong[size];\n        for (var i = 0; i &lt; size; ++i)\n            ba[i] = Next(minValue, maxValue);\n        return ba;\n    }\n    public string GetRandomString(int minLen, int maxLen)\n    {\n        if (minLen == maxLen)\n            return new string(GetNextCharArray(minLen));\n        return new string(GetNextCharArray((int) Next((ulong) minLen, (ulong) maxLen)));\n    }\n    public override void GetBytes(byte[] data)\n    {\n        if (data == null)\n            throw new ArgumentException(\"The buffer cannot be null.\");\n        _crng.GetBytes(data);\n    }\n    public void NextBytes(byte[] buffer)\n    {\n        if (buffer == null)\n            throw new ArgumentNullException(\"The buffer cannot be null.\");\n        for (var index = 0; index &lt; buffer.Length; ++index)\n            buffer[index] = (byte) (Sample() * byte.MaxValue + 1);\n    }\n    public override void GetNonZeroBytes(byte[] buffer)\n    {\n        if (buffer == null)\n            throw new ArgumentNullException(\"The buffer cannot be null.\");\n        var index = 0;\n        do\n        {\n            var v = (byte) (Sample() * byte.MaxValue + 1);\n            if (v > 0)\n            {\n                buffer[index] = v;\n                index++;\n            }\n        } while (index &lt; buffer.Length);\n    }\n    private unsafe ulong BufferToLong(byte[] buffer)\n    {\n        var len = buffer.Length;\n        if (len &lt; 1 || len > 8)\n            throw new ArgumentException($\"The array length {len} must be between 1 and 8\");\n        fixed (byte* Ptr = &amp;buffer[0])\n        {\n            switch (len)\n            {\n                case 1:\n                    return *Ptr;\n                case 2:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8));\n                case 3:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8) | (Ptr[2] &lt;&lt; 16));\n                case 4:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8) | (Ptr[2] &lt;&lt; 16) | (Ptr[3] &lt;&lt; 24));\n                case 5:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8) | (Ptr[2] &lt;&lt; 16) | (Ptr[3] &lt;&lt; 24)) | ((ulong) Ptr[4] &lt;&lt; 32);\n                case 6:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8) | (Ptr[2] &lt;&lt; 16) | (Ptr[3] &lt;&lt; 24)) | ((ulong) (Ptr[4] | (Ptr[5] &lt;&lt; 8)) &lt;&lt; 32);\n                case 7:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8) | (Ptr[2] &lt;&lt; 16) | (Ptr[3] &lt;&lt; 24)) | ((ulong) (Ptr[4] | (Ptr[5] &lt;&lt; 8) | (Ptr[6] &lt;&lt; 16)) &lt;&lt; 32);\n                case 8:\n                    return (uint) (*Ptr | (Ptr[1] &lt;&lt; 8) | (Ptr[2] &lt;&lt; 16) | (Ptr[3] &lt;&lt; 24)) | ((ulong) (Ptr[4] | (Ptr[5] &lt;&lt; 8) | (Ptr[6] &lt;&lt; 16) | (Ptr[7] &lt;&lt; 24)) &lt;&lt; 32);\n                default:\n                    return 0;\n            }\n        }\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>64 Bit RNG using RngJitterSource.cs Updated: Dec-26,2020<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/15"}],"collection":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/comments?post=15"}],"version-history":[{"count":5,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/15\/revisions"}],"predecessor-version":[{"id":347,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/15\/revisions\/347"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=15"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=15"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=15"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}