OSDN Git Service

3221d890124401e3e62416b8ea47591f19aa98ae
[mhash384/mhash384.git] / ports / c-sharp / libmhash384 / MHash384.cs
1 /* ---------------------------------------------------------------------------------------------- */
2 /* MHash-384 - Simple fast portable secure hashing library                                        */
3 /* Copyright(c) 2016-2019 LoRd_MuldeR <mulder2@gmx.de>                                            */
4 /*                                                                                                */
5 /* Permission is hereby granted, free of charge, to any person obtaining a copy of this software  */
6 /* and associated documentation files (the "Software"), to deal in the Software without           */
7 /* restriction, including without limitation the rights to use, copy, modify, merge, publish,     */
8 /* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the  */
9 /* Software is furnished to do so, subject to the following conditions:                           */
10 /*                                                                                                */
11 /* The above copyright notice and this permission notice shall be included in all copies or       */
12 /* substantial portions of the Software.                                                          */
13 /*                                                                                                */
14 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING  */
15 /* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND     */
16 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   */
17 /* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
18 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.        */
19 /* ---------------------------------------------------------------------------------------------- */
20
21 using System;
22 using System.Text;
23 using System.Runtime.CompilerServices;
24
25 namespace com.muldersoft.mhash384
26 {
27     /// <summary>
28     /// <para>MHash384 – Simple fast portable secure hashing library</para>
29     /// <para>Copyright(c) 2016-2019 LoRd_MuldeR &lt;mulder2@gmx.de&gt;</para>
30     /// </summary>
31     public class MHash384
32     {
33         public const int MHASH384_WORDS = 6;
34         public const int MHASH384_SIZE = MHASH384_WORDS * sizeof(ulong);
35
36         public static readonly short VERSION_MAJOR = 2;
37         public static readonly short VERSION_MINOR = 0;
38         public static readonly short VERSION_PATCH = 0;
39
40         //=======================================================================
41         // HELPER CLASSES
42         //=======================================================================
43
44         private class Row<T>
45         {
46             private Row(T[] data)
47             {
48                 this.data = data;
49             }
50
51             public static Row<T> Wrap(T[] data)
52             {
53                 return new Row<T>(data);
54             }
55
56             public T this[int index]
57             {
58                 [MethodImpl(MethodImplOptions.AggressiveInlining)]
59                 get => data[index];
60             }
61
62             public int Length
63             {
64                 [MethodImpl(MethodImplOptions.AggressiveInlining)]
65                 get => data.Length;
66             }
67
68             public T[] ToArray()
69             {
70                 return (T[]) data.Clone();
71             }
72
73             private readonly T[] data;
74         }
75
76         private class Table<T>
77         {
78             private Table(Row<T>[] data)
79             {
80                 this.data = data;
81             }
82             
83             public static Table<T> Wrap(Row<T>[] data)
84             {
85                 return new Table<T>(data);
86             }
87
88             public Row<T> this[int index]
89             {
90                 [MethodImpl(MethodImplOptions.AggressiveInlining)]
91                 get => data[index];
92             }
93
94             public int Length
95             {
96                 [MethodImpl(MethodImplOptions.AggressiveInlining)]
97                 get => data.Length;
98             }
99
100             private readonly Row<T>[] data;
101         }
102
103         //=======================================================================
104         // CONST TABLES
105         //=======================================================================
106
107         private static class Tables
108         {
109             public static readonly Row<ulong> INI = CreateRow<ulong>
110             (
111                 "0wijhYhqPyREc3ADLooZE9AxnykiOAmkiWxO7Jj6Lgh3E9A45iEoRWwM6TTPZlS+"
112             );
113
114             public static readonly Table<ulong> XOR = CreateTable<ulong>
115             (
116                 "NzBLQQDf3AH4lo4bZq+zsSExOdtzKE2UVecqZjaa2nOxVstOjDFPH7ylKpzZQ5fw", /*00*/
117                 "VMm/y8a7H6jb7VmJZEPeOS+CAdoLGmQaWCaTZnJgLrWEIICsMRdbLNSdxx9nEO/C", /*01*/
118                 "RgCBCI6NKs/2aOKJIJt+i+wtXSxlYQSTuci/IyLklvBwCf5MljjTjb1g7HwvNJwm", /*02*/
119                 "UgXt0iCpcLnhp00lSokPAdhAGp1fIF+NWF/9w8w9w1BXLNjnvTGftDOQlSr2BN58", /*03*/
120                 "rIScK4Ky+knxvozWjGS4NN4mQbtHERLlD+D/slQfs8AyxoyOoz0ZL/yKm0JLmIwF", /*04*/
121                 "QpmMTaSdf+DyZcqas/kqvpXCbUaxjz1dx2L5wz4eBcC2K87UzMP9+DeZGcbvwCSQ", /*05*/
122                 "7/UB73cTEaP/owJsNpv1MdwWDXZJKbhh3zu9kq9YufaywGns76qXcs2Ehp6tUIr+", /*06*/
123                 "oJrqKcjQPT2jx5bsfll3PoQWfx4jONCP4O23HxN7YWR0WEDF5JzJhePFGR/UNYel", /*07*/
124                 "mhv5yopiKIBkcMk4BWRKGYAWT4oBXqEEVQk2wgQbvvQgGljvTE2y352HFf2g0Fk8", /*08*/
125                 "vPGK5+zi+IjCZHMpIm5rtPOZa5J/8TmTfPC4s4k0KTHxvMlJFs4JOem8Mfo7EEYM", /*09*/
126                 "qeLvx4wLGk1x6FWtjIfXr1NBz1jI+5zI1nVPx4aUc8TyyQoTLBn3C5q9gV688oQA", /*0A*/
127                 "z8pPAXXp+0rkQcz6jK/eQekW7VM7wh48SDIcD7NusHhyXCgEXRYR3eSRlGC12UZl", /*0B*/
128                 "YNLITeDi0f/O7HSKlIaxBzHFGhJFDhK1hQyBMGPIC70wd0jb3a+T3paRuW7esN54", /*0C*/
129                 "VbreP6yiunl+VirJ4eO3sZQHW0qraT+l3W1PlZl02vBIIhPhiXwRWG4axZT39V3Z", /*0D*/
130                 "MxwJZQyKvInCNTEG7upOsInmtkrgZzL18ot+ILd5xbTf0jw0UR7TP/6XgS8+Up4R", /*0E*/
131                 "LfNgYBzLEC5ja06pMueSvGdC0B+DDSLzf+i8FHRfLFBXJB3pHWXgiRXZgkSwVp51", /*0F*/
132                 "A+iEaizjrkPj1wssIAdQDCrTBUJHZPS0Bmw43pX8F31FpXpWZL/f6G8EU1idiL1V", /*10*/
133                 "J9q46hS+emhEw3INtTp7OY1h3h9tql5QaT+hXYZ5vmEtDum1Kau7Fy+L+nIZkgwB", /*11*/
134                 "U/Rv9aQjcovhb4u5XHsbKX2/b3glFkL9yM3o0CAQPeOHnnOLcAxTyi+huATz8YqH", /*12*/
135                 "Eddt5SQfzn7fpi8bJGkILv2yWcTcNLiEO32eMabtIuAomTygjJ2DWXTHu5H0kEdk", /*13*/
136                 "Dd2w5klv3MsyZzQAjS+6RBzmalghyLyGW+XOhRJJt8dROH/Z/xI57b+8vr6GAa/0", /*14*/
137                 "FuXMTuVIisoG9fi3ZBjfvqRqs6RgH2rV2dkN/rVasknh/Eleu303IeeZndX1ZI9w", /*15*/
138                 "LOCvaaVz+OmQc5nKBbxm2oVT01ZHF4iMMKf99GzxquoSNTplVXqfs1LoI7wntwrx", /*16*/
139                 "r+K7xfhv6ZN86VMCQoV3pEwHfffRJUtwnFVwFD8JssDPqmTj1P1bjfcbWz9nGAVV", /*17*/
140                 "yxroWy6DrI3Yg3UrIPuLWOTX0d9wik2jPgOHticGO9DPddzbfr7Q4+qLn7DF6I6B", /*18*/
141                 "MX2dSOECO44yteNkK3U2U2UKWFx5zNTkfnbtE/MIq22/Nrr9iH5WjtAz6djxkJQl", /*19*/
142                 "Yqos1tA3tOoDsIK5KK2QwOwEV9Jo11XiQ2ol9hpRSKBfi0lNjwef5/5Xs3X7NRfE", /*1A*/
143                 "nfJPUMOf2nAl/3OGOB+rubpXc9FML5I2SuDnkrI6nPDsE7rZwwvOkOONkTymTHxk", /*1B*/
144                 "iNbs0Y2jNNhqq0beIAB6qR+nLub2x96cfsRN129aiijxUM5lJy5K1DxPntu1UJu7", /*1C*/
145                 "5vLdQQ6pbcYJXAwWb+g/Wr7MCFFA8Gpvf/wnti44OPlsAH9hNNY9FpeEkNz+sYRR", /*1D*/
146                 "HLL8B+0ZV8nr524/BN8SUc40IwFg/flQeWXZBFGon1inBRnXRJ4St41SMwdudhQz", /*1E*/
147                 "uHxFxRSAbNy2aWoozf011r8BfeIsI2/WD+yC9sBKr1b1KEO2VR3fV8rKhyrF1B5l", /*1F*/
148                 "AsXueczR2Sb+67E0CjS/aXRxOY6sqqX6b89rQr35qNBSJG1NRh8TW9rW0GBW0S0S", /*20*/
149                 "L6JRX+yaOG77J8FUHI/2fjBcSOBGTW2YMYrP5zl7pPCPp/K3/Y05HS4NsfvRUcYv", /*21*/
150                 "sNxJG41OTqRD88JJIIKkB7oFZY1KwArEbLEpBz8dudkVkA+1UZnzqnaQP63T9W6W", /*22*/
151                 "CdC2DqzLeOqr3iNacqb+oNmUy0R0nHLODaonZmKUqUDVGNDjzTj3N8WzzQEcSSlM", /*23*/
152                 "eshFp66Sl3zUj73FIFb/0blWSwDjhMqe1rEowiM5/Vo7KP2znvfb5Z9LCFTjEhdE", /*24*/
153                 "vEni2IsoXePlZqNTFGx3kezvlU5o4dH1Bvbd1xfhCJGMfM6inQ+zgQ2MgYbX25dk", /*25*/
154                 "4EsERf+R+MLr4ocrbaehdb/C84p5Zc6F3An9TitTPyGIbDql9R2qDbIm2FBqYCgw", /*26*/
155                 "OvN5Y2FimmBtUeRTvKM5o+zbWmphkq3XqiTphm1yQ9BlmML0ZLVVhbDWwTGrEqpW", /*27*/
156                 "/3vBwYXt2c7C/7qsJSNS65RT0bL02NME6m51BExQcdLxJ/gaqaTbLeQCgI/C1Wcf", /*28*/
157                 "j8AtQ60InIvHu5aX4kN1Wt5nGTxb26Y05E6AosI7bgF1LxflzMqbW7q9rYCLWUl1", /*29*/
158                 "VdHNxRexP2/F7tacpbDDFmmHU94RpKHZfMNKn5dUjJPbhFLVwbw3N7drFfmKn61s", /*2A*/
159                 "3+t1nE8ov+voPXUGtOuDszxAfO56EoaqJ+A9UhDdvxATikrrxPaLE2eweNt99u+x", /*2B*/
160                 "Xtqjeo0T0fZxY7aPjQmouvKqbIsbbefa3B6NNjQQD0B30uhyUX+TfO/mrTz4uwV9", /*2C*/
161                 "gbA0z6YunA6gC/ZYDbM2kMqL8EhYLDrbZNVQQrnReshmYfnuCS6JfPOFEFfPhdsm", /*2D*/
162                 "KsEYh/XjHiXkKooXgY1D+aioOZCImpLw/cy9XiJla/DGc7/37RRNLs/6HbyVmDap", /*2E*/
163                 "y3lpHbQC48oj5h61WFr6uy+1GsiduRNRVqAX7Ft5k2BeNV4uTftxj/KiNLrtki92", /*2F*/
164                 "/9mkZVIBMNHIJh/XU6K+CeYhZcTt6raBqbiCVhZo4vojtkp3xD6cqLKdIVXgRS4N", /*30*/
165                 "q5Kmw4QCViu4p3mz0IoAN/wL+TAszRGv7WInDyV66H/DQnJkEdf7w70is/Zkgu10", /*31*/
166                 "Qzmtp8hcGSjET0xGCOjLUyaHX3Z6PY7VT6qFAfZSMNjntDsihQ3L7yisf3heMDFa", /*32*/
167                 "Q5XxMOIOXXLgNN+9xtKRkAFGdcLGSb7ja1atpAswvmHBfPpRdZ3XAljaHF8PkUNl", /*33*/
168                 "P7SBRMStmUCB69kvkmET/qzOH0SewImpGZDL0xM6m0Q0ESBvOb6pRf4zZgRa0Brc", /*34*/
169                 "aT4vUm06VhqeWkefB55YvjgATI5jqaJ1YgN6VwJiO9r2enINHj8dITOS2ZpS/B9e", /*35*/
170                 "G9DWxoYetkcYw62tg299Q4xz7Y0CYaPVSxYlBGNMDaDSnUyvpa9pGoK1UflnHJ75", /*36*/
171                 "eeq9tkB3aqajgK+WFP/3/oyJzeo+1K8FNHGtMe14DLBzZoTXGhrTDr6ZFBZEaLl0", /*37*/
172                 "LtH2y2yN+kZWOTB/FPzCMX8GX94BRH9w6ZQ148f+5ToUF1Njip/jKLLKnx7qKbO3", /*38*/
173                 "BHhcglX32O/RDNMLh5NaHxaH/3FGib/vWNor8n9h7SgutlyuzIkSQfnyARj0Qt2V", /*39*/
174                 "4Vn8RYZbUqgMf18KwC3mdawWBCGFZ8UJJnYNs+l271Bl1vUZ3Cw7K//02BHNlxKk", /*3A*/
175                 "OVDunmSayeplADwUL8mTpQYSBwNScxSz7KRkx6BhJ+qzJaxs1H+qAr8DbamCwYzG", /*3B*/
176                 "qDzITgI/h7LrU4j9uApHl70Fs1nBFf4Y/erqh/YIq7BDLmBz3j8KUfD88MxNuOED", /*3C*/
177                 "2MAzgNy7W9hP86mcw9kjkv3DY1ttyzt9tQ8M2nT5MBxDUfu+nrwki/yEe1uSVInF", /*3D*/
178                 "p9dECC58vWoNU99sReryzLghOSv1jJPofGWB8qI8Arqu7dF1pl1j7Gy+4S7yUqq0", /*3E*/
179                 "BFnLd8Y6HJhJe4eETLWSahVYxUC7plt07XGjIg1Vr7d0U1/Gh73o1fU49fA3Sodn", /*3F*/
180                 "IcDsnSq6O8JQNA4Lkw5hTn5XdxSpGmgadsPtFJcgozi2SuvuY1XRD3gh1AGKZld9", /*40*/
181                 "tZigReGM+GpGi4vYjIXrGujW4rivM7fo+uunEIyqPzHqfFV3Xjd9ElUhLwv3or2W", /*41*/
182                 "Nravj5cDiexjlwdcQjwhx3zRtmoDhAN2SR9fOCY6xuD1bRqB1neYKY24BFP8kG+H", /*42*/
183                 "Frrg1sK7+qa85oAAZMlwm3uymFUm1bIpfjnkJsdXlkrVeGZ2xswBqJiZYXLM9w6A", /*43*/
184                 "v5BUz6gxWSOfh48OjvmY56cM8zic4u7GJAA+1fJ5mpJFelhJJ+HyiGUZiTiPsoUL", /*44*/
185                 "J9ik5AMDXhZqQ+jRQk+ZZxsNE27Pi8zm/N6dcBEXEFAoU9AMxN47N/YJUaqkdLJA", /*45*/
186                 "yPj9CKCL+Kla4G5H45fI7HR61WmrkOK8XRHjERjbRPqIDEhk/a5nYuvsOi1K0Jcm", /*46*/
187                 "EzPNq/IqeMBzYvnykBK6ArnCrVYaL8hjxFH+PsDo+BD9r8wlhjTr467nuJyWB9aT", /*47*/
188                 "vI/lQ5QXbszuuKdVxpMc0qSLKx+jNJgr7uwlYFFpO8iUrnpCe+t2kW6ntzCeW7aM", /*48*/
189                 "idnt1go6o8H3tRNY2cWzGIuaNTsmvSSwUJupFiJ8wcgpdyNYHaH5cZBCKBh2fKY6", /*49*/
190                 "exwgCV5Gt5mB+qQcoJ/4miPRGnY+xi78FH2xhZWjqeKBTvkp5U05CKT6lJfmSJRH", /*4A*/
191                 "u8q9TBw9yiPkNxrONlQm48lMip72EL8bTVyPBAhnpgX+/luc3dxZ4v1uk/36ZZ5D", /*4B*/
192                 "nHGPl7ZzTaKOu7DMQ/NTP2p84J52cjy+3Vj1nFOey/pqmN4wTh25ZzqRmBbRE7kd", /*4C*/
193                 "xsPDDRROvZjoYzK/khUrFA5bCe1ZrL7Naokl9vBjB5A5TjIwD1UT4pUxgHpBpBOK", /*4D*/
194                 "c2BijO2YzSo4Ms/EtKaqHF3rd7YetNwEaFsQqERYi/hNGgYalZ4dmNuOh0yJcZS8", /*4E*/
195                 "vS1sXa3+WUlJMFCM4lm9ajSLr0xJxdIGPCmkBBNU5HAD9fLKFjQPUoXbEybZCT2y", /*4F*/
196                 "kRctwxWotSbGM7BbVeeZLE9RAgBqnc4Jl3mNKysohdTGFEpKL3lbnOe0C9wCnR2F", /*50*/
197                 "7GCwz8q2/mLqYcbVaX2XnVYV2AbY7wi/GFfqYKTu8SVllloftUZTonSijDXcmi/Z", /*51*/
198                 "pv/oY/w95iej/ZnO4sy5zQ2DdEl1W52XvpNmfUDImDK3QpujrV+dYuGEzXES01Qm", /*52*/
199                 "PFhu9tqkH6tmR9I2ore27rPG9f3NOAepTC2OZOWpyyijDf4MbL/l/YWE19djuACd", /*53*/
200                 "qhbqTgm/+3XyKdd8Ah+TSH8umwB5BjZdGuI9vUjR/N3h0JSwRPW/TSIsNZRiXA6c", /*54*/
201                 "0lOIlv8nOijyAw3qbAyWsDjbc6QHuisXu/TmltKHjGgPz2hdvOm3XLS/Rw4b16VX", /*55*/
202                 "L//kwaoIAd6ZK8bqq89G0wj2tZg/IC63vilLpYw9hYGAFqqfyNeupu3XOVwVOwnS", /*56*/
203                 "hEuX1JmsrgvatMmZpljyx8H1zEpeLGJvqr6Bl305q1jj/wHhZx+Bv/MOPByIwryv", /*57*/
204                 "PmyNUfsRsiZKeBAa1dq6ZGwYh6UGTr7mXM1DE8b1cdRd7arWDbuJg32hFIlnEoHI", /*58*/
205                 "fdKIu8MLLSvSelH/+tGnxa2Cn6BWkPOWTk3tbBqmOPtksvmmTo4wnbPG7EopzpeQ", /*59*/
206                 "orGQBpUryo/fItQDv/w+KatTY+ezJZGMcwGnoZIgQD129purTJerm25YjF3F/Khe", /*5A*/
207                 "jOzhwuiSjEBQQxu3FMn0SmkQ+83groZRZ3xlufrqhSOAypjI0+QI936QhJj4ucge", /*5B*/
208                 "eBgsaouV6EZHpngPQf1yIQSQKTrYnY6dJdBaJsMTCTnxy3cw4vEx0vPXgE5XPu7n", /*5C*/
209                 "skBe2KNnhVpzzz8TYfHsFtcNPLpvXNpS+0uz3oN55VZT0Wi33E8lgy24xjVf+RSa", /*5D*/
210                 "5kqd4cYpikkRuidg9Kr0LgWV84Sqfbq9TZTc9gQqC5RTDfwQVtN+TuFZfpDClN26", /*5E*/
211                 "gF9HP8QP3xQv+EsmjariF02Ti+XfW2KSgeqspBX0hIMrZNjFrl6cjodmghxf9Y5N", /*5F*/
212                 "2Shx98Q1I0qUuprSdhROVERQeCFjyE5lWkSAL7DZSrAg0MiAZBvgsL/Lo4heMm5Z", /*60*/
213                 "YtBIdBVVaYlobSMPTIywDaLE0Txb/Kg7W1NE4VN89QRAaOR7zE3Qt0ZGM5Ixmb5L", /*61*/
214                 "J84Cq+Y3eB2kPknUrlujPr76lN+1/crRTwwXYruAtZhDHEKpbHrFwzQWIMHCX9Zo", /*62*/
215                 "NnVxSLy66voVcy/26FFCRSPFzf2n6BizRBPJEyCDLnxSkGnRr12eTac3BYeMLiYS", /*63*/
216                 "ogKE7wtdPooJmQH6+sU7o/ViB9Cs6MtjeEGYgfGjJuq79kq70Xjrbl+EDjBxls9+", /*64*/
217                 "/ND1zHy2EQhrvZY0P6uMny1cNfEkfctXgN5bFpSFIVj4eDplijbz+mJ3JnYB2EzA", /*65*/
218                 "sCOqWud8QeZhF6bL47+nNO22yfiW4xOMY+0JS0ZmkFyD4lwsZGrLdsZJtD4qCI5J", /*66*/
219                 "oFp7NabeKm9pe1UVKzjaVK56I0YZ2Csw3P4eEYK7DI/T8iDOrS3dRdjRoujppXeK", /*67*/
220                 "KCqGNScz7OFEfJx+Gou2kuNj6ZncGFb0cxrdAkWYrHwNhHDNmAVlyP1ObaKEpV2a", /*68*/
221                 "XMFABwGbsRaaQxYQwEpUtKWZL56cdB8iD1dlmieKPqatctCtaRYjxwHIC3S6NbzF", /*69*/
222                 "lIY3T1rnRGxHdleKEM560tYVfvr6h8QX357iyNVUNmr6H2HM7V7jDJNQCcADjIrY", /*6A*/
223                 "LB9LvEhpEM8Sl7mQmdzAkTKrCeHjITsZZhbdCAbeQDMoKGC/d7ZbinG3lxELQSxA", /*6B*/
224                 "PlSlnPQPCOsnytZClUK5tAUyU8Fd1JlZPu8bijme6vfG3nZUdxeIvgBByJB3TQYX", /*6C*/
225                 "1vinUJGOMvP4/awEG+bjUhWwzvMQINhR2NV2ZjNz1llCw5Ed77yzTEm+M4C1mlgM", /*6D*/
226                 "VTjg3A7nuFRX/YeW6ZC1e90fK41oCP9sT5n+iwZtD/1ErokkMM6b6+TjYQYgH7Jm", /*6E*/
227                 "rWmWGGAAXi/kygA80PE6R7Tz0WiSKXgC0sl+OrwUh4jZ0utx8Mf5nxDb/13CXVqH", /*6F*/
228                 "2JmDRj56qeKhDcgyyur3Ox0jwraOrNwTl+4CEQ7JfiI0FDjwMkg0suuQsQODiBOG", /*70*/
229                 "/r8m4Gw7PTpZ7WiaO5XUGKB3t0pXe7sksdyDSdZ9y+CXrGmYQ4x2zzNgDpB6vGKA", /*71*/
230                 "xzN6irfD1DnrtLAq8i7XQ5QDpd2Ega5UNoXDg6B9Kgwi2Eodkm+8nUKqLhj+Ybss", /*72*/
231                 "TdILbICazth8ckVYpmWd9kiw8nbMgf/DWM5nysP9sXaK58v7CpfQzvP1JrdBKVBX", /*73*/
232                 "+fzOf8GuBuCRNQCeYqHKBRJTWJ/JDAW3kJQVHkBgkmZazFenWtJChAx3OEDNVYYi", /*74*/
233                 "ofPx02eN7pP01/jbSG2kvjxFRoYr8JE8WIoYBB98PWyE75z4h3Kp70v/ixBONkDL", /*75*/
234                 "JfhPDXPj3MaQJ5d9+FSvAo94T28P0ml9j24WTMZVwpCiyflLv59So2tPaTYRxM4+", /*76*/
235                 "P3vKxl4K4T2qrIXQgWAZfvdgXXDjDV/fdXDF3IN8PjmXj7ncwjvzpcAEEg0Ff+sK", /*77*/
236                 "BbyoET07O2/cuJUrq2kitRNfOLFO4u0S4bU2WGu6KyBJzFqSxTY27r8Jte72TCJC", /*78*/
237                 "kpq+xLvDDF8u3VTM/BNDWDZAOQAP6R/BI5f8cnxmcTOfjaxiC5kRlq1/MTzrufxM", /*79*/
238                 "uj9KiQpSjspAzJgAuNGevXx1898HRfK97DWN5nLFrkfkc7MnPVLU86sFOpcWHrEa", /*7A*/
239                 "fYFrwqaTwv8o2FlJE52eLL+bGQhkIaV/YdjMDd4C8KZd8yx/xZ2Pvkd2pIbf4lIT", /*7B*/
240                 "dI5wAeFbtYQ+nyAhN8XeOr2t32gemo+xLc90l4FQoAlihwo4XSmr5J8jnGgMW2Cj", /*7C*/
241                 "j/7fvx8Dx90KL4Nb5l0XC4WWcWW8KhYxsTa8S1NeIVFErgFdO30vnxu2g25CokPP", /*7D*/
242                 "SvAWK2fbMn6It2oO3kVvzkEL57hIhXElxPqgOc+LNtdHDIhJ7GNolXQWNJZXMw5y", /*7E*/
243                 "xtbZM456cAbGdtVs4r+EtmzEX81efvREt0TYVqgjG69+ZcVqkSemmBl+EqFkOQwE", /*7F*/
244                 "m6PANDHs2qUf21q9YEGgDMsanvKpxQ61r7/3ahKhL76zpMXJxAr8vinrsR/HOUeZ", /*80*/
245                 "Y6eDPjQt7G8M9VdXcaXbW7MRauQuKPbWJFUqkvUBtajKBbYGEKKCp4Fcl5bo0guh", /*81*/
246                 "7dAmIlPgqri3hA5HwDEYiSj/6EjWJMh06wY5rS7g5LUTp2Daagi7WvEpnmpmVwyo", /*82*/
247                 "CiPnsVI+nlImjvDJYYgUDD2ArRsTivwMn6ovkCTzCYxImJmHSe4xAldUKy5JiAY7", /*83*/
248                 "zRRoA8Xqpu/1XaqNHzx3AjHeAge97U4O70DX0FfXf7qLXwB0DF+AqPgePv97RkgU", /*84*/
249                 "DcdqAWa3ByrpGUI2NVwhZPH2/DX+fm/NZ5LChGDAXPBEpHkl8/I7q8m5JZot9HWs", /*85*/
250                 "ZITb7bUUOu/p0C0tgOAUIyp2KPmprt4UAlrhgLTrY1fm9c3oFMr3JbzmYdwQRVmO", /*86*/
251                 "CwAh/dw4LOanPe4X6Sqze1a2yUziFZ/k2GGj3FmC4lZIXyipCIA7tBvmSn6vtMYN", /*87*/
252                 "rtxCESRkPHA6BkUsNDMtc8tnRWKhfoc3FNFNYTTVcSjR9ZQdKglI57ccbQxvBSRF", /*88*/
253                 "+V1ZOoKxJeN8OW/J1Q0tdFH0qUCVHDZEuR8z9psvOAJnBBrpu6/LjqgE+RE4v45S", /*89*/
254                 "DfsxRlPGK/1smuv+NvClJ3UHHZHXdvjQcgtunKKz7xKhHYdePcpL3G/0CObmto8C", /*8A*/
255                 "SnsKk8jsF+89J/tyRrOXnY9dojVfg67GWx/CMJVGJ2yV51Bhoha8LxrHteCqk60C", /*8B*/
256                 "Vt0Hz0O+JG0vKo2jYh1oY6BKchG0yXKYCmkZfIW0grj0xgQojbqxh0kL9DbMmbHX", /*8C*/
257                 "D579c4WN++4KVpGbGQM0k4wk1WUWtA3/lkGY6gXhLjKb2JA4+OCM24AfkDyY+DI6", /*8D*/
258                 "rFshP/naLAisTye5oRjBZ4oZk/scUHSv0xLooKtcUlNuiv5eADqvyf6ypw223ELy", /*8E*/
259                 "3xRzu79/iNNCwyD38Mzc3RXEyDMcM8SyW3j0ZwcBZhaH5F39wbdVhPJ1GBjqxSGo", /*8F*/
260                 "8GKFQTGYKH7DhbFCMC7RKpaupjXX0CB8Qb0s4pjvi6ZDMtn4Ih1BoTgvPU9A+xPY", /*90*/
261                 "lEJmb6fAP+HL3f332ckhfvix1mazaB4WdDh0tX6Vv1Vm12SD7xMystRDZvmKuZtS", /*91*/
262                 "M1zbqt16bQMuAy2AX4MlBfK+otfY0Pd9t5Z2skR2koS5tfnR5CFeIf23DsRpNnR3", /*92*/
263                 "hHeJ6EtTs6mQUBpUg0L9W3iXHBLN/K+Xx4l5Y8nERsHHWdrLL+cgCE9PrqD04iZV", /*93*/
264                 "wr1y/SCec6SmTKXBpeVubVxOiMtveqlwSJyXnjMIYSunI7vWMDemk+VeBACrzh1b", /*94*/
265                 "24uM+OQUfELCmwOOhjCGHRstUFGiQNszPStdtMzJQ+AtewfutmcrKSp0TOK9Lzoc", /*95*/
266                 "atgWcPNp7T3D12asE3uUmpyzTN9Fhi2C2hCe8ZgPoivExCpCjRMDZx1KoI8T1jSN", /*96*/
267                 "LBF9JYuc5SjPn0nFjAZHhxoZ+YC3bsHWCK/3MxYVFrTDoaFrDeAwotKDW5a5bwb9", /*97*/
268                 "N/yPfxu89HDcD2vlMQPcOL0LK62QcqupxoMHPTyXB7MfEcrN9lXEvdzwuBeD4PAj", /*98*/
269                 "D8WFkk7C7grOGrYzeKTNOyMH7ln5hpmDuV5/jUoDWcm1T1ywBX6t1MQOep/Tozds", /*99*/
270                 "By2/DyO3JwJH7StjrdLXKNDvElCLj70HQjRA4DrUoEihSRR/IDmJmxny/bkBrR41", /*9A*/
271                 "Je8cMS6dEad5BO3E0CxTHgsK09h4+HIiQkyc7SxBnHb13ctl+vsvJo426iFn2HPb", /*9B*/
272                 "sty6Pwvp20tX6m+NOuwkEwANhTDl+55t9Mik+K+IGkAcJy6Ka7dcZUNv4b1tW1A1", /*9C*/
273                 "N3D1I37lFW4m+sFic3NiSQu4KRgtN2LJEWJN6jJo/qFjd275B+MmZ1tQdxYIYccE", /*9D*/
274                 "ZMFvijr/4kJosiidvLKF+yg6UyTwz1nFzrPaETk/yC4nanOdSscPrs9Mq4sE3Zzb", /*9E*/
275                 "ZecgHSJSnNcE5zyQc92eSUmD9H2YbQGbwcUv0Uq0+vz5/QC485MSgb7OU8oZxh1R", /*9F*/
276                 "3+0muHjuWaBayBdNKa9zRrWC8k1OfVJe41z5kyaaW9uW8lT7BNNRZcwvkWUNtz6r", /*A0*/
277                 "NYHHtmdPDH03TTDep64MOf6U1Mirn+FJFkWgN2Qbnhpa82qrvcRsiP4C9URzISkF", /*A1*/
278                 "7iy1QUHz7Tw/V1NHkrozgVoCZrwivjLLszxA3oMBSAwxz98ntIRbv1YhI7CNQlFy", /*A2*/
279                 "yyWOxTHo/IZ1/MtF/j/EXL6Z8ULAfIczHC7CDH/6EhIjmB99S6uORJ5Zp586NrGn", /*A3*/
280                 "bRDloO0vjC0/67s4aDYuGa+gzgqmaiI2apLzwV0o4efs2YMY+nEDkGbrYPMaO8O6", /*A4*/
281                 "4+C9EhahotS4TMsUpg2rgsb0AaxQTZoYR6b22aFdauO2EWux1iAx5HhT5zZCXzl9", /*A5*/
282                 "f4fzR81VwcBxyjTD5b8DS/dPhEsfD3F3xY0Ocqu7QzQGNIbFaIg/8FDrcsgRBdYP", /*A6*/
283                 "BmMotao9JYyslmFK9Tikml4soiPHCB0YoRA5jshJPGOwdSaZZ0r1yXbZOL2smN0f", /*A7*/
284                 "96l1ddqTCKEYoLJaAkpfj8D/azPwOAXYb2KJONNRlw8akb8luT44MGDMGc5onxTm", /*A8*/
285                 "mAW+xrodCLmSFMdpvNldeCsXbqUMWgOLiEhyADV4RolpBWVYyVcer2Ei8k+UTt7h", /*A9*/
286                 "0sAYJ03cXurkilqhTV0cyxUwFviCIyfGzlR7BeU0qZQN0Wg9GkiOZaBGCuUpSfLo", /*AA*/
287                 "zYL0GihG8X0Ge0Am52hLAbzdcIyTZOVsotqlct7S2jaAKQuc9jtXbSkDqrQUq01o", /*AB*/
288                 "X4tzTgbcaZz1NhxavRbMgxIbFG5eNpup6Mz60Fr6SCdJnNlHoHPQJgwMW1CCsQWw", /*AC*/
289                 "HP3QDqKithUlWtabcq8zkxssvZMyM8wi4YtesUnZJNcXcbkSBdvQaTxl1w2YqKyF", /*AD*/
290                 "8rN71ynGDiOyfCkdmVsRQ2/HUyx5Vfmip1vi6yhnp0gARDgFpGLmfGad9Gt+a8Dd", /*AE*/
291                 "C0FEdr253SAGjC76sZFjBQB8Fs9R3k7KcPg2BVUrYEb0H8KXJWdAUEuE+4pu7PgK", /*AF*/
292                 "g7hRknTFIwAAfmvWhk9aM4/O+j7tPTWu3jV71iYFyD9TvIDa+3iQDRRM/vPfAHlG", /*B0*/
293                 "E4FEar6ynA8pWJpqG1SN4w78VPPaUzln6WmFfyeKgTw7KhLbd+oWjYTqthgDhgrk", /*B1*/
294                 "UF59LfQRzniNmZwZ/233hMs16TqOV5uZEjLmGywJ/dnYFtOsYzzzMQxc1rgwgKBa", /*B2*/
295                 "6U+onOHbmAA3IRTRF2ZC4hvieGoWxMNj5LADPjVFsXTECOXqJAg89CpgKCVi5sFY", /*B3*/
296                 "b2pC0ebrJ55Co19rCmBqKnADqWsw4veP3d0+aBrZg9+IUyLwQiRXKQoyN2QbD8zp", /*B4*/
297                 "TgaW6IDzTQWkiK2jShq4+m8VymxIJnT4YClHN4I8G7sKlj/3fLjAfgh4D0fm11dc", /*B5*/
298                 "GkphrAPhWFffWBP4hu5qdmo5dNxRuj8gH3LFafk9yXiXZRkw4jKe5lu5is3Oxofi", /*B6*/
299                 "l8wNDMGnBipfdKZoginVmbNYSHe7GNjyhthkTw2CKtWBOSZ6+I6AL3bGR2NuIJG7", /*B7*/
300                 "RsfgHNfGRwgRHnxEG0X9hsxvheKwIwbCHhiYAy363TpGazNroKA2Z30lsbLuCsfR", /*B8*/
301                 "dpcaFA0mM1bbo2xZX4Aw1UbON5T2PuOMiHB0fulULfbqRZtIGJNc38pQqAuf0qqk", /*B9*/
302                 "n21/dhZ7vb3dtrfxJ4SW9+52UrOZZcdYkdetbH9Mbyh7EUIXQMCIgWPRZkKW8cTO", /*BA*/
303                 "JFsTtabo5Jd3eSnlhdeLirvFW5egwUVFfeNZn73j+hMr3pEOfGLVr6nhdIR3rCOi", /*BB*/
304                 "O2ts+OrxG97+NQDVrKNGos0hatmdF4BvAw0wF8u3jT9sUJRdi3l6SUHoGvbG3FKt", /*BC*/
305                 "C0QfjtDhpPTgImTVPGMnXiAUtB1PwWUUwjeNmEOQk5pos10k+lzmy1Wo3SjerkBj", /*BD*/
306                 "VCSJP1q2eh+htb5+FrQK140CwiToMSabvBkV49572dWMBeRJdMct6v+6L20tTyDr", /*BE*/
307                 "XWaicZHmN2UjP1pDNfjSP4psLWI+3dWt+EPi5dXNIsWiqP3b8yfsWkUUDlftZXpH", /*BF*/
308                 "Y50u0wHLpztrQbXnNFcznvY5RfmEatkODaf1beTizkUc7K/p4S4U3t1y3E8cEtZ4", /*C0*/
309                 "dws5U/YKs3u2e49/K085LYk0rxPCo3cChNBW3XTm9n1RJMRzMM1DVhjcodGLX7H6", /*C1*/
310                 "iw0V9atTtEKM4YgRnBA/kfk7tB9jt3vCGYQQ74Xm3evqM23Fh3zWdoTwQK/Ac+yV", /*C2*/
311                 "+wv1oVk95LwARtgEyidwuktkvqKY22/7Su09mX533tU6D3HfHp+j/EGIjYU8ieWl", /*C3*/
312                 "/Kyu5nbHisbrBmGGx2eAU+P9Ti81SnvSeOMBv7OifYRYbZI2weN5PBAWqiaHvFf5", /*C4*/
313                 "EsbHA0IsSZX8IYPusQ3WDUIr9gKp69nh8qQ3Dn2/LepI2vWLCbkf4TijjoE/If7b", /*C5*/
314                 "3VZHbTEhyxdqFECBSVKJuIhChID1EoFkNY/V98OtR0l3U2riKM4cZZv4N/PaAzgL", /*C6*/
315                 "47bm3OIWq77fcpHjyOw5jw6c8j9VyXxgpwtPTxUV/UvkjEC9tjBi7plOFg0RVLY1", /*C7*/
316                 "1BzB0hv/3a2gGm66LCYaKkZaRwkdKfILMt70raugk0xjPjMnE47ucyg70fUxIK7z", /*C8*/
317                 "XKXZsqt8bCT24B4sKMfpUNfToGWVoL0v66QEnGdSZRmC3aYp2mZ8E79W2ktra6cI", /*C9*/
318                 "EIbi45vFo3xI4nofz3XdajVkenNQdHQBO5K0spwl8qEQcs6OXvXI4Ju2UPOYQ5bX", /*CA*/
319                 "AVGC0U6GReDFoeGTkZZUrMeUB02TWtgjE0JKc8uI+rT51aO91r9cfCWIdDjpf2Bm", /*CB*/
320                 "gdSAodJv87r3mJUbrEDE6mywt/+ATaKaY/FYc1EfYHk7totBMRgH0QM6fa6mCZaB", /*CC*/
321                 "UeW6zdhSkT4W0D0gP3mthpGo1Ip36zq+GGZr100lECgnwzZm481dm4zFi4ZlrYoK", /*CD*/
322                 "KhWTDXhyBm2RgIJ7JAXn7j9GN/F2ub2ev8HQonM+3qfHagSgC6Bx+IY08gOolkxI", /*CE*/
323                 "+78Gu9q8xw+zCWM9+z9c92KREAPRBaPsYf9PIDtQPzeiP5ZUnywzzrTNQiKlIESa", /*CF*/
324                 "wZjReRFIHcdpJenORShaULVVZ932vznzRZLojSvV6osryg2SZW5oSzeK5j6kP1mZ", /*D0*/
325                 "ARXmF9doCtmmYZGhriC5m+SxDtmWbz0vfT1RELrsFd8xGPC0OdXl5jbO/ih1etHH", /*D1*/
326                 "r/vrtL7wT6DKo9o9Wwrp5UWh9AkiVFOEB6e1K9f/poBqvxpacMTgFH1nisEf7JnW", /*D2*/
327                 "dRUY4yShIXBflK0XKK563FpWDX8eUrWL7gUIL3nTcWYaOkGUo46I08z5W7VHfk3O", /*D3*/
328                 "aN6qPCZA9CJ7rC53h7J75+lAKpZ1N0kpG7mMpn+iBh7Hub0qkwLv3TNSF9yIO/B5", /*D4*/
329                 "kSM+tRfV9mU5HAvwomXbl1VIqoWbrncdcQebPps7ExnUs30a8dl2Y4Rh4Vov0JqU", /*D5*/
330                 "O5Kd4M00RP5ScDtx/fywAzhyptSQMnEtlu4p9m+UVisoxLOyAV2hYKAzOXmvXh0L", /*D6*/
331                 "S0kNDvv8QLze0bPHSEYco43sB5ohPBHxHL3CpbG+eCOUoXCAR8MMGSlj9czhttpj", /*D7*/
332                 "kb+6gp5rG5ABENZFTCMqh2xtzMGVaqRslSLw4BWTdyKs5ms0lpOlYEaISMsDpWf7", /*D8*/
333                 "C2aXTPdA1FAM/u1kv8oe5yLOGFeJGyCABtM1TYCJXaCG0LCiAgRwj8DfpEwzy28y", /*D9*/
334                 "1c0FoC7Q+7wVMVV1Rloi8GKvp5I2i+EICu2MDIJK0wXqgD7DzteoUZyHrj9QB8AK", /*DA*/
335                 "GlI8yLXvPvSsQYjEX7Dp5fm1hb84LMV5qfc7rhgIzSZ0X4/KMlw4T1JHlXsQInvx", /*DB*/
336                 "sKSYkZb8SBocTgy7QImn2ZF2DuabHXhCMIoPaPPK0Ycpr2pgk/Gf0JOHBGC82hhF", /*DC*/
337                 "NKBWShNIXfC5adyR616miWI85mA59MePkl5B+Z9rHPo1eTRWTp0hfoXvCt7WSGor", /*DD*/
338                 "/V8ES8X5fxqyaJQuVqmgRJK/Hi2iJRTxDo7SCxIzjSBi4YCvl0HX8pNs5t9zyu3O", /*DE*/
339                 "pMkpnUOQcdWdr14r3AfARNzOgKdI323vsSRgqeQFsmFd/sOEzraFGCHO4raGabW4", /*DF*/
340                 "mX4jNPqsbfPQ/rxTUutFvsAasrhGaSxAZ83p5/ymYCT8KSYWW22a+B6C23Sjzmz2", /*E0*/
341                 "HRrD3HRg4BbDOPrDegFy8WDthLdLzsG7ceYq6Lyoidq7wCaN+8/aptb2CZaugVEY", /*E1*/
342                 "YXbRlN3bEPGT82m6TLuf9QBePD/7YDtGrHiO/pa4YBy2Wt6VZ+KzXhliTWXUKHOZ", /*E2*/
343                 "YUviqxiRBiFq/M6PxLgcgQL5VvssAztIV8CMGUjoMvtwT6BiVIEgpuJZSYnROACQ", /*E3*/
344                 "0Oz/m3gJ1VqgnPYlg17N3YKMm80aj00VrzzOlF73fay+VIez0VRlbeeGhHOvZNu1", /*E4*/
345                 "v0OarKEIozWS5OazWoBHJo9YYW9hSrdLTvXbW+4CRvrbdHEKR2LdP6z6CKg8Q5VX", /*E5*/
346                 "BaZMd7iUoFEl8u50TJcHX1Opga33/ioC1m8zukvEZwk9uuyKkSejigo/PFc2hAv3", /*E6*/
347                 "w2YHQoNPN8988D6hARnzcQ/c+d7HVq1jMaL1Wei1W55MPom5O0W/0GCXccJmS+Gh", /*E7*/
348                 "SD79c8xhGLThS7A4oXkdRheo+zd90xBApCUyaaoiln2aeSaBS0UEIrZuzdyH1KUz", /*E8*/
349                 "IDMFejHQkdJ2Hw3l8Xh24sefFWM6Zj2aUrS6Zz9Ne60czjMrXsCcJsO8NNccJrgP", /*E9*/
350                 "7iVKPW1U0PPyt8korXQotCgtlimLeOxzU4UrE0g650pmC5Gg15lsdVxVLXHC4qfs", /*EA*/
351                 "3R+RJL+ln1VLVXA33vXdoUa5ZpMT/cPHpCsdiAzMfm6HS+Unam3nFHi4+sT71VJz", /*EB*/
352                 "CqyN7StimvEuWvx+XY5UNbJX8LR0ScjKrjUDPdB+Mas4F8XyOMEPcRY0QFpJzJCc", /*EC*/
353                 "YQTxNrnep5+dL0ZYC5tSoWXsucgRkRCf6jNORCjroyM3iRF1yoRAVcLqRsmnWJ1Z", /*ED*/
354                 "TqxWeLuqw26vzMvBB2kOmPXLAMetV4Uf9NlIr+Acy32Kq5mB39qzfxLz2/q4bbPm", /*EE*/
355                 "YBYQej8ND8CXxrYtsZRbYDhftqJ7T5R5vOJH3d6KhUArsJ8O20sEHjmVEKMBnceG", /*EF*/
356                 "KkiYWz2JMZcmA3n5Z+KN+11QOhQH9ICH46jTzPyuHKT+p7fXs/BCoKyhGbv+UTE+", /*F0*/
357                 "UGk6AHn27ecSq8ao1Jf8uppVeZy0lsATGVBLQwElBcMJ+63nI/uAEsAvvTFdkFkZ", /*F1*/
358                 "W8b8/EYMXFcZtDQ/h15i/qO4UX/M/ZYWwOdaDvNWnMcVrX/SHEbjFFkoR8u5zHsb", /*F2*/
359                 "Fo/M5Vj+Bji/wTRn104k+FbbXQ8OlAROe4sVxN2v0FvJxRGZlLrGpCaXrlXBKm7/", /*F3*/
360                 "REERuETIx0kAyzXKG+RQtHz5vmfsUCQwiw0e20kgZqj6uI5SIsBp2veiwYVl8btq", /*F4*/
361                 "TgR/9g1CuzezB+/i8+nA3EF4dxiGCBBNrtoFkzflkgSPEuQ3HHmkPRfqpMtFhGiA", /*F5*/
362                 "nY3P5HyKOVGlnKaR2PylSaUtOcIOpnI9OVWrebiWgg7eC9wurwDLa5A+S+VIOLm+", /*F6*/
363                 "GS6SGCrF13r1uPXEVywpKQvBd6WYH8/wzWC2OymfKwf7tnVVT2C4Cdv8uYFqOcve", /*F7*/
364                 "3iDCtK3XSiUNB6CVD+JibNibMDnzieutnyiLF8yF9qKlle5dW5BDk4Z8l6I0D8Pg", /*F8*/
365                 "qr/P9xrVnGYdJ4Bob4Dg45C/mOBZwjRpSXLK+/Dq/l22GEGLlEv3icMHaPvqCmRT", /*F9*/
366                 "IOFLwNysO91RjhlkvUlJbXSKWWaWs/0xgVrBwOltvLt5YsBhHCB/8t1cTujjrzgn", /*FA*/
367                 "3hFkWtMf180/Uoc+eRLAPPM2yg9y+M+wEvAAc+Bf6JMLCT8mhaCU6OyQ+toBCvYt", /*FB*/
368                 "3fq07rENpZ2aeXSZnOQk5bnLJGry/wnezees8+lxna+d7GYlprFi61M1fSGxKtAG", /*FC*/
369                 "IjXgGjnmMd0V6TVbBtGskxiS5wPMVuv08ZcMhVyBFwdvClTAimpPv/B/UOldrvj8", /*FD*/
370                 "B7JQ3BO0RavV2FGVNhe0QBByjhBqKDLKr5PQ2FReIgPpdqUeWaVsS2LgxE13qxJO", /*FE*/
371                 "bLls31D49NldM2cWG9i6iuVynOfPeUDLlmkxPnYvVOXEl9O5eUs+MBFRlIsDM2nk", /*FF*/
372                 "AiUNO8VcsXVYQ1Kga8ob2n5rwFZ1l9qeJRMKz35yV2z4w+V4Wj1h3FqUtKOULQbO"  /*00*/
373             );
374
375             public static readonly Table<byte> MIX = CreateTable<byte>
376             (
377                 "BQMEAQIA", /*00*/
378                 "AgUABAMB", /*01*/
379                 "BAMBAgUA", /*02*/
380                 "AwUEAAIB", /*03*/
381                 "AgMFAQAE", /*04*/
382                 "BAADBQIB", /*05*/
383                 "AwIFAQAE", /*06*/
384                 "BAUDAgEA", /*07*/
385                 "AwQBBQAC", /*08*/
386                 "AQIEAAUD", /*09*/
387                 "BQQDAQAC", /*0A*/
388                 "BAIBBQMA", /*0B*/
389                 "BQMEAQAC", /*0C*/
390                 "BAABBQID", /*0D*/
391                 "AgUDBAAB", /*0E*/
392                 "BQIBAAME", /*0F*/
393                 "BAUDAQAC", /*10*/
394                 "AQAEAgUD", /*11*/
395                 "AgUBBAMA", /*12*/
396                 "BAIAAQUD", /*13*/
397                 "AQMFAgAE", /*14*/
398                 "BAABBQMC", /*15*/
399                 "AQUEAgAD", /*16*/
400                 "AwQFAAEC", /*17*/
401                 "AQIABQME", /*18*/
402                 "BAUDAgAB", /*19*/
403                 "BQMABAEC", /*1A*/
404                 "AgUEAQAD", /*1B*/
405                 "BQADBAIB", /*1C*/
406                 "BAMAAQUC", /*1D*/
407                 "AQIEBQMA", /*1E*/
408                 "BAADAgUB", /*1F*/
409                 "AgMABQEE", /*20*/
410                 "AwQBAAUC", /*21*/
411                 "BQADAQIE", /*22*/
412                 "BAMAAgUB", /*23*/
413                 "BQIDAQAE", /*24*/
414                 "AgQFAAED", /*25*/
415                 "BAMABQIB", /*26*/
416                 "BQIBBAAD", /*27*/
417                 "AwUEAQIA", /*28*/
418                 "AgMFAAEE", /*29*/
419                 "BAUAAQID", /*2A*/
420                 "BQMBAgAE", /*2B*/
421                 "AgUABAED", /*2C*/
422                 "BQIEAQMA", /*2D*/
423                 "BAUDAAEC", /*2E*/
424                 "BQABAgME", /*2F*/
425                 "AwUEAQAC", /*30*/
426                 "AQAFAgME", /*31*/
427                 "BQQDAAEC", /*32*/
428                 "AwAEBQIB", /*33*/
429                 "BQIABAED", /*34*/
430                 "AQQFAAMC", /*35*/
431                 "AwABBQIE", /*36*/
432                 "AQUEAAMC", /*37*/
433                 "AwIBBQAE", /*38*/
434                 "AgAFBAED", /*39*/
435                 "BAIDAQUA", /*3A*/
436                 "AwUBBAAC", /*3B*/
437                 "BQAEAgED", /*3C*/
438                 "BAMFAAIB", /*3D*/
439                 "BQIBBAMA", /*3E*/
440                 "AQUDAgAE", /*3F*/
441                 "BQABBAMC", /*40*/
442                 "AgUDAQAE", /*41*/
443                 "AwQFAgEA", /*42*/
444                 "AQUEAAID", /*43*/
445                 "AgQBBQMA", /*44*/
446                 "BAAFAQID", /*45*/
447                 "AwUAAgEE", /*46*/
448                 "BQAEAQID", /*47*/
449                 "AwIABQEE", /*48*/
450                 "AgMBBAUA", /*49*/
451                 "AQQDBQAC", /*4A*/
452                 "AwUAAQIE", /*4B*/
453                 "AgADBAUB", /*4C*/
454                 "BQQBAgAD", /*4D*/
455                 "AwAFAQIE", /*4E*/
456                 "AQMEAgUA", /*4F*/
457                 "AwQFAAIB", /*50*/
458                 "BAIABQED", /*51*/
459                 "AQUDBAAC", /*52*/
460                 "AwIAAQUE", /*53*/
461                 "BAMFAAEC", /*54*/
462                 "BQIDBAAB", /*55*/
463                 "AwAFAgEE", /*56*/
464                 "AQMEAAUC", /*57*/
465                 "AgQDBQEA", /*58*/
466                 "BQMABAIB", /*59*/
467                 "BAIDBQEA", /*5A*/
468                 "BQQAAQMC", /*5B*/
469                 "AwUBAAIE", /*5C*/
470                 "BAMFAgAB", /*5D*/
471                 "AwABBAUC", /*5E*/
472                 "BQMEAgEA", /*5F*/
473                 "BAUBAAID", /*60*/
474                 "AQMAAgUE", /*61*/
475                 "AgUEAQMA", /*62*/
476                 "BQQDAgAB", /*63*/
477                 "AQAEBQMC", /*64*/
478                 "AgQFAQAD", /*65*/
479                 "AwIBBAUA", /*66*/
480                 "AgUAAQME", /*67*/
481                 "AwIFBAAB", /*68*/
482                 "AQUDAAIE", /*69*/
483                 "AgAEAQUD", /*6A*/
484                 "AQIDBQAE", /*6B*/
485                 "BAUAAgED", /*6C*/
486                 "AgQFAQMA", /*6D*/
487                 "BAMBBQAC", /*6E*/
488                 "BQIABAMB", /*6F*/
489                 "AgMEBQEA", /*70*/
490                 "BAADAQUC", /*71*/
491                 "AQMFAAIE", /*72*/
492                 "AgAEBQMB", /*73*/
493                 "BAMFAgEA", /*74*/
494                 "AQQDAAUC", /*75*/
495                 "BQABBAID", /*76*/
496                 "AgMEBQAB", /*77*/
497                 "BQQDAgEA", /*78*/
498                 "BAMFAQAC", /*79*/
499                 "BQQAAgMB", /*7A*/
500                 "AQAEBQID", /*7B*/
501                 "AgUDAAEE", /*7C*/
502                 "AQQAAgUD", /*7D*/
503                 "BQIDBAEA", /*7E*/
504                 "BAUAAQMC", /*7F*/
505                 "AQIDBAUA", /*80*/
506                 "BQAEAgMB", /*81*/
507                 "AQIDAAUE", /*82*/
508                 "BAAFAQMC", /*83*/
509                 "AgQDBQAB", /*84*/
510                 "BQIAAQME", /*85*/
511                 "AgMFBAEA", /*86*/
512                 "BAUAAgMB", /*87*/
513                 "AgQDAQUA", /*88*/
514                 "AwIFAAEE", /*89*/
515                 "AQUABAMC", /*8A*/
516                 "BAMBBQIA", /*8B*/
517                 "AwUEAgAB", /*8C*/
518                 "AgQAAQUD", /*8D*/
519                 "AwUEAAEC", /*8E*/
520                 "AQQFAgAD", /*8F*/
521                 "BAUBAAMC", /*90*/
522                 "AgAEBQED", /*91*/
523                 "BAMFAQIA", /*92*/
524                 "AgABBAUD", /*93*/
525                 "AwQFAgAB", /*94*/
526                 "AgUDBAEA", /*95*/
527                 "BQMEAgAB", /*96*/
528                 "AgUBAAME", /*97*/
529                 "BAMABQEC", /*98*/
530                 "AQAFBAID", /*99*/
531                 "AwQBAgUA", /*9A*/
532                 "BQADBAEC", /*9B*/
533                 "AwUBAgAE", /*9C*/
534                 "BAIABQMB", /*9D*/
535                 "AwAFBAEC", /*9E*/
536                 "BAUBAgMA", /*9F*/
537                 "AgADBQEE", /*A0*/
538                 "AQMABAUC", /*A1*/
539                 "AgAFAQME", /*A2*/
540                 "BAIBAAUD", /*A3*/
541                 "BQMAAgEE", /*A4*/
542                 "AgQFAAMB", /*A5*/
543                 "AQADBAUC", /*A6*/
544                 "BQMBAAIE", /*A7*/
545                 "AQUEAgMA", /*A8*/
546                 "AgMAAQUE", /*A9*/
547                 "BAIBBQAD", /*AA*/
548                 "AwAFBAIB", /*AB*/
549                 "BQQBAAMC", /*AC*/
550                 "AgMFBAAB", /*AD*/
551                 "AwIEBQEA", /*AE*/
552                 "AgAFBAMB", /*AF*/
553                 "BQIDAAEE", /*B0*/
554                 "AwQFAQAC", /*B1*/
555                 "AgABBQME", /*B2*/
556                 "AwUEAgEA", /*B3*/
557                 "AQADBQIE", /*B4*/
558                 "AgUEAAED", /*B5*/
559                 "BQQBAgMA", /*B6*/
560                 "BAIFAAED", /*B7*/
561                 "AwUBBAIA", /*B8*/
562                 "BQAEAQMC", /*B9*/
563                 "BAIDBQAB", /*BA*/
564                 "AgMBAAUE", /*BB*/
565                 "AQUDBAIA", /*BC*/
566                 "AgQBBQAD", /*BD*/
567                 "AwIEAQUA", /*BE*/
568                 "BQQBAAID", /*BF*/
569                 "AgADAQUE", /*C0*/
570                 "BQQAAgED", /*C1*/
571                 "BAIFAAMB", /*C2*/
572                 "BQMAAQIE", /*C3*/
573                 "AgUBBAAD", /*C4*/
574                 "BAAFAgMB", /*C5*/
575                 "AwQBBQIA", /*C6*/
576                 "BAAFAgED", /*C7*/
577                 "AwIEAAUB", /*C8*/
578                 "AQQFAgMA", /*C9*/
579                 "AwAEBQEC", /*CA*/
580                 "BQMBBAIA", /*CB*/
581                 "AwQAAQUC", /*CC*/
582                 "AQMEBQIA", /*CD*/
583                 "BQADAgEE", /*CE*/
584                 "AQIEBQAD", /*CF*/
585                 "AgMABAUB", /*D0*/
586                 "BQIEAAED", /*D1*/
587                 "AgMBBQAE", /*D2*/
588                 "AQUABAID", /*D3*/
589                 "AgQDAAUB", /*D4*/
590                 "AQMABQIE", /*D5*/
591                 "AwAEAgUB", /*D6*/
592                 "AQMFBAAC", /*D7*/
593                 "BAUDAQIA", /*D8*/
594                 "AgMEAAUB", /*D9*/
595                 "AwIFBAEA", /*DA*/
596                 "BAMBAAUC", /*DB*/
597                 "AQIFBAMA", /*DC*/
598                 "AwQAAgUB", /*DD*/
599                 "AQMFBAIA", /*DE*/
600                 "AgQBAAUD", /*DF*/
601                 "AwUABAEC", /*E0*/
602                 "BQMEAAIB", /*E1*/
603                 "AwQABQEC", /*E2*/
604                 "BAUBAgAD", /*E3*/
605                 "AwQABQIB", /*E4*/
606                 "AQAFBAMC", /*E5*/
607                 "AwIEBQAB", /*E6*/
608                 "AQQFAAID", /*E7*/
609                 "BAADBQEC", /*E8*/
610                 "AwIABAUB", /*E9*/
611                 "BQMEAAEC", /*EA*/
612                 "BAIFAQAD", /*EB*/
613                 "AQUAAgME", /*EC*/
614                 "BAIDAAUB", /*ED*/
615                 "AQQABQID", /*EE*/
616                 "BQMBBAAC", /*EF*/
617                 "AQQDBQIA", /*F0*/
618                 "BQIEAQAD", /*F1*/
619                 "AwABAgUE", /*F2*/
620                 "BQIEAAMB", /*F3*/
621                 "AgQABQED", /*F4*/
622                 "AQIFAAME", /*F5*/
623                 "BQQDAQIA", /*F6*/
624                 "AQIFBAAD", /*F7*/
625                 "AgQABQMB", /*F8*/
626                 "BAABAgUD", /*F9*/
627                 "AwQFAQIA", /*FA*/
628                 "AQADAgUE", /*FB*/
629                 "AwUABAIB", /*FC*/
630                 "AgMEAQUA", /*FD*/
631                 "BAUDAAIB", /*FE*/
632                 "AQQABQMC"  /*FF*/
633             );
634
635             public static readonly Table<uint> ADD = CreateTable<uint>
636             (
637                 "jMGyEw3jMK9hrRBfpv/16KyjUnl26RXy", /*00*/
638                 "usvJp51XPL+zYiCMjf6qVQEYFfi0Axco", /*01*/
639                 "OMxp7qlUrHQ7SMiEeFCbBe4ZMz/RjCRL", /*02*/
640                 "ZAJ+7jWDeD1zUIbUj0F0G+D2WsZTWA2j", /*03*/
641                 "vWvIotNSqLc8YZdfehl1X+gFiNepMjUV", /*04*/
642                 "izHV8h79MFxtE3c43U5vxL4LpJdu7s+f", /*05*/
643                 "DAW42laUHGXgshByzyG26m4D8mDAz/nb", /*06*/
644                 "FF5X2ByqhPDAdh6cqWxvM/7LcYc4LRPC", /*07*/
645                 "oHejhtoh+b9Xa60WRQqIyN3Opq45qZv3", /*08*/
646                 "m3QIoIr7PCmSTIp+EfKEXoV0zzw+w1SO", /*09*/
647                 "bxd4mqvscniZEeZ+zfA59w2iK4ulObNy", /*0A*/
648                 "bJ+3+WNN9CdbpuXQfiwJBuZg68QQ1ASD", /*0B*/
649                 "2pKanNGM5vhKf6dth+sTIIWG1NVXpdfQ", /*0C*/
650                 "d4hgEv0QY1s9bSlBg11DV9zfBqlybRo6", /*0D*/
651                 "5scSUVHX9uulJjD9I52jCPFPE1SKLFvs", /*0E*/
652                 "5u5SL9NTqECB7Ys132Jrx09ueI53NvZ1", /*0F*/
653                 "ftKrVLgr7rfBbXUXuzvetkC1kqlK5KRm", /*10*/
654                 "C2+Mm7HOojwJPFi9UTZxFN6nearF0cMo", /*11*/
655                 "i/e0q9iU4dPjhQqqlrHHyQ9xhTgL45ID", /*12*/
656                 "kOoioTYkGseCXD8i/6SwjNFXm1udaGrx", /*13*/
657                 "DTv6epNd4HWhB32+mIXIicHw2/s+9kds", /*14*/
658                 "P7rS08/wxGF9EkufeqWv6h2TzgiFaezJ", /*15*/
659                 "oix5sCxb1jnd5C99X+XG9EuzJm/yFiw5", /*16*/
660                 "YL/vWVqtbwUwu2wgvmWu3K7cedbb5k7d", /*17*/
661                 "48vgP67BFj2q6BAufzxN7Ixrwj4zL5XB", /*18*/
662                 "L6oV1aXnACQ6/nFOCf6N152YzbPr4zGg", /*19*/
663                 "DJVLaHqbRB8m773VrWJl6/P1KCv5+T0K", /*1A*/
664                 "uRE47IfdU3+HsqkLr2rUszSQDdP57gqP", /*1B*/
665                 "aGc2dqHW+YFW24Yzvwuy2ZfiAVY2YmQw", /*1C*/
666                 "hFzaf4EIO5VyzEqs7lpWNdsPVNPdZCwH", /*1D*/
667                 "qqsZX/XlHsleta/1oZboK9UJxOEP+ul0", /*1E*/
668                 "n81y03xuZ1v4WvtMIn83r4yFMckNzkVU", /*1F*/
669                 "fyw7QkFWaVhl+PdTS/GP3RKwhzfWcJB2", /*20*/
670                 "fUHQ3DqBFPm/20E4vikbYAG5t7RJpsPc", /*21*/
671                 "653iO9Cg+e0P+t3yzCMvksM7VsRyLxLk", /*22*/
672                 "ZkaL6JC6zt09MXtbCtwPvtkxRF21zgVt", /*23*/
673                 "a2TyaxTvS55oqn2xlrgec/aWebTpmQY8", /*24*/
674                 "lOKIPgJy+WYEvR1wfm/PkdSlgbzrMrbV", /*25*/
675                 "1TIMX4+zGAGLd3J8yVHiRXam6Q6a7Yzh", /*26*/
676                 "FUbsDTTK+rybzzN6AkL8f5hsAzx/EbAv", /*27*/
677                 "ghjoS7nGK9FCGaz6k7clyFlQIz2ysA0M", /*28*/
678                 "4klAHWq4hCp+239TDrSB7D852n3Q16Ov", /*29*/
679                 "RG1rAwNM3ptlzF6AZ4a0L3m5TInPuXmL", /*2A*/
680                 "JOehJnvkQcBcBFLFzAL1XUd+t4Y98zfM", /*2B*/
681                 "FDdz+PfpSYDfKyYA2yTj1qTBhqKLmU70", /*2C*/
682                 "g624KvZe/nHo1gVJd63aFqwMdQTnFO4A", /*2D*/
683                 "4YLkyUVPsFRrY8YF0h5QoyMq+/nMvl+J", /*2E*/
684                 "xSQ9rcx+AdC4gajfUjzcSC2d5pcc0sXv", /*2F*/
685                 "RMhWzCbwW4d62/CKe5+qyNjhd3k4fFWW", /*30*/
686                 "0k9wUU4XUcT8xcAdMgRpPEk9Ee7hOy8c", /*31*/
687                 "0qR75tAqoRywCV5MJgrJjO9csWvPC6IE", /*32*/
688                 "Hoao80u2qKvBcx2nZlU/s7vCgNez8aQ1", /*33*/
689                 "DuXGOu43ggXi08wo6TjBZWJfFjZSE0a6", /*34*/
690                 "VKSQwUtKsTuLT6pur/hUxNkJ+yN6O4vM", /*35*/
691                 "qFV7mjk9f7kc95W95F92+L805GDjyENN", /*36*/
692                 "lKdJdORUwBcRRB4DodGKy1iurUkePcW7", /*37*/
693                 "izLURGcVnWAFjicdqRrdWmT9yJj/VLlW", /*38*/
694                 "VF6/IqbY+dpDIyNtwfOOSHZ3FPB0xoVB", /*39*/
695                 "o3C/vmmNwB4bn05AF5FdRIAutzzlhVZH", /*3A*/
696                 "rGQ+VkoB03H7HHRyJssu8hrEUUVD7CMA", /*3B*/
697                 "K93p45YZwzegZl7lDR8t0bWZJTQvSG/F", /*3C*/
698                 "4+mp8Y0tDnc2ogtLcUx9eW/pFFWGhpO9", /*3D*/
699                 "Wd9VKi2YGMwmjTsJCkf3eAOacU+ef0NK", /*3E*/
700                 "aSKrlzOiIqwXHT1dHjUGeTpYyT2SIet/", /*3F*/
701                 "peMReb9mvNMzb7lw92TDEz035GujHO6V", /*40*/
702                 "uRtLYml/1bHavtYjWXPEFL4bxlO6DGOi", /*41*/
703                 "V7YUhvETzTDCuv/cZmkaCeyZidFUw6Ou", /*42*/
704                 "ywC7zoZFwUTeKrqXb+HgWIiL1u/IQnd1", /*43*/
705                 "m2HWrc6ARMaSvhWaXAUsfv9P4+DdRLdT", /*44*/
706                 "uI5ZGB+OELkVyLWUUzD6eXcTHODy12d5", /*45*/
707                 "EL3/r/Ou6g0/JGYc8wFm3ZsGEiCEXARD", /*46*/
708                 "S8osVEKoeFi2MC8pfYK7qj0LI9gvCGIy", /*47*/
709                 "8N1k2aZRg03WDRT8coZrLZTTMgVBdGfK", /*48*/
710                 "YblYm/Sa+ZuHmIpHfN53StS3YAWHGKOx", /*49*/
711                 "zBU0PImBS6z6k2ew8sC5wBUbnUfYU6Mf", /*4A*/
712                 "etMHU+uEdo5iIznpOLoGbbY6hMHO3eyn", /*4B*/
713                 "P6yTqw1Ow7i+nEcXIv+5ObMyJcuTnha0", /*4C*/
714                 "h0d7bPNIUCkBGEAnsMouWTqQNo1aJcfN", /*4D*/
715                 "pBLkGx2DanJftwDryvw7F9uuL5V9gepD", /*4E*/
716                 "EADE+xfbC9GuID2u0n80IDZ28K9uzIal", /*4F*/
717                 "SA8AA8wycyytCgKwTbbsCWQouNvA95yK", /*50*/
718                 "ZF7QwH0dkhHQmveSxV4fTMmiirMcgxEF", /*51*/
719                 "OAkZjfvoOm+P9O3IVKts8qT657AhqsIW", /*52*/
720                 "WJycNcNAkYi3vHBeVvOsWPuyvcPV1Yio", /*53*/
721                 "77n2hGhBVVy3yo1KQMPtXfd7xUTbrb8x", /*54*/
722                 "IHcsxBvR2pRddPwpOUYfPPxtL+Uurt2X", /*55*/
723                 "whSLDP6A2bC2I1YTH9dyXMqNW1vAmUrb", /*56*/
724                 "P997XglfiNKP+EbPze+5HuBruzxEdXyQ", /*57*/
725                 "iNibvXJsgKYPtsDmzi1be2wOq+fCzSDi", /*58*/
726                 "e1dVjBU1AqXnDWPGCng8PczuUDbL607B", /*59*/
727                 "uWGWcCIEd67FcM+m/qI/swrxOuuRiyL0", /*5A*/
728                 "UqROJDDrgBXnR8HfLsFv+Zse9Rd9Dufg", /*5B*/
729                 "DtVPNLffhI96GTmFiin6L6Ui5VgbdkZr", /*5C*/
730                 "E3AEAPO2Y0Z5ThhYSTRfygjFB5ZMQfon", /*5D*/
731                 "w2jB7zN7AdyNpDF/bjxLa0JS0DwoNzxl", /*5E*/
732                 "ikTJqgm5vyWzPiFC9+BuC1IRMnDqtrVA", /*5F*/
733                 "40clT0iLyIRM1InHRn0x6I4xHvvYjTOj", /*60*/
734                 "PrcP2IzSRIHMQaQzVGNzt24qG6lHMZc8", /*61*/
735                 "Hf/C0IGrC/hZYwB+kAAFWrx0g5LpxTbm", /*62*/
736                 "Zm3JKWx84q5R4XwmeHN0QNnUTLDzwUBR", /*63*/
737                 "XndrFdA1TZo7X9qEek55Hi2VFWx31jS+", /*64*/
738                 "6/H7lURnyktsd/ByzbQRfDxOZ6WkLQKn", /*65*/
739                 "9phwbAOiNTWTTyJj8fblT8AK1k8x8IRi", /*66*/
740                 "fXXxtanhovB9JkZAyuZlI7eEHPD1d3Gi", /*67*/
741                 "X6Wo9yPS5Ciy2zNpfGVuwLeUTECOJ8nN", /*68*/
742                 "SduPuLAcPNuacUNmVxGKp0lWiXQm6jWb", /*69*/
743                 "pgBS4I+8jK81aTZ2cjZljJv5oxCqKS84", /*6A*/
744                 "ADmrKcREnChf5GMV3mUKqey/oDDO3J+r", /*6B*/
745                 "pgry4cppneykbiUDO7K/1weJg5p3Qq0s", /*6C*/
746                 "wzdr3RSJboFG2fVQkzssOc1iIz9B9/5b", /*6D*/
747                 "AYR1bZCLzNq7cQcpGKN57W9Shxp2Pi4v", /*6E*/
748                 "Fq2DM/pERw83exyKEyTMjlopMnevofaj", /*6F*/
749                 "Z1Oy8VvrPiOwUp0nymwEmgdl17CrY1mI", /*70*/
750                 "+eFz7HLXrm9yD3jsJg7FRlvbIWLmdcqJ", /*71*/
751                 "XZ/Y2ngm21kYwHml9QjakF55nr6I2eQR", /*72*/
752                 "H69zI63Zz8wVnl428R86dO18BRNiFtFt", /*73*/
753                 "q88q43ieZezycrQMfpAC3QI4zv9jGR+5", /*74*/
754                 "LRzMQ5mdI6RrMG53iJp09ZBk7Zzc8J0t", /*75*/
755                 "6TKKPX5V2/Px7tOnQWOcMnM8bTr4IdAJ", /*76*/
756                 "YnbedDrxsI8J0ZNnhmro7yZjOZp205bv", /*77*/
757                 "4h2SfNVVTMJb1EQ1otmGVjVW8l1U6cfv", /*78*/
758                 "HXhIbAaDjOoprXp1h1wRQD3ALqnCPm3z", /*79*/
759                 "AexIisbux2poEv/gxydRCh4HRALt0Lav", /*7A*/
760                 "M52ymcvNjV6o1C7afv3M2drki2bDWBgI", /*7B*/
761                 "B2Lc3cMpI7VyuR006DCrT00fgv+djLZH", /*7C*/
762                 "piGV1Q01hevGR/XMouBQ71qvSbWExLD7", /*7D*/
763                 "9OkXUhMjfLKvIivI0EaaYfr0D07V/rca", /*7E*/
764                 "pb8+kUAkVb6lJx64qQ34/mQIEFzujj+8", /*7F*/
765                 "E3ZiJ5HWU929oboZEeh50aD9G5I5xRo+", /*80*/
766                 "B8XKF+CPqWqF4AL7++7Q9vSZZ2dAnTUS", /*81*/
767                 "7ppNVUlSot4cULzEsrQR8NyEuVhaa5yS", /*82*/
768                 "yK0XMu5tmv0VHpLDwVnWq2k506tnZzCT", /*83*/
769                 "r4wyNaLXxPN+NLAH5Sf2PYzHc7LNCPKt", /*84*/
770                 "H3LXKwM4ePUklrsbBbG0Vc/zs/+z4fJM", /*85*/
771                 "aN1l0W0dwLFiHhAdYlYKOtIihzxa/0S3", /*86*/
772                 "GISbROvOxSnNA0SXq2CW5JlRFIJ7ts4g", /*87*/
773                 "c6QrfHmArufYLUMxqfWHh7UoQuAvLzkz", /*88*/
774                 "+hYnlhIdbwpY+LNGxxniYvEqHoYysmZY", /*89*/
775                 "UQKzVzca9WJoQTJZMG6D8AG8g8CusYt3", /*8A*/
776                 "nsihcUw6rOxkzrs8L4310QZuXGqVQcZh", /*8B*/
777                 "HKIFfNnqWxVc/91+mIy7eBFO6Kj5se7F", /*8C*/
778                 "s/+fQ0YTrfGxi4mcmNC0+mN47zDoRnaL", /*8D*/
779                 "fIG5B4mjqZY+hphG4VZDAhryrzgJfRH0", /*8E*/
780                 "cygLp0Uxikgxx6VD05+kEuUAAL0BkF6b", /*8F*/
781                 "D2PWF8wPrvPrT9A2qMS4ILmCdXF8jVNI", /*90*/
782                 "/kWwkZX23D9cDW01joC4LuNMTv12mskd", /*91*/
783                 "KufxREb0MEXWRVWyjUmAULLYxrj0uDLL", /*92*/
784                 "VywGqETdPj+M6e5IVLle4tu9Ehfh33BS", /*93*/
785                 "wgH5EpnZ5p1piXLF5V0sBuTFSTytSjRb", /*94*/
786                 "1KlBe73TFwDVRlqshCKvr6jO70U/xs4z", /*95*/
787                 "pKLqsySDkBUA/rXc1+nx0Lxi41GIt8v+", /*96*/
788                 "BebVL9rK/cbrnt/kF56jIslg7pSHTc7y", /*97*/
789                 "EHRiXsjqWN3UDf92+c8apZpdbkCIxPZB", /*98*/
790                 "+WAIkfviiIxKOz5v2fVjtULgDz9Rcrvz", /*99*/
791                 "mAhyxJmISxd+YifQ5VRex3APOv58aTq4", /*9A*/
792                 "+/2zl+LVgN7Tr02XM2hQg/B+qlGp6VEn", /*9B*/
793                 "rrBqSEdKxzmeBeWLH9IG04clbEYYW8Ow", /*9C*/
794                 "TErUU91OXE0rAkfvdZj0A4Rn6lim9Lgd", /*9D*/
795                 "Y2xt82TOPyh4dicfcgtN2tYH7E4Rle2L", /*9E*/
796                 "GdAlUT2c3zGoOY9VhTmCLtljDzYvuP5h", /*9F*/
797                 "uEF85PKtDqe0lFruGGepmlv4ekYdB6JG", /*A0*/
798                 "FBAS7iah9y6FL7FjMPBSqmlaz4zQxfQu", /*A1*/
799                 "dQLjVi3JPpymq8AD6m2BEJ7lq3VVAwap", /*A2*/
800                 "hJsxjFq1/81EoAKWjwWDQcbKUGy8K6F2", /*A3*/
801                 "RaElHLX1HgRgCkIHzp2nMFGYxJqEmFC6", /*A4*/
802                 "1NR2wB5z6NVnwfGuaU3OUsJDEkboSxJZ", /*A5*/
803                 "x7J50ZgU7gbQZe+Gj3ZHxFO/9IfFAtAA", /*A6*/
804                 "p7+3+5b+54N3Z4rAkjj0BYV/IbDDH8ks", /*A7*/
805                 "dSYD6NlAcKEQ0YupW210e1etqnHAxXDP", /*A8*/
806                 "tqUyB0eGqAiLhOpjYq4iiSR4NwDwQrbm", /*A9*/
807                 "WfEflCqobww3ttdVrhKl1TClpkdGfW2z", /*AA*/
808                 "gbRJyiaLePMV5cAW2feuLVunR2K1S0h4", /*AB*/
809                 "k04QZRcnYKoCze425Y4/hM6soSnVC8m9", /*AC*/
810                 "nSZiD8cKN2345xYay0g0RvtkuLgUqp7M", /*AD*/
811                 "ZN1aoIhPVNEOiY6A/gdDrRWjnduIkDwK", /*AE*/
812                 "Q5e02+LAHYLYLHrlx2/w6XAQPjbVqVop", /*AF*/
813                 "RLQmozdGH2IBaGGSu18f/az+b9yAHLFY", /*B0*/
814                 "x0kuIZXQUdF2ojZLZn3XKjesGs8geXv3", /*B1*/
815                 "gEKroiCpcTl88Aa5jLoT2cbRKQR8uAsH", /*B2*/
816                 "rfqrNFkkZo3JA12cE9eGs+N8c60T+fly", /*B3*/
817                 "t3iNLtBTBKNxQ8X0gguO0ZUZLSt4rDMD", /*B4*/
818                 "BP7m4V2nBJjeER/72bYg0pG8tHxhaPdu", /*B5*/
819                 "WqWHvuaX1wDRgWIPvDUiJE8FpPfbu1fq", /*B6*/
820                 "SQB9mNiYwAPVZsnAAnKL1qBqxw5ZZkrO", /*B7*/
821                 "0xQXcDpNK8yDWo7KTN/kGni37Vn5rMAz", /*B8*/
822                 "IgEL6ZMmAOhEOSsVQCX0IpREV8bijMJG", /*B9*/
823                 "rIKxcvb3Aalb1P1ceXmpOY1d58FBWjx7", /*BA*/
824                 "tHGcY/jPD74E8WxSKeP6VLuYIAN3V7Xn", /*BB*/
825                 "m3ar/kkHbClv8DumfGItDCV0YIRpQPmk", /*BC*/
826                 "pzjJ8kQe1CdZqlZ+bG7kbW387dsJFEAE", /*BD*/
827                 "AYj8MmDSFoX+GtZkMkVZlhLKuh5rPAlv", /*BE*/
828                 "rL3NTZll5k28qpQnnS//kxqhKn5Kh8/w", /*BF*/
829                 "a2oW3nHtyLpoGv4235bwwMVBt4VIlbuW", /*C0*/
830                 "0vLa8RQh0ouRn5Dm72B+dvL690xXGoC7", /*C1*/
831                 "W6C6Rnpt3SC1dGdL7d2dnUIB1v0KpVFT", /*C2*/
832                 "udJUEcijQ2I8GrrvU9aA2FZSzVmsY+9L", /*C3*/
833                 "yg9/u+49z4vo03zvpW6aQBEqW9B9iz/L", /*C4*/
834                 "hgLfXCsyqhUZRfeCNSV2GQDqrhATu8am", /*C5*/
835                 "ZM+MT6L5dcGIIIpFC1ZOMzFK2T6g/m/D", /*C6*/
836                 "KZB0KhbpgKcGNxgyjlIvk+TDUB0Y/Ing", /*C7*/
837                 "j3Imqm0IncJcjvhhjervLN3xiO4PupvI", /*C8*/
838                 "V83ipbfEnWJ5YHLHsUCk7nR2fVB/7T6g", /*C9*/
839                 "mDC3I8eW6XvavYtsNxqIfTd7RBJAnS4R", /*CA*/
840                 "kgodwgoBmtDzejXNP7YmBSbf4tE0gvRP", /*CB*/
841                 "zVkNleHbOQaDJzOcRsdJ+uvHPZXkNrGO", /*CC*/
842                 "/vSomYYWaomD5RveQqbjINXlZQ7M2qwP", /*CD*/
843                 "fd2KT/99esJhhkNlsmu+BIyVgN8ymjZn", /*CE*/
844                 "zpJOECCf4ZTzhqpvjeQlmk4gggQbLSyR", /*CF*/
845                 "JIisKL883YEKOwDUMjaoXwpeSF+KmoFf", /*D0*/
846                 "q+bQ5sh96Qm+bZRecwXZfYan7PW80Luw", /*D1*/
847                 "8XfTuDe2oo8KGDUrYkFGKDXQVcQhkPp9", /*D2*/
848                 "BynFasbkSSfQpNZq2nRxO+/jGf4K9PH5", /*D3*/
849                 "RQMQ2/7/1fVGRa9axWxaqTHicrFf5LiS", /*D4*/
850                 "Wyx9YQy7M+FvfM6V8btZ6Pd2JeFhitJ0", /*D5*/
851                 "TsqEwt7c88zb+ZzG06WX09ycgAI/h7x/", /*D6*/
852                 "3FhxF2rcMCvYa1Kvy4PnecU11shBmrho", /*D7*/
853                 "49sPNRynmpDzxpnBomYFl9o3v1hWB8pi", /*D8*/
854                 "cZFii9kLxoOd3udVif2HCpFaFmOFXL7E", /*D9*/
855                 "4gKLe8yotZizEr6XyHzB74ARDmLSuea7", /*DA*/
856                 "kGuTl9eoWTCZLCSZW3ESUqLkQDv/MLNH", /*DB*/
857                 "SC/o3qViWJxSgclGwcAm3uLcfKAM8mm8", /*DC*/
858                 "QTHqqko1QPiVoOF+rG2PSW0h6Oqgll62", /*DD*/
859                 "nF3XEjEVqmp23yCugXkl/nvnTkN5dZxU", /*DE*/
860                 "aMQvGwjhQAmeGt5giW/UQRLWDc9rOKB6", /*DF*/
861                 "9jNkpboAkXjpt81QbK4ROho2JIIUPIsf", /*E0*/
862                 "HDpt/TKmLekUWrMIzSH5bVB4iL6k0hru", /*E1*/
863                 "9FksdyEOV7kc4Eh0HrYypuQYAkprk9RI", /*E2*/
864                 "xLccANcRJWSpVxReUxzXGzC7jvgSn/eq", /*E3*/
865                 "nJkpO3uo8mGEjBynS9c/CzDCGpmcGNUc", /*E4*/
866                 "Bdvwl8vbZkFbCM35afU/CL3Olc0srKSg", /*E5*/
867                 "2f4ojDlnpwsDHsjXaZPsKHmzfvQkxgNO", /*E6*/
868                 "rSfviDYSlxc4zOhNa5Jo1LOS44uRQDlW", /*E7*/
869                 "DGt7rThtCOY+EMx0q8RPc4MzlhgJ/df1", /*E8*/
870                 "dQm0NhmSQX4j2wnRb59W3fLzXcysKnxj", /*E9*/
871                 "/+BUw+OrHXHq7gg4eWYgbOpAUNdBbPtA", /*EA*/
872                 "Rqua3WdO5kFbQhomfD/LgDmhMaX6TZN1", /*EB*/
873                 "CErkFIuijB9Clcb/aRpRs0wDqvgBLuUm", /*EC*/
874                 "iSBbXA8LfLMYvdDYLyyTQO8v7txTmYJS", /*ED*/
875                 "b1bqN9FNnAhi12CfhlR48g1rOqk9BgNl", /*EE*/
876                 "x+LLwCbFI07wcmtgBXpLiHv2bqYK2A3z", /*EF*/
877                 "4Hby85LGkTVbiLuyWC7C2ynKbXgGDeoV", /*F0*/
878                 "lqK3kJ3swSzmKpIg344LNcG2DVglZx6Q", /*F1*/
879                 "Id6ZwE5Z4R1RM9JI6B/O0XFm4nZKdF6A", /*F2*/
880                 "Ex4HiXqk6Oi5J+cs9rv6vlandD8tPuJa", /*F3*/
881                 "3OUI/YzkZouyJc1J59drNbrpKpNCTc/A", /*F4*/
882                 "PgdhrcAQbRTGhLkVpD/rB/GlvK+/g6EK", /*F5*/
883                 "pEch+HyJPd9KVTuqgtJq40vhta3KhEVV", /*F6*/
884                 "tGfshCY0S9jJpvAr7/iji4taLdbKZdkX", /*F7*/
885                 "DKu1A/Eqaiizn7U98YuP/UmLvmge0gJS", /*F8*/
886                 "fDBMIYDRZdShcIDEVXhnlLcYZ1yzT2Z9", /*F9*/
887                 "+N+tC8xOzEzMbzHhVVgKyvSMDR7Y4x4M", /*FA*/
888                 "hyFq89tkXpzi8FpMj0VFioHTBIJ0GONM", /*FB*/
889                 "pa92Tw1yY/+M/gkfAunXiNhMwG+X6ylV", /*FC*/
890                 "YkmEYyKd8IViUOIQT+gLnLVAlAMyur6P", /*FD*/
891                 "J6RHxOuI3LpyhcQ+POhMKX3K5EP+3K/V", /*FE*/
892                 "TyZ9zH5NddtcVyANgbrSDarYbosjUYau", /*FF*/
893                 "RFJqYyG1PCD/M/kG3EibuTnkZbdWIqiL"  /*00*/
894             );
895
896             public static readonly Row<byte> FIN = CreateRow<byte>
897             (
898                 "GRIjFgEfCQAMKgURBxMNAhQuCiYrHCAXLQQpGiEGIigPHiUQCy8bDhUsHScIAyQY"
899             );
900         }
901
902         //=======================================================================
903         // PUBLIC METHODS
904         //=======================================================================
905
906         public MHash384()
907         {
908             Reset(); /*initialize*/
909         }
910
911         [MethodImpl(MethodImplOptions.AggressiveInlining)]
912         public void Update(byte value)
913         {
914             if(finished)
915             {
916                 throw new InvalidOperationException("Hash computation finished. Must call reset() first!");
917             }
918             Iterate(hash, Tables.XOR[value], Tables.MIX[rnd++], Tables.ADD[value]);
919         }
920
921         public void Update(byte[] data)
922         {
923             if(object.ReferenceEquals(data, null))
924             {
925                 throw new ArgumentNullException("Input array must not be null!");
926             }
927             foreach(byte value in data)
928             {
929                 Update(value);
930             }
931         }
932
933         public void Update(byte[] data, int len)
934         {
935             if (object.ReferenceEquals(data, null))
936             {
937                 throw new ArgumentNullException("Input array must not be null!");
938             }
939             for (int i = 0; i < len; ++i)
940             {
941                 Update(data[i]);
942             }
943         }
944
945         public void Update(byte[] data, int offset, int len)
946         {
947             if (object.ReferenceEquals(data, null))
948             {
949                 throw new ArgumentNullException("Input array must not be null!");
950             }
951             int limit = checked(offset + len);
952             for(int i = offset; i < limit; ++i)
953             {
954                 Update(data[i]);
955             }
956         }
957
958         public byte[] GetDigest()
959         {
960             if(finished)
961             {
962                 throw new InvalidOperationException("Hash computation finished. Must call reset() first!");
963             }
964             byte[] digest = new byte[MHASH384_SIZE];
965             Row<ulong> row_xor = Tables.XOR[256];
966             Row<uint>  row_add = Tables.ADD[256];
967             for(int i = 0; i < MHASH384_SIZE; ++i)
968             {
969                 Iterate(hash, row_xor, Tables.MIX[rnd++], row_add);
970                 digest[i] = GetByte(hash, Tables.FIN[i]);
971             }
972             return digest;
973         }
974
975         public void Update(string str, Encoding enc = null)
976         {
977             if (object.ReferenceEquals(str, null))
978             {
979                 throw new ArgumentNullException("Input string must not be null!");
980             }
981             Update((enc ?? Encoding.UTF8).GetBytes(str));
982         }
983
984         public void Reset()
985         {
986             rnd = 0;
987             hash = Tables.INI.ToArray();
988             finished = false;
989         }
990
991         //-----------------------------------------------------------------------
992         // Convenience functions
993         //-----------------------------------------------------------------------
994
995         public static byte[] Compute(byte[] data)
996         {
997             MHash384 hash = new MHash384();
998             hash.Update(data);
999             return hash.GetDigest();
1000         }
1001
1002         public static byte[] Compute(byte[] data, int len)
1003         {
1004             MHash384 hash = new MHash384();
1005             hash.Update(data, len);
1006             return hash.GetDigest();
1007         }
1008
1009         public static byte[] Compute(byte[] data, int offset, int len)
1010         {
1011             MHash384 hash = new MHash384();
1012             hash.Update(data, offset, len);
1013             return hash.GetDigest();
1014         }
1015
1016         public static byte[] Compute(string str, Encoding enc = null)
1017         {
1018             MHash384 hash = new MHash384();
1019             hash.Update(str, enc);
1020             return hash.GetDigest();
1021         }
1022
1023         //=======================================================================
1024         // INTERNAL METHODS
1025         //=======================================================================
1026
1027         /* Magic onst*/
1028         private const ulong KMUL = 0x9DDFEA08EB382D69;
1029
1030         /* Hash state */
1031         private ulong[] hash;
1032         private byte rnd;
1033         private bool finished;
1034
1035         /* Temporary */
1036         private readonly ulong[] temp = new ulong[MHASH384_WORDS];
1037
1038         //-----------------------------------------------------------------------
1039         // Initialization
1040         //-----------------------------------------------------------------------
1041
1042         static MHash384()
1043         {
1044             if (!BitConverter.IsLittleEndian)
1045             {
1046                 throw new SystemException("BigEndian system is not currently supported!");
1047             }
1048         }
1049
1050         //-----------------------------------------------------------------------
1051         // Utility functions
1052         //-----------------------------------------------------------------------
1053
1054         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1055         private void Iterate(ulong[] hash, Row<ulong> xor, Row<byte> mix, Row<uint> add)
1056         {
1057             for(int i = 0; i < MHASH384_WORDS; ++i)
1058             {
1059                 temp[i] = Mix128to64(hash[i] + add[i], hash[mix[i]]) ^ xor[i];
1060             }
1061             Array.Copy(temp, 0, hash, 0, MHASH384_WORDS);
1062         }
1063
1064         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1065         private static byte GetByte(ulong[] hash, byte index)
1066         {
1067             return (byte) (hash[index / 8] >> ((index % 8) * 8));
1068         }
1069
1070         private static ulong Mix128to64(ulong u, ulong v)
1071         {
1072             v = (v ^ u) * KMUL;
1073             v ^= (v >> 47);
1074             v = (v ^ u) * KMUL;
1075             v ^= (v >> 47);
1076             return (v * KMUL);
1077         }
1078
1079         //-----------------------------------------------------------------------
1080         // Table initialization
1081         //-----------------------------------------------------------------------
1082
1083         private static Table<T> CreateTable<T>(params string[] lines)
1084         {
1085             Row<T>[] table = new Row<T>[lines.Length];
1086             int row = 0;
1087             foreach (string line in lines)
1088             {
1089                 table[row++] = CreateRow<T>(line);
1090             }
1091             return Table<T>.Wrap(table);
1092         }
1093
1094         private static Row<T> CreateRow<T>(string line)
1095         {
1096             byte[] data = Convert.FromBase64String(line);
1097             switch (Type.GetTypeCode(typeof(T)))
1098             {
1099                 case TypeCode.Byte:
1100                     return (Row<T>) (object) BuildRow(line, (byte[] src, int off) => src[off], 1);
1101                 case TypeCode.UInt32:
1102                     return (Row<T>) (object) BuildRow(line, (byte[] src, int off) => BitConverter.ToUInt32(src, off), 4);
1103                 case TypeCode.UInt64:
1104                     return (Row<T>) (object) BuildRow(line, (byte[] src, int off) => BitConverter.ToUInt64(src, off), 8);
1105                 default:
1106                     throw new InvalidOperationException("Unsupported type!");
1107             }
1108         }
1109
1110         private static Row<T> BuildRow<T>(string line, Func<byte[], int, T> convert, int pitch)
1111         {
1112             byte[] data = Convert.FromBase64String(line);
1113             if (data.Length % pitch != 0)
1114             {
1115                 throw new ArgumentException("Length of input array is not a multiple of the specified pitch!");
1116             }
1117             T[] row_data = new T[data.Length / pitch];
1118             for (int col = 0, offset = 0; offset < data.Length; ++col, offset += pitch)
1119             {
1120                 row_data[col] = convert(data, offset);
1121             }
1122             return Row<T>.Wrap(row_data);
1123         }
1124     }
1125 }