{"id":162,"date":"2020-08-06T11:21:26","date_gmt":"2020-08-06T11:21:26","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=162"},"modified":"2020-08-06T11:21:26","modified_gmt":"2020-08-06T11:21:26","slug":"zob64-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/08\/06\/zob64-cs\/","title":{"rendered":"ZOB64.cs"},"content":{"rendered":"\n<p>Example Zobrist Hashing 64-Bit<\/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=\"\">using System;\nusing System.Runtime.InteropServices;\nusing System.Security.Cryptography;\n\/\/\/ &lt;summary>\n\/\/\/     \n\/\/\/     https:\/\/en.wikipedia.org\/wiki\/Zobrist_hashing\n\/\/\/    \n\/\/\/ &lt;\/summary>\npublic class ZOB64 : HashAlgorithm\n{\n    private readonly ulong      starthash = 0x391615744853B307;\n    private          ulong[]    _table;\n    private          ulong      hash;\n    private          uint       hash32;\n    private          ZOB32State zhs;\n    public ZOB64()\n    {\n        hash = starthash;\n        BuildTable(0x7965CBDDD4A9E7AF);\n    }\n    public override int HashSize => 64;\n    public override void Initialize()\n    {\n        hash = starthash;\n    }\n    protected override void HashCore(byte[] bytes, int ibStart, int cbSize)\n    {\n        Hash64(bytes, ibStart, cbSize);\n    }\n    private static ulong RotateLeft(ulong value, int count)\n    {\n        return(value &lt;&lt; count) | (value >> (64 - count % 64));\n    }\n    private unsafe void Hash64(byte[] bytes, int ibStart, int cbSize)\n    {\n        if(bytes == null)\n            return;\n        if(ibStart >= bytes.Length || cbSize > bytes.Length)\n            return;\n        var i = 1;\n        fixed(byte* pb = bytes)\n        {\n            var nb = pb + ibStart;\n            while(cbSize >= 1)\n            {\n                hash   ^= RotateLeft(_table[*nb], i++);\n                nb     += 1;\n                cbSize -= 1;\n            }\n        }\n    }\n    protected override byte[] HashFinal()\n    {\n        zhs.hash64 = hash;\n        hash32     = zhs.hi ^ zhs.lo;\n        return hash.GetBytes();\n    }\n    public void BuildTable(ulong seed)\n    {\n        var s1   = (int) seed;\n        var s2   = (int) (seed >> 32);\n        var rnd  = new Random(s1);\n        var rnd1 = new Random(s2);\n        var tt   = new DynHashSet32&lt;ulong>();\n        _table = new ulong[256];\n        var u = new ZOB32State();\n        for(var i = 0; i &lt; 256; i++)\n        {\n            ulong v;\n            do\n            {\n                u.hi = (uint) rnd.Next();\n                u.lo = (uint) rnd1.Next();\n                v    = u.hash64;\n            } while(tt.Contains(v));\n            tt.Add(v);\n            _table[i] = v;\n        }\n    }\n    [StructLayout(LayoutKind.Explicit)]\n    public struct ZOB32State\n    {\n        [FieldOffset(0)] public ulong hash64;\n        [FieldOffset(0)] public uint  lo;\n        [FieldOffset(4)] public uint  hi;\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Example Zobrist Hashing 64-Bit<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[36,76,75],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/162"}],"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=162"}],"version-history":[{"count":1,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/162\/revisions"}],"predecessor-version":[{"id":163,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/162\/revisions\/163"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=162"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=162"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=162"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}