public void ChunkHashesMatchAndRollupToIdentifier() { var random = new Random(); TryWithDifferentSizes(testSize => { var bytes = new byte[testSize]; random.NextBytes(bytes); var blocks = new List <BlobBlockHash>(); var rollingId = new VsoHash.RollingBlobIdentifierWithBlocks(); BlobIdentifierWithBlocks blobIdentifierWithBlocks = null; for (int i = 0; i < testSize;) { int blockSize = Math.Min(testSize - i, VsoHash.BlockSize); var block = new byte[blockSize]; Array.Copy(bytes, i, block, 0, blockSize); BlobBlockHash blockHash = VsoHash.HashBlock(block, blockSize); blocks.Add(blockHash); i += blockSize; if (i < testSize) { rollingId.Update(blockHash); } else { blobIdentifierWithBlocks = rollingId.Finalize(blockHash); } } if (testSize == 0) { BlobBlockHash blockHash = VsoHash.HashBlock(new byte[] { }, 0); blocks.Add(blockHash); blobIdentifierWithBlocks = rollingId.Finalize(blockHash); } using (var byteStream = new MemoryStream(bytes)) { BlobIdentifierWithBlocks identifierWithBlocks = VsoHash.CalculateBlobIdentifierWithBlocks(byteStream); Assert.True(identifierWithBlocks.BlockHashes.SequenceEqual(blocks)); Assert.Equal(identifierWithBlocks, blobIdentifierWithBlocks); } }); }
public void BlockHashesDoNotChange() { var knownValues = new Dictionary <IEnumerable <int>, string>() { { Enumerable.Empty <int>(), "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" }, { Enumerable.Range(0, 1), "1406E05881E299367766D313E26C05564EC91BF721D31726BD6E46E60689539A" }, { Enumerable.Range(0, VsoHash.PageSize - 1), "12078762B8EDA8A5499C46E9B5C7F8D37BAB3A684571AEFC2A7D3ABCD56C093E" }, { Enumerable.Range(0, VsoHash.PageSize), "B00BE365B41949CF3571F69F8F5AD95514F6AFDFE094ABA614ECD34BD828272B" }, { Enumerable.Range(0, VsoHash.PageSize + 1), "4A3E85BABDD4243495A3617E9316BDF9CDC4526F97AA0E435A47226876C3D167" }, { Enumerable.Range(0, VsoHash.BlockSize - 1), "3492B19DDCD76EA1ED5C07090A021705ADC7E7D5C5AAD4FF619FD12FAECEB197" }, { Enumerable.Range(0, VsoHash.BlockSize), "E8DEEF25ED53357D2A738D7156067E69892A7BDC190818CD2AD698A3A1F95E03" }, }; foreach (var knownValue in knownValues) { byte[] bytes = knownValue.Key.Select(i => (byte)(i & 0xFF)).ToArray(); Assert.Equal( knownValue.Value, VsoHash.HashBlock(bytes, bytes.Length).HashString); } }
/// <summary> /// Gets a single hash representing the ContentHashList /// </summary> public static byte[] GetHashOfHashes(this ContentHashList contentHashList) { var rollingBlobIdentifier = new VsoHash.RollingBlobIdentifier(); BlobIdentifier blobIdOfContentHashes = VsoHash.OfNothing.BlobId; for (int i = 0; i < contentHashList.Hashes.Count; i++) { BlobIdentifier blobId = BlobIdentifier.Deserialize(contentHashList.Hashes[i].ToHex()); if (i != contentHashList.Hashes.Count - 1) { rollingBlobIdentifier.Update(VsoHash.HashBlock(blobId.Bytes, blobId.Bytes.Length)); } else { blobIdOfContentHashes = rollingBlobIdentifier.Finalize(VsoHash.HashBlock(blobId.Bytes, blobId.Bytes.Length)); } } return(blobIdOfContentHashes.Bytes); }