Пример #1
0
        public async Task <string> GetED2KHash()
        {
            if (_hashString != null)
            {
                return(_hashString);
            }

            var queue = MaxSimultaneousChunks <= 0
                                                ? new BlockingCollection <Task <Tuple <MD4Digest, bool> > >(
                new ConcurrentQueue <Task <Tuple <MD4Digest, bool> > >())
                                                : new BlockingCollection <Task <Tuple <MD4Digest, bool> > >(
                new ConcurrentQueue <Task <Tuple <MD4Digest, bool> > >(), MaxSimultaneousChunks);

            Task.Run(() =>
            {
                var fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read);
                for (uint i = 0; i < ChunkCount; i++)
                {
                    byte[] data = new byte[fs.Length - fs.Position > ChunkSize
                                                                            ? ChunkSize
                                                                            : fs.Length - fs.Position];
                    fs.Read(data, 0, data.Length);
                    var last  = fs.Position == fs.Length;
                    var index = i;
                    Debug.Print("=>" + index);
                    queue.Add(Task.Run(() =>
                    {
                        Debug.Print("<=" + index);
                        using (var chunk = new Chunk(data, last))
                            return(Tuple.Create(chunk.Digest(), chunk.Last));
                    }));

                    ReadChunks = i + 1;
                }
            });

            uint       completedChunks = 0;
            MD4Context md4Context      = new MD4Context();
            Task <Tuple <MD4Digest, bool> > currentChunk;

            do
            {
                currentChunk = queue.Take();

                var chunkHash = (await currentChunk).Item1.ToArray();
                md4Context.Update(chunkHash, 0, chunkHash.Length);
                completedChunks++;
                CompletedChunks = completedChunks;
            } while (!currentChunk.Result.Item2);             //While not last

            _hashString = md4Context.GetDigest().ToString();
            return(_hashString);
        }
Пример #2
0
        public void CalculateHash()
        {
            Complete = 0;

            MD4Context md4Context = new MD4Context();

            if (ChunkCount == 1)
            {
                byte[] data = new byte[_fileStream.Length];
                _fileStream.Read(data, 0, data.Length);

                Chunk newChunk = new Chunk(data);

                newChunk.CalculateHash();

                _hash = newChunk.MD4Digest.ToString();

                Complete = 1;
                return;
            }

            Parallel.Invoke(new Action[]
            {
                () =>
                {
                    for (int i = 0; i < ChunkCount; i++)
                    {
                        byte[] data = new byte[_fileStream.Length - _fileStream.Position > ChunkSize
                                                                                                                                                ? ChunkSize
                                                                                                                                                : _fileStream.Length - _fileStream.Position];

                        _fileStream.Read(data, 0, data.Length);

                        Chunk newChunk = new Chunk(data)
                        {
                            Last = _fileStream.Position == _fileStream.Length
                        };
                        ThreadPool.QueueUserWorkItem(o => newChunk.CalculateHash());

                        //Blocks if the queue is full
                        _processQueue.Add(newChunk);
                    }
                },
                () =>
                {
                    Chunk currentChunk;
                    do
                    {
                        //Blocks if the queue is empty
                        currentChunk = _processQueue.Take();

                        //Blocks if the chunk hash is still calculating
                        currentChunk.Done.WaitOne();

                        byte[] chunkHash = currentChunk.MD4Digest.ToArray();

                        md4Context.Update(chunkHash, 0, chunkHash.Length);

                        Complete++;
                    } while (!currentChunk.Last);
                }
            });

            _hash = md4Context.GetDigest().ToString();
        }