diff --git a/Tests/TestApp/Program.cs b/Tests/TestApp/Program.cs
index 89f88dc..0599e9e 100644
--- a/Tests/TestApp/Program.cs
+++ b/Tests/TestApp/Program.cs
@@ -1,10 +1,8 @@
using System;
using System.Collections.Concurrent;
-using System.Linq;
-using System.Reflection;
using ZeroLevel.Logging;
-using ZeroLevel.Services.Invokation;
-using ZeroLevel.Services.Serialization;
+using ZeroLevel.Services.HashFunctions;
+using ZeroLevel.Services.Mathemathics;
namespace TestApp
{
@@ -54,10 +52,34 @@ namespace TestApp
internal static class Program
{
-
-
private static void Main(string[] args)
{
+ var date = DateTime.Now;
+
+ var bytes = new byte[1531];
+ new Random().NextBytes(bytes);
+ var hash = Murmur3.ComputeULongHash(bytes);
+ Console.WriteLine($"{hash}");
+
+ new Random().NextBytes(bytes);
+ hash = Murmur3.ComputeULongHash(bytes);
+ Console.WriteLine($"{hash}");
+
+ bytes[0] = 10;
+ hash = Murmur3.ComputeULongHash(bytes);
+ Console.WriteLine($"{hash}");
+
+ new Random().NextBytes(bytes);
+ hash = Murmur3.ComputeULongHash(bytes);
+ Console.WriteLine($"{hash}");
+ Console.ReadKey();
+
+ /*
+ foreach (var c in Combinations.GenerateUniqueSets(new int[] { 1, 2, 3, 4, 5, 6 }, 3))
+ {
+ Console.WriteLine(string.Join('\t', c));
+ }
+ */
}
}
}
\ No newline at end of file
diff --git a/Tests/TestApp/t.cs b/Tests/TestApp/t.cs
new file mode 100644
index 0000000..c7da7f3
--- /dev/null
+++ b/Tests/TestApp/t.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Linq;
+
+namespace TestApp
+{
+ internal class t
+ {
+ public int Calculate()
+ {
+ var c = int.Parse(Console.ReadLine());
+ var data = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
+ int result = 0;
+ for (int i = 0; i < c - 1; i++)
+ {
+ for (int j = i + 1; j < c; j++)
+ {
+ var d1 = Math.Min(data[i], data[j]);
+ var d2 = Math.Max(data[i], data[j]);
+ if (d2 > 100000) continue;
+ if ((d1 != 0 && d2 != 0) && ((float)d1 / d2) >= .9f)
+ result++;
+ }
+ }
+ return result;
+ }
+ }
+}
diff --git a/Tests/ZeroLevel.UnitTests/BytesEncodingTest.cs b/Tests/ZeroLevel.UnitTests/BytesEncodingTest.cs
new file mode 100644
index 0000000..2f0f1cf
--- /dev/null
+++ b/Tests/ZeroLevel.UnitTests/BytesEncodingTest.cs
@@ -0,0 +1,110 @@
+using System;
+using Xunit;
+
+namespace ZeroLevel.UnitTests
+{
+ public class BytesEncodingTests
+ {
+ public static void DeHashData(byte[] data, byte initialMask)
+ {
+ int i;
+ for (i = data.Length - 1; i > 9; i -= 8)
+ {
+ data[i - 0] ^= data[i - 1];
+ data[i - 1] ^= data[i - 2];
+ data[i - 2] ^= data[i - 3];
+ data[i - 3] ^= data[i - 4];
+ data[i - 4] ^= data[i - 5];
+ data[i - 5] ^= data[i - 6];
+ data[i - 6] ^= data[i - 7];
+ data[i - 7] ^= data[i - 8];
+ }
+ for (; i >= 1; i--)
+ {
+ data[i] ^= data[i - 1];
+ }
+ data[0] ^= initialMask;
+ }
+
+ public static void HashData(byte[] data, byte initialmask)
+ {
+ if (data == null || data.Length == 0) return;
+ int i = 1;
+ data[0] ^= initialmask;
+ for (; i < (data.Length - 8); i += 8)
+ {
+ data[i + 0] ^= data[i - 1];
+ data[i + 1] ^= data[i + 0];
+ data[i + 2] ^= data[i + 1];
+ data[i + 3] ^= data[i + 2];
+ data[i + 4] ^= data[i + 3];
+ data[i + 5] ^= data[i + 4];
+ data[i + 6] ^= data[i + 5];
+ data[i + 7] ^= data[i + 6];
+ }
+ for (; i < data.Length; i++)
+ {
+ data[i] ^= data[i - 1];
+ }
+ }
+
+ [Fact]
+ public void SpecialTest()
+ {
+ var arr = new byte[] { 244, 135 }; //, 125, 160, 109, 144, 187, 109, 88, 78, 175, 115, 83, 174, 165, 246, 253, 112 };
+ var copy = new byte[arr.Length];
+ Array.Copy(arr, copy, arr.Length);
+
+ byte initial = (byte)(arr.Length % 255);
+ HashData(arr, initial);
+ Assert.False(ArrayExtensions.UnsafeEquals(arr, copy));
+
+ DeHashData(arr, initial);
+ Assert.True(ArrayExtensions.UnsafeEquals(arr, copy));
+ }
+
+ [Fact]
+ public void BytesEncodingTest()
+ {
+ // Arrange
+ var r = new Random((int)Environment.TickCount);
+
+ for (int i = 1; i < 20; i ++)
+ {
+ // Act
+ var arr = new byte[i];
+ var copy = new byte[i];
+ r.NextBytes(arr);
+ Array.Copy(arr, copy, arr.Length);
+
+ // Assert
+
+ var initial = arr[0];
+ HashData(arr, initial);
+ Assert.False(ArrayExtensions.UnsafeEquals(arr, copy));
+
+ DeHashData(arr, initial);
+ Assert.True(ArrayExtensions.UnsafeEquals(arr, copy));
+ }
+
+ for (int i = 1; i < 200000; i += 17)
+ {
+ // Act
+ var arr = new byte[i];
+ var copy = new byte[i];
+ r.NextBytes(arr);
+ Array.Copy(arr, copy, arr.Length);
+
+ // Assert
+
+ var initial = arr[0];
+ HashData(arr, initial);
+ Assert.False(ArrayExtensions.UnsafeEquals(arr, copy));
+
+ DeHashData(arr, initial);
+ Assert.True(ArrayExtensions.UnsafeEquals(arr, copy));
+ }
+ }
+
+ }
+}
diff --git a/ZeroLevel/Services/Encryption/FastObfuscator.cs b/ZeroLevel/Services/Encryption/FastObfuscator.cs
index 4f72368..389f87d 100644
--- a/ZeroLevel/Services/Encryption/FastObfuscator.cs
+++ b/ZeroLevel/Services/Encryption/FastObfuscator.cs
@@ -40,8 +40,19 @@ namespace ZeroLevel.Services.Encryption
public void DeHashData(byte[] data)
{
- if (data.Length == 0) return;
- for (var i = data.Length - 1; i > 0; i--)
+ int i;
+ for (i = data.Length - 1; i > 9; i -= 8)
+ {
+ data[i - 0] ^= data[i - 1];
+ data[i - 1] ^= data[i - 2];
+ data[i - 2] ^= data[i - 3];
+ data[i - 3] ^= data[i - 4];
+ data[i - 4] ^= data[i - 5];
+ data[i - 5] ^= data[i - 6];
+ data[i - 6] ^= data[i - 7];
+ data[i - 7] ^= data[i - 8];
+ }
+ for (; i >= 1; i--)
{
data[i] ^= data[i - 1];
}
diff --git a/ZeroLevel/Services/HashFunctions/Murmur3.cs b/ZeroLevel/Services/HashFunctions/Murmur3.cs
index 45dc758..68d25da 100644
--- a/ZeroLevel/Services/HashFunctions/Murmur3.cs
+++ b/ZeroLevel/Services/HashFunctions/Murmur3.cs
@@ -1,5 +1,6 @@
using System;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace ZeroLevel.Services.HashFunctions
{
@@ -149,9 +150,150 @@ namespace ZeroLevel.Services.HashFunctions
return hash;
}
+ public static ulong ComputeULongHash(byte[] bb, ulong seed = 0)
+ {
+ var h1 = seed;
+ ulong h2 = 0;
+ var length = 0UL;
+ int pos = 0;
+ ulong remaining = (ulong)bb.Length;
+ // read 128 bits, 16 bytes, 2 longs in eacy cycle
+ while (remaining >= READ_SIZE)
+ {
+ ulong k1 = bb.GetUInt64(pos);
+ pos += 8;
+ ulong k2 = bb.GetUInt64(pos);
+ pos += 8;
+ length += READ_SIZE;
+ remaining -= READ_SIZE;
+
+ h1 ^= MixKey1(k1);
+ h1 = h1.RotateLeft(27);
+ h1 += h2;
+ h1 = h1 * 5 + 0x52dce729;
+ h2 ^= MixKey2(k2);
+ h2 = h2.RotateLeft(31);
+ h2 += h1;
+ h2 = h2 * 5 + 0x38495ab5;
+ }
+
+ // if the input MOD 16 != 0
+ if (remaining > 0)
+ {
+ ulong k1 = 0;
+ ulong k2 = 0;
+ length += remaining;
+ // little endian (x86) processing
+ switch (remaining)
+ {
+ case 15:
+ k2 ^= (ulong)bb[pos + 14] << 48; // fall through
+ goto case 14;
+ case 14:
+ k2 ^= (ulong)bb[pos + 13] << 40; // fall through
+ goto case 13;
+ case 13:
+ k2 ^= (ulong)bb[pos + 12] << 32; // fall through
+ goto case 12;
+ case 12:
+ k2 ^= (ulong)bb[pos + 11] << 24; // fall through
+ goto case 11;
+ case 11:
+ k2 ^= (ulong)bb[pos + 10] << 16; // fall through
+ goto case 10;
+ case 10:
+ k2 ^= (ulong)bb[pos + 9] << 8; // fall through
+ goto case 9;
+ case 9:
+ k2 ^= (ulong)bb[pos + 8]; // fall through
+ goto case 8;
+ case 8:
+ k1 ^= bb.GetUInt64(pos);
+ break;
+ case 7:
+ k1 ^= (ulong)bb[pos + 6] << 48; // fall through
+ goto case 6;
+ case 6:
+ k1 ^= (ulong)bb[pos + 5] << 40; // fall through
+ goto case 5;
+ case 5:
+ k1 ^= (ulong)bb[pos + 4] << 32; // fall through
+ goto case 4;
+ case 4:
+ k1 ^= (ulong)bb[pos + 3] << 24; // fall through
+ goto case 3;
+ case 3:
+ k1 ^= (ulong)bb[pos + 2] << 16; // fall through
+ goto case 2;
+ case 2:
+ k1 ^= (ulong)bb[pos + 1] << 8; // fall through
+ goto case 1;
+ case 1:
+ k1 ^= (ulong)bb[pos]; // fall through
+ break;
+ default:
+ throw new Exception("Something went wrong with remaining bytes calculation.");
+ }
+ h1 ^= MixKey1(k1);
+ h2 ^= MixKey2(k2);
+ }
+
+
+ h1 ^= length;
+ h2 ^= length;
+
+ h1 += h2;
+ h2 += h1;
+
+ h1 = Murmur3.MixFinal(h1);
+ h2 = Murmur3.MixFinal(h2);
+
+ h1 += h2;
+ h2 += h1;
+
+ return h2;
+ }
+
+ ///
+ /// Hashes the into a MurmurHash3 as a .
+ ///
+ /// The span.
+ /// The seed for this algorithm.
+ /// The MurmurHash3 as a
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint ComputeUIntHash(ref ReadOnlySpan bytes, uint seed)
+ {
+ ref byte bp = ref MemoryMarshal.GetReference(bytes);
+ ref uint endPoint = ref Unsafe.Add(ref Unsafe.As(ref bp), bytes.Length >> 2);
+ if (bytes.Length >= 4)
+ {
+ do
+ {
+ seed = RotateLeft(seed ^ RotateLeft(Unsafe.ReadUnaligned(ref bp) * 3432918353U, 15) * 461845907U, 13) * 5 - 430675100;
+ bp = ref Unsafe.Add(ref bp, 4);
+ } while (Unsafe.IsAddressLessThan(ref Unsafe.As(ref bp), ref endPoint));
+ }
+ var remainder = bytes.Length & 3;
+ if (remainder > 0)
+ {
+ uint num = 0;
+ if (remainder > 2) num ^= Unsafe.Add(ref endPoint, 2) << 16;
+ if (remainder > 1) num ^= Unsafe.Add(ref endPoint, 1) << 8;
+ num ^= endPoint;
+
+ seed ^= RotateLeft(num * 3432918353U, 15) * 461845907U;
+ }
+ seed ^= (uint)bytes.Length;
+ seed = (uint)((seed ^ (seed >> 16)) * -2048144789);
+ seed = (uint)((seed ^ (seed >> 13)) * -1028477387);
+ return seed ^ seed >> 16;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong RotateLeft(this ulong original, int bits) => (original << bits) | (original >> (64 - bits));
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ulong RotateLeft(this ulong original, int bits) =>
- (original << bits) | (original >> (64 - bits));
+ public static uint RotateLeft(this uint original, int bits) => (original << bits) | (original >> (32 - bits));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong RotateRight(this ulong original, int bits) =>
diff --git a/ZeroLevel/Services/Mathemathics/Combinations.cs b/ZeroLevel/Services/Mathemathics/Combinations.cs
new file mode 100644
index 0000000..e1fddb5
--- /dev/null
+++ b/ZeroLevel/Services/Mathemathics/Combinations.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+
+namespace ZeroLevel.Services.Mathemathics
+{
+ public static class Combinations
+ {
+ private static IEnumerable GenerateIndiciesForUniqueSets(int m, int n)
+ {
+ int[] result = new int[m];
+ Stack stack = new Stack(m);
+ stack.Push(0);
+ while (stack.Count > 0)
+ {
+ int index = stack.Count - 1;
+ int value = stack.Pop();
+ while (value < n)
+ {
+ result[index++] = value++;
+ stack.Push(value);
+ if (index != m) continue;
+ yield return result;
+ break;
+ }
+ }
+ }
+
+ public static IEnumerable GenerateUniqueSets(T[] original, int k)
+ {
+ T[] result = new T[k];
+ foreach (var indices in GenerateIndiciesForUniqueSets(k, original.Length))
+ {
+ for (int i = 0; i < k; i++)
+ {
+ result[i] = original[indices[i]];
+ }
+ yield return result;
+ }
+ }
+ }
+}
diff --git a/ZeroLevel/ZeroLevel.csproj b/ZeroLevel/ZeroLevel.csproj
index ec512c8..6d53858 100644
--- a/ZeroLevel/ZeroLevel.csproj
+++ b/ZeroLevel/ZeroLevel.csproj
@@ -8,7 +8,7 @@
True
ZeroLevel
$(AssemblyVersion)
- 4.0.0.0
+ 4.0.0.1
$(AssemblyVersion)
latest
Ogoun
@@ -32,6 +32,10 @@
+
+
+
+
True