Support new features of Xamari.Forms (#186)
[platform/core/csapi/xsf.git] / src / XSF / Xamarin.Forms.Core / Crc64.cs
1 #if !NETSTANDARD1_0
2
3 using System;
4 using System.Runtime.InteropServices;
5 using System.Security.Cryptography;
6 using System.Text;
7
8 /// <summary>
9 /// https://github.com/xamarin/java.interop/blob/master/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs
10 /// </summary>
11 namespace Xamarin.Forms.Internals
12 {
13         /// <summary>
14         ///  CRC64 variant: crc-64-jones 64-bit
15         ///  * Poly: 0xad93d23594c935a9
16         ///  Changes beyond initial implementation:
17         ///  * Starting Value: ulong.MaxValue
18         ///  * XOR length in HashFinal()
19         /// </summary>
20         internal class Crc64 : HashAlgorithm
21         {
22                 static Crc64 _instance;
23                 public static Crc64 Instance
24                 {
25                         get
26                         {
27                                 if (_instance == null)
28                                         _instance = new Crc64();
29
30                                 return _instance;
31                         }
32                 }
33
34                 Crc64() { }
35
36                 static readonly ulong[] Table = {
37                         0x0000000000000000, 0x7ad870c830358979,
38                         0xf5b0e190606b12f2, 0x8f689158505e9b8b,
39                         0xc038e5739841b68f, 0xbae095bba8743ff6,
40                         0x358804e3f82aa47d, 0x4f50742bc81f2d04,
41                         0xab28ecb46814fe75, 0xd1f09c7c5821770c,
42                         0x5e980d24087fec87, 0x24407dec384a65fe,
43                         0x6b1009c7f05548fa, 0x11c8790fc060c183,
44                         0x9ea0e857903e5a08, 0xe478989fa00bd371,
45                         0x7d08ff3b88be6f81, 0x07d08ff3b88be6f8,
46                         0x88b81eabe8d57d73, 0xf2606e63d8e0f40a,
47                         0xbd301a4810ffd90e, 0xc7e86a8020ca5077,
48                         0x4880fbd87094cbfc, 0x32588b1040a14285,
49                         0xd620138fe0aa91f4, 0xacf86347d09f188d,
50                         0x2390f21f80c18306, 0x594882d7b0f40a7f,
51                         0x1618f6fc78eb277b, 0x6cc0863448deae02,
52                         0xe3a8176c18803589, 0x997067a428b5bcf0,
53                         0xfa11fe77117cdf02, 0x80c98ebf2149567b,
54                         0x0fa11fe77117cdf0, 0x75796f2f41224489,
55                         0x3a291b04893d698d, 0x40f16bccb908e0f4,
56                         0xcf99fa94e9567b7f, 0xb5418a5cd963f206,
57                         0x513912c379682177, 0x2be1620b495da80e,
58                         0xa489f35319033385, 0xde51839b2936bafc,
59                         0x9101f7b0e12997f8, 0xebd98778d11c1e81,
60                         0x64b116208142850a, 0x1e6966e8b1770c73,
61                         0x8719014c99c2b083, 0xfdc17184a9f739fa,
62                         0x72a9e0dcf9a9a271, 0x08719014c99c2b08,
63                         0x4721e43f0183060c, 0x3df994f731b68f75,
64                         0xb29105af61e814fe, 0xc849756751dd9d87,
65                         0x2c31edf8f1d64ef6, 0x56e99d30c1e3c78f,
66                         0xd9810c6891bd5c04, 0xa3597ca0a188d57d,
67                         0xec09088b6997f879, 0x96d1784359a27100,
68                         0x19b9e91b09fcea8b, 0x636199d339c963f2,
69                         0xdf7adabd7a6e2d6f, 0xa5a2aa754a5ba416,
70                         0x2aca3b2d1a053f9d, 0x50124be52a30b6e4,
71                         0x1f423fcee22f9be0, 0x659a4f06d21a1299,
72                         0xeaf2de5e82448912, 0x902aae96b271006b,
73                         0x74523609127ad31a, 0x0e8a46c1224f5a63,
74                         0x81e2d7997211c1e8, 0xfb3aa75142244891,
75                         0xb46ad37a8a3b6595, 0xceb2a3b2ba0eecec,
76                         0x41da32eaea507767, 0x3b024222da65fe1e,
77                         0xa2722586f2d042ee, 0xd8aa554ec2e5cb97,
78                         0x57c2c41692bb501c, 0x2d1ab4dea28ed965,
79                         0x624ac0f56a91f461, 0x1892b03d5aa47d18,
80                         0x97fa21650afae693, 0xed2251ad3acf6fea,
81                         0x095ac9329ac4bc9b, 0x7382b9faaaf135e2,
82                         0xfcea28a2faafae69, 0x8632586aca9a2710,
83                         0xc9622c4102850a14, 0xb3ba5c8932b0836d,
84                         0x3cd2cdd162ee18e6, 0x460abd1952db919f,
85                         0x256b24ca6b12f26d, 0x5fb354025b277b14,
86                         0xd0dbc55a0b79e09f, 0xaa03b5923b4c69e6,
87                         0xe553c1b9f35344e2, 0x9f8bb171c366cd9b,
88                         0x10e3202993385610, 0x6a3b50e1a30ddf69,
89                         0x8e43c87e03060c18, 0xf49bb8b633338561,
90                         0x7bf329ee636d1eea, 0x012b592653589793,
91                         0x4e7b2d0d9b47ba97, 0x34a35dc5ab7233ee,
92                         0xbbcbcc9dfb2ca865, 0xc113bc55cb19211c,
93                         0x5863dbf1e3ac9dec, 0x22bbab39d3991495,
94                         0xadd33a6183c78f1e, 0xd70b4aa9b3f20667,
95                         0x985b3e827bed2b63, 0xe2834e4a4bd8a21a,
96                         0x6debdf121b863991, 0x1733afda2bb3b0e8,
97                         0xf34b37458bb86399, 0x8993478dbb8deae0,
98                         0x06fbd6d5ebd3716b, 0x7c23a61ddbe6f812,
99                         0x3373d23613f9d516, 0x49aba2fe23cc5c6f,
100                         0xc6c333a67392c7e4, 0xbc1b436e43a74e9d,
101                         0x95ac9329ac4bc9b5, 0xef74e3e19c7e40cc,
102                         0x601c72b9cc20db47, 0x1ac40271fc15523e,
103                         0x5594765a340a7f3a, 0x2f4c0692043ff643,
104                         0xa02497ca54616dc8, 0xdafce7026454e4b1,
105                         0x3e847f9dc45f37c0, 0x445c0f55f46abeb9,
106                         0xcb349e0da4342532, 0xb1eceec59401ac4b,
107                         0xfebc9aee5c1e814f, 0x8464ea266c2b0836,
108                         0x0b0c7b7e3c7593bd, 0x71d40bb60c401ac4,
109                         0xe8a46c1224f5a634, 0x927c1cda14c02f4d,
110                         0x1d148d82449eb4c6, 0x67ccfd4a74ab3dbf,
111                         0x289c8961bcb410bb, 0x5244f9a98c8199c2,
112                         0xdd2c68f1dcdf0249, 0xa7f41839ecea8b30,
113                         0x438c80a64ce15841, 0x3954f06e7cd4d138,
114                         0xb63c61362c8a4ab3, 0xcce411fe1cbfc3ca,
115                         0x83b465d5d4a0eece, 0xf96c151de49567b7,
116                         0x76048445b4cbfc3c, 0x0cdcf48d84fe7545,
117                         0x6fbd6d5ebd3716b7, 0x15651d968d029fce,
118                         0x9a0d8ccedd5c0445, 0xe0d5fc06ed698d3c,
119                         0xaf85882d2576a038, 0xd55df8e515432941,
120                         0x5a3569bd451db2ca, 0x20ed197575283bb3,
121                         0xc49581ead523e8c2, 0xbe4df122e51661bb,
122                         0x3125607ab548fa30, 0x4bfd10b2857d7349,
123                         0x04ad64994d625e4d, 0x7e7514517d57d734,
124                         0xf11d85092d094cbf, 0x8bc5f5c11d3cc5c6,
125                         0x12b5926535897936, 0x686de2ad05bcf04f,
126                         0xe70573f555e26bc4, 0x9ddd033d65d7e2bd,
127                         0xd28d7716adc8cfb9, 0xa85507de9dfd46c0,
128                         0x273d9686cda3dd4b, 0x5de5e64efd965432,
129                         0xb99d7ed15d9d8743, 0xc3450e196da80e3a,
130                         0x4c2d9f413df695b1, 0x36f5ef890dc31cc8,
131                         0x79a59ba2c5dc31cc, 0x037deb6af5e9b8b5,
132                         0x8c157a32a5b7233e, 0xf6cd0afa9582aa47,
133                         0x4ad64994d625e4da, 0x300e395ce6106da3,
134                         0xbf66a804b64ef628, 0xc5bed8cc867b7f51,
135                         0x8aeeace74e645255, 0xf036dc2f7e51db2c,
136                         0x7f5e4d772e0f40a7, 0x05863dbf1e3ac9de,
137                         0xe1fea520be311aaf, 0x9b26d5e88e0493d6,
138                         0x144e44b0de5a085d, 0x6e963478ee6f8124,
139                         0x21c640532670ac20, 0x5b1e309b16452559,
140                         0xd476a1c3461bbed2, 0xaeaed10b762e37ab,
141                         0x37deb6af5e9b8b5b, 0x4d06c6676eae0222,
142                         0xc26e573f3ef099a9, 0xb8b627f70ec510d0,
143                         0xf7e653dcc6da3dd4, 0x8d3e2314f6efb4ad,
144                         0x0256b24ca6b12f26, 0x788ec2849684a65f,
145                         0x9cf65a1b368f752e, 0xe62e2ad306bafc57,
146                         0x6946bb8b56e467dc, 0x139ecb4366d1eea5,
147                         0x5ccebf68aecec3a1, 0x2616cfa09efb4ad8,
148                         0xa97e5ef8cea5d153, 0xd3a62e30fe90582a,
149                         0xb0c7b7e3c7593bd8, 0xca1fc72bf76cb2a1,
150                         0x45775673a732292a, 0x3faf26bb9707a053,
151                         0x70ff52905f188d57, 0x0a2722586f2d042e,
152                         0x854fb3003f739fa5, 0xff97c3c80f4616dc,
153                         0x1bef5b57af4dc5ad, 0x61372b9f9f784cd4,
154                         0xee5fbac7cf26d75f, 0x9487ca0fff135e26,
155                         0xdbd7be24370c7322, 0xa10fceec0739fa5b,
156                         0x2e675fb4576761d0, 0x54bf2f7c6752e8a9,
157                         0xcdcf48d84fe75459, 0xb71738107fd2dd20,
158                         0x387fa9482f8c46ab, 0x42a7d9801fb9cfd2,
159                         0x0df7adabd7a6e2d6, 0x772fdd63e7936baf,
160                         0xf8474c3bb7cdf024, 0x829f3cf387f8795d,
161                         0x66e7a46c27f3aa2c, 0x1c3fd4a417c62355,
162                         0x935745fc4798b8de, 0xe98f353477ad31a7,
163                         0xa6df411fbfb21ca3, 0xdc0731d78f8795da,
164                         0x536fa08fdfd90e51, 0x29b7d047efec8728,
165                 };
166
167                 ulong crc = ulong.MaxValue;
168                 ulong length = 0;
169
170                 public override void Initialize()
171                 {
172                         crc = ulong.MaxValue;
173                         length = 0;
174                 }
175
176                 protected override void HashCore(byte[] array, int ibStart, int cbSize)
177                 {
178                         for (int i = ibStart; i < cbSize; i++)
179                         {
180                                 crc = Table[(byte)(crc ^ array[i])] ^ (crc >> 8);
181                         }
182                         length += (ulong)cbSize;
183                 }
184
185                 protected override byte[] HashFinal() => BitConverter.GetBytes(crc ^ length);
186
187
188
189                 // https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa/24343727#24343727
190                 static readonly uint[] _lookup32 = CreateLookup32();
191
192                 static uint[] CreateLookup32()
193                 {
194                         var result = new uint[256];
195                         for (int i = 0; i < 256; i++)
196                         {
197                                 string s = i.ToString("X2");
198                                 result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
199                         }
200                         return result;
201                 }
202
203                 static string ByteArrayToHexViaLookup32(byte[] bytes)
204                 {
205                         var lookup32 = _lookup32;
206                         var result = new char[bytes.Length * 2];
207                         for (int i = 0; i < bytes.Length; i++)
208                         {
209                                 var val = lookup32[bytes[i]];
210                                 result[2 * i] = (char)val;
211                                 result[2 * i + 1] = (char)(val >> 16);
212                         }
213                         return new string(result);
214                 }
215
216                 public static string GetHash(string input)
217                 {
218                         byte[] bytes = Instance.ComputeHash(Encoding.UTF8.GetBytes(input));
219                         return ByteArrayToHexViaLookup32(bytes);
220                 }
221
222         }
223 }
224 #endif