/// <summary>
        /// Girilen parametrelere gore plainText in ozetini alip byte[] olarak doner.
        /// </summary>
        /// <param name="plainText">Ozeti alinacak metin</param>
        /// <param name="hashAlgorithm">Ozet algoritmasi</param>
        /// <param name="stringConversion">Tuzlama degerini byte[] e cevirmek icin kullanilacak yontem</param>
        /// <returns>Parametre olarak verilen acik metnin ozet bilgisini string olarak doner.</returns>
        public string ComputeHash(string plainText, HashAlgorithmEnum hashAlgorithm, StringConversionEnum stringConversion = StringConversionEnum.Base64)
        {
            // Convert result into a base64-encoded string.
            var hashValue = string.Empty;

            if (stringConversion == StringConversionEnum.Base64)
            {
                hashValue = Convert.ToBase64String(ComputeHash(plainText, hashAlgorithm, string.Empty));
            }
            else if (stringConversion == StringConversionEnum.Hex)
            {
                hashValue = ByteArrayToHexString(ComputeHash(plainText, hashAlgorithm, string.Empty));
            }
            // Return the result.
            return(hashValue);
        }
        /// <summary>
        /// Girilen parametrelere gore plainText in ozetini alip byte[] olarak doner.
        /// </summary>
        /// <param name="plainText">Ozeti alinacak metin</param>
        /// <param name="hashAlgorithm">Ozet algoritmasi</param>
        /// <param name="saltValue">Tuzlama degeri</param>
        /// <param name="stringConversion">Tuzlama degerini byte[] e cevirmek icin kullanilacak yontem</param>
        /// <returns>Parametre olarak verilen acik metnin ozet bilgisini btye[] olarak doner.</returns>
        public byte[] ComputeHash(string plainText, HashAlgorithmEnum hashAlgorithm, string saltValue, StringConversionEnum stringConversion = StringConversionEnum.Base64)
        {
            // If salt is not specified, generate it on the fly.
            byte[] saltBytes = null;
            if (saltValue == null)
            {
                // Generate a random number for the size of the salt.
                var random   = new Random();
                var saltSize = random.Next(MinSaltSize, MaxSaltSize);

                // Allocate a byte array, which will hold the salt.
                saltBytes = new byte[saltSize];

                // Initialize a random number generator.
                var rng = new RNGCryptoServiceProvider();

                // Fill the salt with cryptographically strong byte values.
                rng.GetNonZeroBytes(saltBytes);
            }
            else
            {
                if (stringConversion == StringConversionEnum.Base64)
                {
                    saltBytes = Convert.FromBase64String(saltValue);
                }
                else if (stringConversion == StringConversionEnum.Hex)
                {
                    saltBytes = StringToByteArray(saltValue);
                }
            }
            // Convert plain text into a byte array.
            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);

            // Allocate array, which will hold plain text and salt.
            var plainTextWithSaltBytes =
                new byte[plainTextBytes.Length + saltBytes.Length];

            // Copy plain text bytes into resulting array.
            for (var i = 0; i < plainTextBytes.Length; i++)
            {
                plainTextWithSaltBytes[i] = plainTextBytes[i];
            }

            // Append salt bytes to the resulting array.
            for (var i = 0; i < saltBytes.Length; i++)
            {
                plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
            }

            // Because we support multiple hashing algorithms, we must define
            // hash object as a common (abstract) base class. We will specify the
            // actual hashing algorithm class later during object creation.
            HashAlgorithm hash;


            // Initialize appropriate hashing algorithm class.
            switch (hashAlgorithm)
            {
            case HashAlgorithmEnum.SHA1:
                hash = new SHA1Managed();
                break;

            case HashAlgorithmEnum.SHA256:
                hash = new SHA256Managed();
                break;

            case HashAlgorithmEnum.SHA384:
                hash = new SHA384Managed();
                break;

            case HashAlgorithmEnum.SHA512:
                hash = new SHA512Managed();
                break;

            case HashAlgorithmEnum.MD5:
                hash = new MD5CryptoServiceProvider();
                break;

            default:
                hash = new MD5CryptoServiceProvider();
                break;
            }

            // Compute hash value of our plain text with appended salt.
            var hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

            // Create array which will hold hash and original salt bytes.
            var hashWithSaltBytes = new byte[hashBytes.Length +
                                             saltBytes.Length];

            // Copy hash bytes into resulting array.
            for (var i = 0; i < hashBytes.Length; i++)
            {
                hashWithSaltBytes[i] = hashBytes[i];
            }

            // Append salt bytes to the result.
            for (var i = 0; i < saltBytes.Length; i++)
            {
                hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];
            }

            return(hashWithSaltBytes);
        }
        /// <summary>
        /// Belirtilen metnin ozetini alarak hashValue parametresi ile belirtilen ozet degeriyle karsilastirir.
        /// </summary>
        /// <param name="plainText">Ozeti alinip karsilastirilacak acik metin</param>
        /// <param name="hashAlgorithm">Ozet algoritmasi</param>
        /// <param name="hashValue">Mevcut ozet degeri</param>
        /// <param name="stringConversion">Hash degerini byte[] e cevirmek icin secilen yontem</param>
        /// <returns>Belirtilen hashValue degeri ile yeni hesaplanan ozet degerinin ayni olup olmadigi (true,false) bilgisini dondurur.</returns>
        public bool VerifyHash(string plainText, HashAlgorithmEnum hashAlgorithm, string hashValue, StringConversionEnum stringConversion = StringConversionEnum.Base64)
        {
            // Convert base64-encoded hash value into a byte array.
            byte[] hashWithSaltBytes = null;
            if (stringConversion == StringConversionEnum.Base64)
            {
                hashWithSaltBytes = Convert.FromBase64String(hashValue);
            }
            else if (stringConversion == StringConversionEnum.Hex)
            {
                hashWithSaltBytes = StringToByteArray(hashValue);
            }
            // We must know size of hash (without salt).
            int hashSizeInBits;

            // Size of hash is based on the specified algorithm.
            switch (hashAlgorithm)
            {
            case HashAlgorithmEnum.SHA1:
                hashSizeInBits = 160;
                break;

            case HashAlgorithmEnum.SHA256:
                hashSizeInBits = 256;
                break;

            case HashAlgorithmEnum.SHA384:
                hashSizeInBits = 384;
                break;

            case HashAlgorithmEnum.SHA512:
                hashSizeInBits = 512;
                break;

            case HashAlgorithmEnum.MD5:
                hashSizeInBits = 128;
                break;

            default:     // Must be MD5
                hashSizeInBits = 128;
                break;
            }

            // Convert size of hash from bits to bytes.
            var hashSizeInBytes = hashSizeInBits / 8;

            // Make sure that the specified hash value is long enough.
            if (hashWithSaltBytes.Length < hashSizeInBytes)
            {
                return(false);
            }

            // Allocate array to hold original salt bytes retrieved from hash.
            var saltBytes = new byte[hashWithSaltBytes.Length -
                                     hashSizeInBytes];

            // Copy salt from the end of the hash to the new array.
            for (var i = 0; i < saltBytes.Length; i++)
            {
                saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];
            }

            // Compute a new hash string.
            var expectedHashString = string.Empty;

            if (stringConversion == StringConversionEnum.Base64)
            {
                expectedHashString = Convert.ToBase64String(ComputeHash(plainText, hashAlgorithm, Convert.ToBase64String(saltBytes)));
            }
            else if (stringConversion == StringConversionEnum.Hex)
            {
                expectedHashString = ByteArrayToHexString(ComputeHash(plainText, hashAlgorithm, ByteArrayToHexString(saltBytes)));
            }

            // If the computed hash matches the specified hash,
            // the plain text value must be correct.
            return(hashValue == expectedHashString);
        }