public void HashableStringSerializeDeserialize() { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var h1 = new HashableString(Guid.NewGuid().ToString()); h1.ComputeHash(provider); var h1s = Newtonsoft.Json.JsonConvert.SerializeObject(h1); var h1d = Newtonsoft.Json.JsonConvert.DeserializeObject <HashableString>(h1s); //verify before recomputing Assert.IsTrue(h1.Verify()); Assert.IsTrue(h1d.Verify()); //check that the hash (and other fields) have not changed Assert.AreEqual(h1.ComputedHash, h1d.ComputedHash); Assert.AreEqual(h1.ComputedHash.ComputedDate, h1d.ComputedHash.ComputedDate); Assert.AreEqual(h1.ComputedHash.Bytes, h1d.ComputedHash.Bytes); Assert.AreEqual(h1.ComputedHash.HashByteLength(), h1d.ComputedHash.HashByteLength()); Assert.AreEqual(h1.ComputedHash.Provider, h1d.ComputedHash.Provider); Assert.AreEqual(h1.ComputedHash.SourceByteLength, h1d.ComputedHash.SourceByteLength); Assert.AreEqual(h1.Value, h1d.Value); //verify after recomputing h1.ComputeHash(provider); h1d.ComputeHash(provider); Assert.IsTrue(h1.Verify()); Assert.IsTrue(h1d.Verify()); //check that the hash has not changed Assert.AreEqual(h1.ComputedHash, h1d.ComputedHash); Assert.AreEqual(h1.Value, h1d.Value); } }
public void AddRange() { var c = new ConsistentHash <HashableString>(HashProvider.SHA384); int rounds = 1000; var items = new List <HashableString>(); for (int i = 0; i < rounds; i++) { var item = new HashableString(Guid.NewGuid().ToString()); item.ComputeHash(c.Provider, null); items.Add(item); } c.AddRange(items, true, 0); foreach (var item in items) { Assert.True(c.ContainsNode(item.ComputedHash)); } Assert.True(c.NodeCount == items.Count); foreach (var item in items) { c.Remove(item); Assert.False(c.ContainsNode(item.ComputedHash)); } Assert.True(c.NodeCount == 0); }
public void HashableStringHashes() { var precomputedHashes = new Dictionary <HashProvider, string>() { { HashProvider.SHA256, @"QSz5LmQc4pbDAgZV0T7cfRW6vYHojRcdYIe/E/peFTY=" }, { HashProvider.SHA384, @"mOMV/0r+ZC+qHvgrYnM7d5kGdsLjH5bNW75gEGwldFy5JEdJ2dctt9+aKBkX0lLV" }, { HashProvider.SHA512, @"xl48gTfq6r+CxVxneqx9k3NGw0px6ubRdSnJUj/oR5MyabKlFC4FZwM2xBq0NkvM6lTOeQCGhZV0ET0EN11JZw==" } }; foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var h = new HashableString("edb0f9cb-37a5-4c37-b8f7-7242e54bff34"); var h2 = new HashableString("edb0f9cb-37a5-4c37-b8f7-7242e54bff3A"); h.ComputeHash(provider); h2.ComputeHash(provider); Assert.True(precomputedHashes.ContainsKey(provider), "The stored test hash dictionary has a comparison Hash"); var precomputedTestHash = precomputedHashes[provider]; var computedHashString = h.ComputedHash.ToString(); Assert.AreEqual(computedHashString, precomputedTestHash, "Computed and stored hash differ, the hash of 'Test' should never change"); Assert.AreNotEqual(h.ComputedHash, h2.ComputedHash, "Slightly different strings hash differently"); Assert.AreNotEqual(h.Value, h2.Value, "Slightly different strings hash differently"); } }
public void WeightedAddRemove() { int rounds = 1000; var c = new ConsistentHash <HashableString>(HashProvider.SHA384); var firstItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(c.Provider, null); c.Add(firstItem, true, rounds); Assert.True(c.ContainsNode(firstItem.ComputedHash)); var rehashed = firstItem.ComputedHash.Rehash(); for (int i = 1; i < rounds; i++) { rehashed = firstItem.ComputedHash.Rehash(); Assert.True(c.ContainsNode(rehashed)); } c.Remove(firstItem.ComputedHash, true); Assert.False(c.ContainsNode(firstItem.ComputedHash)); Assert.True(c.NodeCount == 0); rehashed = firstItem.ComputedHash.Rehash(); for (int i = 1; i < rounds; i++) { rehashed = firstItem.ComputedHash.Rehash(); Assert.False(c.ContainsNode(rehashed)); } }
public void AddBulkPerformance() { var results = ""; foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { long itemCount = 0; DateTime startTime = DateTime.Now; var c = new ConsistentHash <HashableString>(provider); while ((startTime + TestLength) > DateTime.Now) { var item = new HashableString(Guid.NewGuid().ToString()); item.ComputeHash(provider); c.Add(item, false, 0); itemCount++; } c.UpdateKeyArray(); results += GetResultString(provider, itemCount); } Assert.Pass(results); }
public void SimpleMemStoreExample() { var memStore = new MemoryStore(HashProvider.SHA256, new TimeSpan(1, 0, 0), new TimeSpan(0, 0, 30), int.MaxValue, int.MaxValue, int.MaxValue, null); var itemToStore = new HashableString("Test Value", HashProvider.SHA256); memStore.StoreItem(itemToStore); Assert.IsTrue(itemToStore.Verify()); Assert.NotNull(memStore.GetItem <HashableString>(itemToStore.ComputedHash)); }
public void SimpleFactoryExample() { var memStore = Factory.Create(typeof(MemoryStore), HashProvider.SHA256); var itemToStore = new HashableString("Test Value", HashProvider.SHA256); memStore.StoreItem(itemToStore); Assert.IsTrue(itemToStore.Verify()); Assert.NotNull(memStore.GetItem <HashableString>(itemToStore.ComputedHash)); }
static void Main(string[] args) { // Make some values to hash string stringToHash = "Easy!"; byte[] bytesToHash = new byte[] { 0x45, 0x61, 0x73, 0x79, 0x21 }; Stream streamToHash = new MemoryStream(new byte[] { 0x45, 0x61, 0x73, 0x79, 0x21 }); File.WriteAllText("CryptLinkDemo.txt", "Easy!"); Stream fileToHash = new FileStream("CryptLinkDemo.txt", FileMode.Open); // Using Extentions stringToHash.ComputeHash(HashProvider.SHA256); bytesToHash.ComputeHash(HashProvider.SHA256); streamToHash.ComputeHash(HashProvider.SHA256); fileToHash.ComputeHash(HashProvider.SHA256); // Using Hash static methods Hash.Compute(stringToHash, HashProvider.SHA256); Hash.Compute(bytesToHash, HashProvider.SHA256); Hash.Compute(streamToHash, HashProvider.SHA256); Hash.Compute(fileToHash, HashProvider.SHA256); // Instanced examples, the value and hash are combined into a meta object // HashableString, holds the original string and the hash var hashableString = new HashableString("Easy!", HashProvider.SHA256); // HashableBytes, holds the original set of bytes and the hash - best for small arrays of bytes var hashableBytes = new HashableBytes(new byte[] { 0x45, 0x61, 0x73, 0x79, 0x21 }, HashProvider.SHA256); // HashableFile, holds a refernce to a local file path and the hash var hashableFile = new HashableFile("CryptLinkDemo.txt", HashProvider.SHA256); var widget = new HashableWidgetExample() { ID = 0, Name = "Widget", Price = 100, PurchaseCount = 1000000 }; widget.ComputeHash(HashProvider.SHA256); Console.WriteLine(widget.ComputedHash); using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySerialNumber, "123456", true); var cert = new Cert(certs[0]); widget.ComputeHash(HashProvider.SHA256, cert); widget.Verify(cert); } }
public void SigningTests() { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var signed1 = new HashableString(Guid.NewGuid().ToString()); signed1.ComputeHash(provider, signingCert1); var signed2 = new HashableString(signed1.Value); signed2.ComputeHash(provider, signingCert2); Assert.AreNotEqual(signingCert1.ComputedHash, signingCert2.ComputedHash, "Cert hashes do not match"); Assert.AreEqual(signed1.ComputedHash, signed2.ComputedHash, "Signed hashes match"); Assert.AreNotEqual(signed1.ComputedHash.SignatureCertHash, signed2.ComputedHash.SignatureCertHash, "Signed hashes match"); Assert.AreNotEqual(signed1.ComputedHash.SignatureBytes, signed2.ComputedHash.SignatureBytes, "Signed hashes match"); //The signed hashes verify as the should Assert.IsTrue(signed1.Verify(signingCert1)); Assert.IsTrue(signed2.Verify(signingCert2)); Assert.IsTrue(signed1.Verify(verifyCert1)); Assert.IsTrue(signed2.Verify(verifyCert2)); //but don't with the wrong certs Assert.IsFalse(signed2.Verify(signingCert1)); Assert.IsFalse(signed1.Verify(signingCert2)); Assert.IsFalse(signed2.Verify(verifyCert1)); Assert.IsFalse(signed1.Verify(verifyCert2)); //Change both hashes slightly if (signed1.ComputedHash.SignatureBytes[0] < Byte.MaxValue) { signed1.ComputedHash.SignatureBytes[0]++; } else { signed1.ComputedHash.SignatureBytes[0]--; } if (signed2.ComputedHash.SignatureBytes[0] < Byte.MaxValue) { signed2.ComputedHash.SignatureBytes[0]++; } else { signed2.ComputedHash.SignatureBytes[0]--; } //Neither should verify now Assert.IsFalse(signed1.Verify(signingCert1)); Assert.IsFalse(signed2.Verify(signingCert2)); Assert.IsFalse(signed1.Verify(verifyCert1)); Assert.IsFalse(signed2.Verify(verifyCert2)); } }
public void HashVerifyTests() { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var signed = new HashableString(Guid.NewGuid().ToString()); signed.ComputeHash(provider, signingCert1); Assert.IsTrue(signed.Verify(signingCert1)); var unsigned = new HashableString(Guid.NewGuid().ToString()); unsigned.ComputeHash(provider); } }
public void B64EncodeDecodeHash() { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var hashed = new HashableString(Guid.NewGuid().ToString()); hashed.ComputeHash(provider, null); var hash = hashed.ComputedHashBytes(); Assert.AreEqual(hash, DecodeBytes(EncodeBytes(hash, false, true), true)); Assert.AreEqual(hash, DecodeBytes(EncodeBytes(hash, true, false), false)); Assert.AreEqual(hash, DecodeBytes(EncodeBytes(hash, true, true), true)); Assert.AreEqual(hash, DecodeBytes(EncodeBytes(hash, false, false), false)); } }
public void UnweightedAddRemove() { var c = new ConsistentHash <HashableString>(HashProvider.SHA384); var firstItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(c.Provider, null); c.Add(firstItem, true, 0); Assert.True(c.ContainsNode(firstItem.ComputedHash)); Assert.True(c.NodeCount == 1); c.Remove(firstItem); Assert.False(c.ContainsNode(firstItem.ComputedHash)); Assert.True(c.NodeCount == 0); }
public void UpdateKeyArray() { var c = new ConsistentHash <HashableString>(HashProvider.SHA384); var firstItem = new HashableString(Guid.NewGuid().ToString()); var secondItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(c.Provider, null); secondItem.ComputeHash(c.Provider, null); c.Add(firstItem, true, 0); c.Add(secondItem, false, 0); Assert.False(c.ContainsNode(secondItem.ComputedHash)); c.UpdateKeyArray(); Assert.True(c.ContainsNode(firstItem.ComputedHash)); }
public void StreamTest() { foreach (var hStoreType in (Factory.GetImplementors())) { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var store = GetTestStore(hStoreType, provider, true, int.MaxValue); if (hStoreType == typeof(NullStore)) { continue; } //add a single item var firstItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(provider, null); store.StoreItem(firstItem); //check that we can get it if (hStoreType != typeof(NullStore)) { Assert.True(store.GetItem <HashableString>(firstItem.ComputedHash).ComputedHash == firstItem.ComputedHash); } //Test streaming var ms = store.GetItemStream(firstItem.ComputedHash); //read the stream ms.Position = 0; string readString; using (var sr = new StreamReader(ms)) { readString = sr.ReadToEnd(); } var deseralized = Newtonsoft.Json.JsonConvert.DeserializeObject <HashableString>(readString); Assert.IsTrue(deseralized.Verify()); deseralized.ComputeHash(provider); Assert.IsTrue(deseralized.Verify()); Assert.AreEqual(deseralized.ComputedHash.Bytes, firstItem.ComputedHash.Bytes); store.DropData(); store.Dispose(); } } }
public void HashableFromsEquate() { var precomputedHashes = new Dictionary <HashProvider, string>() { { HashProvider.SHA256, @"AYSLdKSodmdJQlMzKiDoAZlUL09GgLyHr9VTZlhQtkg=" }, { HashProvider.SHA384, @"TDQMTam7Wy20bTaD0vV7mCd760L4DNmsp55cgPnltRvVVf18qtTi/6ryuR4bXvJm" }, { HashProvider.SHA512, @"NMp1zZdwa+MmPPwe6YoPe0eS1UxXk0sBCJN6tEzD0/BCHsqk9P282nwS3paL+XJRSdipcCb3EObB7F5r/qe6xQ==" } }; var testFilePath = "HashableFromsEquate.txt"; var testString = "60EC9927-35B3-4CCB-9791-56D0FF00F07B"; File.WriteAllText(testFilePath, testString); var hBytes = new HashableBytes(Encoding.ASCII.GetBytes(testString)); var hString = new HashableString(testString); var hFile = new HashableFile(testFilePath); var hStream = new HashableStream(new MemoryStream(Encoding.ASCII.GetBytes(testString))); foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { hBytes.ComputeHash(provider); hString.ComputeHash(provider); hFile.ComputeHash(provider); hStream.ComputeHash(provider); Assert.True(precomputedHashes.ContainsKey(provider), "The stored test hash dictionary has a comparison Hash, and same as HashableString"); var precomputedTestHash = precomputedHashes[provider]; var hBytesString = hBytes.ComputedHash.ToString(); Assert.AreEqual(hBytesString, precomputedTestHash, "Computed and stored hash differ"); Assert.AreEqual(hBytesString, hString.ComputedHash.ToString()); Assert.AreEqual(hBytesString, hFile.ComputedHash.ToString()); Assert.AreEqual(hBytesString, hStream.ComputedHash.ToString()); } }
public void AddRemoveAccuracy() { foreach (var hStoreType in Factory.GetImplementors()) { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var store = GetTestStore(hStoreType, provider, true, int.MaxValue); var firstItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(provider, signingCert); store.StoreItem(firstItem); if (hStoreType == typeof(NullStore)) { //Skip nullstore continue; } //Check that we can get our item and all the fields match exactly var retrevedItem = store.GetItem <HashableString>(firstItem.ComputedHash); Assert.True(retrevedItem.ComputedHash == firstItem.ComputedHash); Assert.True(retrevedItem.ComputedHash.Provider == firstItem.ComputedHash.Provider); Assert.True(retrevedItem.ComputedHash.SignatureBytes.ToComparable() == firstItem.ComputedHash.SignatureBytes.ToComparable()); Assert.True(retrevedItem.ComputedHash.SignatureCertHash.ToComparable() == firstItem.ComputedHash.SignatureCertHash.ToComparable()); Assert.True(retrevedItem.ComputedHash.SourceByteLength == firstItem.ComputedHash.SourceByteLength); Assert.True(firstItem.Verify(signingCert)); Assert.True(retrevedItem.Verify(signingCert)); Assert.NotNull(retrevedItem.ComputedHash.ComputedDate); Assert.True(retrevedItem.ComputedHash.ComputedDate.Value.Ticks == firstItem.ComputedHash.ComputedDate.Value.Ticks); Assert.True(retrevedItem.Value == firstItem.Value); Assert.True(store.ItemCount == 1); } } }
public void RunMaintenanceExaustive() { int testSize = R.Next(10, 50); foreach (var hStoreType in (Factory.GetImplementors())) { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { if (hStoreType == typeof(NullStore)) { continue; } var store = GetTestStore(hStoreType, provider, true, testSize); store.RunMaintenance(); //some stores may not have an item count until maintenance is run Assert.True(store.ItemCount == 0); //new store should be empty //add a single item var firstItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(provider, null); store.StoreItem(firstItem); //check that we can get it if (hStoreType != typeof(NullStore)) { Assert.True(store.GetItem <HashableString>(firstItem.ComputedHash).ComputedHash == firstItem.ComputedHash); } //add a bunch more for (int i = 0; i < testSize; i++) { var item = new HashableString(Guid.NewGuid().ToString()); item.ComputeHash(provider, null); store.StoreItem(item); Assert.IsTrue(item.Verify()); Assert.True(store.GetItem <HashableString>(item.ComputedHash).ComputedHash == item.ComputedHash); System.Threading.Thread.Sleep(100); } //check the size, should have all Assert.True(store.ItemCount == testSize + 1); if (store.IsPersistant) { //Dispose the current instance store.Dispose(); //Recreate the store store = GetTestStore(hStoreType, provider, false, testSize); //some stores may not have an item count until maintenance is run store.RunMaintenance(); } else { //run maintenance and remove the oldest item store.RunMaintenance(); } //store should be exactly the test size after maintance Assert.True(store.ItemCount == testSize); //first item should be gone since it is the oldest var firstItemGet = store.GetItem <HashableString>(firstItem.ComputedHash); Assert.IsNull(firstItemGet); store.DropData(); store.Dispose(); } } }
public void AddRemoveExaustive() { foreach (var hStoreType in Factory.GetImplementors()) { foreach (HashProvider provider in Enum.GetValues(typeof(HashProvider))) { var store = GetTestStore(hStoreType, provider, true, int.MaxValue); var firstItem = new HashableString(Guid.NewGuid().ToString()); firstItem.ComputeHash(provider, null); store.StoreItem(firstItem); if (hStoreType == typeof(NullStore)) { //Skip nullstore continue; } //If we are not storing to null, check that we can get our item var retrevedItem = store.GetItem <HashableString>(firstItem.ComputedHash); Assert.True(retrevedItem.ComputedHash == firstItem.ComputedHash); Assert.True(retrevedItem.ComputedHash.ComputedDate == firstItem.ComputedHash.ComputedDate); Assert.True(retrevedItem.Value == firstItem.Value); Assert.IsTrue(retrevedItem.Verify()); Assert.IsTrue(firstItem.Verify()); Assert.True(store.ItemCount == 1); if (store.IsPersistant) { //Dispose the current instance store.Dispose(); //Check that dispose is implemented correctly and we can't get an item from a disposed store Assert.IsNull(store.GetItem <HashableString>(firstItem.ComputedHash), "Disposed stores should not return a value"); Assert.False(store.StoreItem(firstItem), "Disposed stores should not store items"); //Recreate the store store = GetTestStore(hStoreType, provider, false, int.MaxValue); //Check that we can still get the persisted item var retrevedItem2 = store.GetItem <HashableString>(firstItem.ComputedHash); Assert.True(retrevedItem.ComputedHash == firstItem.ComputedHash); Assert.True(retrevedItem.ComputedHash.ComputedDate == firstItem.ComputedHash.ComputedDate); Assert.True(retrevedItem.Value == firstItem.Value); //some stores may not have an item count until maintenance is run (FileStore) store.RunMaintenance(); Assert.True(store.ItemCount == 1); } store.TryRemoveItem(firstItem.ComputedHash); if (hStoreType != typeof(NullStore)) { //Check that an item after removal can't be retrieved Assert.IsNull(store.GetItem <HashableString>(firstItem.ComputedHash)); Assert.True(store.ItemCount == 0); } //Drop all data store.DropData(); Assert.IsNull(store.GetItem <HashableString>(firstItem.ComputedHash), "Dropped stores should not return a value"); //Finally dispose store.Dispose(); } } }