private static void GenerateAndSendHashes(Stream stream, C3C4TaylorsRollingChecksum rollingChecksum, Stream fileStream, int fileSize, byte[] buffer) { int fileSize2 = fileSize; int weakHash = 0; while (fileSize2 > 0) { int toSend = fileSize2 < BlockSize ? fileSize2 : BlockSize; for (int i = 0; i < toSend; ++i) weakHash = rollingChecksum.Slide(); weakHash.WriteTo(stream); fileStream.Seek(fileSize - fileSize2, 0); fileStream.ForceRead(buffer, 0, toSend); byte[] strongHash = Md5.ComputeHash(buffer, 0, toSend); stream.Write(strongHash, 0, strongHash.Length); toSend.WriteTo(stream); fileSize2 -= toSend; } }
private static List<Chunk> DiscoverChunksInLocalFile(Dictionary<int, List<Chunk>> remoteChunks, C3C4TaylorsRollingChecksum weakHashFunction, Stream fileStreamOld, int fileSizeOld, byte[] buffer) { var chunks = new List<Chunk>(); int i = 0; while (i++ < fileSizeOld) { int weakHash = weakHashFunction.Slide(); List<Chunk> sameWeakHashChunks; if (remoteChunks.TryGetValue(weakHash, out sameWeakHashChunks)) { byte[] strongHash = null; foreach (var chunk in sameWeakHashChunks) { if (chunk.Found || i < chunk.Length) continue; if (strongHash == null) { fileStreamOld.Seek(i - chunk.Length, 0); fileStreamOld.ForceRead(buffer, 0, chunk.Length); strongHash = Md5.ComputeHash(buffer, 0, chunk.Length); fileStreamOld.Seek(i, 0); } if (strongHash.AreEqual(chunk.StrongHash)) { chunk.Found = true; chunk.OldStart = i - chunk.Length; chunks.Add(chunk); } } } } chunks.Sort((i1, i2) => i1.NewStart.CompareTo(i2.NewStart)); return chunks; }