public void AffineHash_Constructor_Rejects_Invalid_Arguments() { var cases = new[] { new { scale = 0L, shift = 0L, expected = typeof(ArgumentOutOfRangeException) }, new { scale = 1L, shift = -1L, expected = typeof(ArgumentOutOfRangeException) }, new { scale = 1L << 32, shift = 0L, expected = typeof(ArgumentOutOfRangeException) }, new { scale = 1L, shift = 1L << 32, expected = typeof(ArgumentOutOfRangeException) }, new { scale = 2L, shift = 0L, expected = typeof(ArgumentException) }, }; for (int i = 0; i < cases.Length; i++) { var c = cases[i]; try { AffineHash target = new AffineHash(c.scale, c.shift); Assert.Fail("index:{0}, target:{1}", i, target); } catch (Exception ex) { Assert.AreEqual(c.expected, ex.GetType(), "index: {0}", i); } } }
/// <summary> /// Gets the hash method delegate for the specified arguments and return type. /// </summary> /// <param name="target">The target hash instance.</param> /// <param name="args">The argument types of the hash method.</param> /// <returns>A delegate that will call the hash method on the target.</returns> private static Delegate HashDelegate(AffineHash target, params Type[] args) { Type[] delegateTypeArgs = new Type[args.Length + 1]; args.CopyTo(delegateTypeArgs, 0); delegateTypeArgs[args.Length] = typeof(int); Type delegateType = null; switch (args.Length) { case 1: delegateType = typeof(Func <,>); break; case 2: delegateType = typeof(Func <, ,>); break; case 3: delegateType = typeof(Func <, , ,>); break; } delegateType = delegateType.MakeGenericType(delegateTypeArgs); return(typeof(AffineHash).GetMethod(nameof(AffineHash.GetHashCode), args).CreateDelegate(delegateType, target)); }
public void AffineHash_Hash_Distributes_Byte_Array() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <byte[]> values = AffineHashTests.RandomByteArrays(random, 101, 10000); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_Byte() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <byte> values = Enumerable.Range(byte.MinValue, byte.MaxValue - byte.MinValue + 1) .Select(n => (byte)n); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_DateTimeOffset() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <DateTimeOffset> values = AffineHashTests.RandomByteArrays(random, sizeof(ulong), 10000) .Select(b => new DateTimeOffset((long)(BitConverter.ToUInt64(b, 0) % (ulong)DateTime.MaxValue.Ticks), TimeSpan.FromMinutes(random.Next(-840, 840)))); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_UInt64() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <ulong> values = AffineHashTests.RandomByteArrays(random, sizeof(ulong), 10000) .Select(b => BitConverter.ToUInt64(b, 0)); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_UInt16() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <ushort> values = Enumerable.Range(ushort.MinValue, ushort.MaxValue - ushort.MinValue + 1) .Select(n => (ushort)n); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_String() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <string> values = AffineHashTests.RandomCharArrays(random, 101, 10000) .Select(b => new string(b)); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_Single() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <float> values = AffineHashTests.RandomByteArrays(random, sizeof(float), 10000) .Select(b => BitConverter.ToSingle(b, 0)); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_Guid() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <Guid> values = AffineHashTests.RandomByteArrays(random, 16, 10000) .Select(b => new Guid(b)); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_Decimal() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <decimal> values = Enumerable.Range(0, 10000) .Select(n => new decimal(random.Next(), random.Next(), random.Next(), random.NextDouble() > 0.5D, (byte)random.Next(29))); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Distributes_Char() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); IEnumerable <char> values = Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue + 1) .Select(n => (char)n); AffineHashTests.AssertHashDistribution(target, values); }
public void AffineHash_Hash_Matches_Identical_String_Segments() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); string value = "TestTest"; int expected = target.GetHashCode(value, 0, 4); int actual = target.GetHashCode(value, 4, 4); Assert.AreEqual(expected, actual); }
public void AffineHash_Hash_Matches_Identical_Byte_Array_Segments() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); byte[] value = { 0, 1, 2, 3, 0, 1, 2, 3 }; int expected = target.GetHashCode(value, 0, 4); int actual = target.GetHashCode(value, 4, 4); Assert.AreEqual(expected, actual); }
public void AffineHash_Hash_Matches_Identical_Char_Array_Segments() { Random random = AffineHashTests.Random(); AffineHash target = new AffineHash(random); char[] value = { 'T', 'e', 's', 't', 'T', 'e', 's', 't' }; int expected = target.GetHashCode(value, 0, 4); int actual = target.GetHashCode(value, 4, 4); Assert.AreEqual(expected, actual); }
public void AffineHash_Hash_Measure_Avalanche() { Random random = new Random(); var cases = new[] { new { name = "zeroes", source = Enumerable.Repeat((byte)0x00, 100).ToArray() }, new { name = "ones", source = Enumerable.Repeat((byte)0xFF, 100).ToArray() }, new { name = "alternating-right", source = Enumerable.Repeat((byte)0x55, 100).ToArray() }, new { name = "alternating-left", source = Enumerable.Repeat((byte)0xAA, 100).ToArray() }, new { name = "random", source = Enumerable.Repeat(default(byte), 100).Select(b => (byte)random.Next()).ToArray() }, }; Avalanche avalanche = new Avalanche(); this.TestContext.WriteLine("power,predictability,scale,shift"); for (int trial = 0; trial < 10000; trial++) { AffineHash target = new AffineHash(random); avalanche.Reset(target); bool strong = true; bool weak = false; foreach (var c in cases) { avalanche.Next(c.source); double predictability = avalanche.Predictability(); if (predictability > 0.1) { strong = false; } if (predictability > 0.2) { weak = true; } } if (strong) { double predictability = avalanche.Finish(); this.TestContext.WriteLine("strong,{0},{1},{2}", predictability, target.Scale, target.Shift); } if (weak) { double predictability = avalanche.Finish(); this.TestContext.WriteLine("weak,{0},{1},{2}", predictability, target.Scale, target.Shift); } } }
public void AffineHash_Hash_Rejects_Invalid_Arguments() { var cases = new[] { new { arguments = new object[] { null }, types = new Type[] { typeof(byte[]) }, expected = typeof(ArgumentNullException) }, new { arguments = new object[] { null }, types = new Type[] { typeof(char[]) }, expected = typeof(ArgumentNullException) }, new { arguments = new object[] { null }, types = new Type[] { typeof(string) }, expected = typeof(ArgumentNullException) }, new { arguments = new object[] { null, 0, 0 }, types = new Type[] { typeof(byte[]), typeof(int), typeof(int) }, expected = typeof(ArgumentNullException) }, new { arguments = new object[] { null, 0, 0 }, types = new Type[] { typeof(char[]), typeof(int), typeof(int) }, expected = typeof(ArgumentNullException) }, new { arguments = new object[] { null, 0, 0 }, types = new Type[] { typeof(string), typeof(int), typeof(int) }, expected = typeof(ArgumentNullException) }, new { arguments = new object[] { new byte[10], -1, 5 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new byte[10], 10, 5 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new byte[10], 5, -1 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new byte[10], 5, 6 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new char[10], -1, 5 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new char[10], 10, 5 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new char[10], 5, -1 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { new char[10], 5, 6 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { "1234567890", -1, 5 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { "1234567890", 10, 5 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { "1234567890", 5, -1 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, new { arguments = new object[] { "1234567890", 5, 6 }, types = (Type[])null, expected = typeof(ArgumentOutOfRangeException) }, }; AffineHash target = new AffineHash(1L, 0L); for (int i = 0; i < cases.Length; i++) { var c = cases[i]; Type[] types = c.types ?? c.arguments.Select(a => a.GetType()).ToArray(); Delegate method = AffineHashTests.HashDelegate(target, types); try { object result = method.DynamicInvoke(c.arguments); Assert.Fail("index: {0}, return: {1}", i, result); } catch (TargetInvocationException ex) { Assert.AreEqual(c.expected, ex.InnerException.GetType(), "index: {0}", i); } catch (Exception ex) { Assert.Fail("index: {0}, exception: {1}", i, ex); } } }
/// <summary> /// Asserts that the distribution of hash values is uniform for a given set of data. /// </summary> /// <typeparam name="T">The type of data to hash.</typeparam> /// <param name="target">The target hash algorithm.</param> /// <param name="values">The values to hash.</param> private static void AssertHashDistribution <T>(AffineHash target, IEnumerable <T> values) { Distribution distribution = new Distribution(); Dictionary <int, T> hashes = new Dictionary <int, T>(); Func <T, int> method = (Func <T, int>)AffineHashTests.HashDelegate(target, typeof(T)); foreach (T value in values) { int hash = method(value); distribution.Observe(hash); if (hashes.ContainsKey(hash)) { Assert.Fail("scale:{0}, shift:{1}, hash:{2}, original:{3}, collision:{4}", target.Scale, target.Shift, hash, hashes[hash], value); } else { hashes.Add(hash, value); } } double ks = distribution.Finish(); Assert.IsTrue(ks < 0.1D, "scale:{0}, shift:{1}, ks:{2}", target.Scale, target.Shift, ks); }
/// <summary> /// Resets the hash algorithm. /// </summary> /// <param name="candidate">The new candidate algorithm.</param> public void Reset(AffineHash candidate) { this.hash = candidate; this.grandLimit = 0; this.grandTotal = 0; }