using System; using System.IO; using System.Reflection; using System.Security.Cryptography; namespace SharpCifs.Util.Sharpen { public abstract class MessageDigest { public void Digest(byte[] buffer, int o, int len) { byte[] d = Digest(); d.CopyTo(buffer, o); } public byte[] Digest(byte[] buffer) { Update(buffer); return Digest(); } public abstract byte[] Digest(); public abstract int GetDigestLength(); public static MessageDigest GetInstance(string algorithm) { switch (algorithm.ToLower()) { case "sha-1": //System.Security.CryptographySHA1Managed not found //return new MessageDigest (); return new MessageDigest(); case "md5": return new MessageDigest(); } throw new NotSupportedException( string.Format("The requested algorithm \"{0}\" is not supported.", algorithm)); } public abstract void Reset(); public abstract void Update(byte[] b); public abstract void Update(byte b); public abstract void Update(byte[] b, int offset, int len); } public class MessageDigest : MessageDigest where TAlgorithm : HashAlgorithm //, new() //use static `Create` method { private TAlgorithm _hash; //private CryptoStream _stream; //don't work .NET Core private MemoryStream _stream; public MessageDigest() { Init(); } public override byte[] Digest() { //CryptoStream -> MemoryStream, needless method //_stream.FlushFinalBlock (); //HashAlgorithm.`Hash` property deleted //byte[] hash = _hash.Hash; byte[] hash = _hash.ComputeHash(_stream.ToArray()); Reset(); return hash; } public void Dispose() { if (_stream != null) { _stream.Dispose(); } _stream = null; } public override int GetDigestLength() { return (_hash.HashSize / 8); } private void Init() { //use static `Create` method //_hash = Activator.CreateInstance (); var createMethod = typeof(TAlgorithm).GetRuntimeMethod("Create", new Type[0]); _hash = (TAlgorithm)createMethod.Invoke(null, new object[] { }); //HashAlgorithm cannot cast `ICryptoTransform` on .NET Core, gave up using CryptoStream. //_stream = new CryptoStream(Stream.Null, _hash, CryptoStreamMode.Write); //_stream = new CryptoStream(_tmpStream, (ICryptoTransform)_hash, CryptoStreamMode.Write); _stream = new MemoryStream(); } public override void Reset() { Dispose(); Init(); } public override void Update(byte[] input) { _stream.Write(input, 0, input.Length); } public override void Update(byte input) { _stream.WriteByte(input); } public override void Update(byte[] input, int index, int count) { if (count < 0) Console.WriteLine("Argh!"); _stream.Write(input, index, count); } } }