/// <summary>
        /// Transform any arbitrary input string into a secure and unintelligible hash (string).
        /// - Simple and quick
        /// - Low level security
        /// - NOT to be used for sensitive data such as passwords. Instead use the method method HashPassword.
        /// </summary>
        /// <param name="text">The input string to hash</param>
        /// <param name="salt">A string containing 16 or more random characters. The salt should be saved together with the hash. Only use each salt once (read: generate a new salt every time you hash)</param>
        /// <param name="algorithm">The algorithm that should perform the hashing operation</param>
        /// <returns>A HashResult object that contains the results of the hashing proces. Call .ToString() to convert the object into a single hash string</returns>
        /// <remarks>Not to be used for sensitive data such as passwords</remarks>
        public static HashResult Hash(string text, string salt, EnmHashingAlgorithm algorithm = EnmHashingAlgorithm.SHA512)
        {
            if (String.IsNullOrEmpty(text))
                return null;
            if (salt == null || salt.Length < SALT_LENGTH)
                throw new ArgumentException("Must be atleast " + SALT_LENGTH.ToString() + " characters in length", "salt");

            var textBytes = ASCIIEncoding.ASCII.GetBytes(text);
            var saltBytes = ASCIIEncoding.ASCII.GetBytes(salt);
            return Hash(textBytes, saltBytes, algorithm.SHA());
        }
        /// <summary>
        /// Transform any arbitrary input string into a secure and unintelligible hash (string). 
        /// This method is a keyed hashing method which is a lot more secure then the regular hashing methods
        /// - The generated keyed hash can be used to verify the authenticity of a message
        /// - NOT to be used for securing passwords, instead use the provided method HashPassword.
        /// </summary>
        /// <param name="text">The input string to hash</param>
        /// <param name="salt">A string containing 16 or more random characters. The salt should be saved together with the hash. Only use each salt once (read: generate a new salt every time you hash)</param>
        /// <param name="algorithm">The hashing algorithm to use for the hashing proces</param>
        /// <param name="key">The secret key to be used to generate the hash. T</param>
        /// <returns>A HashResult object that contains the results of the hashing proces. Call .ToString() to convert the object into a single hash string</returns>
        /// <remarks>Not to be used for sensitive data such as passwords</remarks>
        public static HashResult HashWithAuthentication(string text, string salt, EnmHashingAlgorithm algorithm, string key)
        {
            if (text == null || text.Length == 0)
                return null;
            if (salt == null || salt.Length < SALT_LENGTH)
                throw new ArgumentException("Must be atleast " + SALT_LENGTH.ToString() + " characters in length", "salt");
            if (key == null || key.Length < MIN_SECRETKEY_LENGTH)
                throw new ArgumentException("Must be atleast " + MIN_SECRETKEY_LENGTH.ToString() + " characters in length", "key");

            var textBytes = Encoding.ASCII.GetBytes(text);
            var saltBytes = Encoding.ASCII.GetBytes(salt);
            var keyBytes = Encoding.ASCII.GetBytes(key);
            return HashWithAuthentication(textBytes, saltBytes, keyBytes, algorithm);
        }
        static HashResult HashWithAuthentication(byte[] text, byte[] salt, byte[] key, EnmHashingAlgorithm algorithm)
        {
            if (text == null || text.Length == 0)
                return null;
            if (salt == null || salt.Length < SALT_LENGTH)
                throw new ArgumentException("Must be atleast " + SALT_LENGTH.ToString() + " characters in length", "salt");
            if (key == null || key.Length < MIN_SECRETKEY_LENGTH)
                throw new ArgumentException("Must be atleast " + MIN_SECRETKEY_LENGTH.ToString() + " characters in length", "masterKey");

            // Tussenstap: Genereer nu o.b.v. de (master)key en de salt een nieuwe afgeleide sleutel waarmee we gaan hashen: de zogenaamde hashKey.
            // Dit doen we zodat je de key niet kan herleiden uit de hash die we straks gaan genereren.
            byte[] hashkeyBytes; // De hashkey. Hiermee gaan we zometeen hashen
            using (var hkdf = new HKDF(SecurityDrivenDotNet.HMACFactories.HMACSHA512, key, salt))
                hashkeyBytes = hkdf.GetBytes(64);

            // Magic: Transformeer de data, met behulp van de sleutel, naar een onleesbare maar voorspelbare hash.
            var hash = new HMAC2(algorithm.Factory(), hashkeyBytes).ComputeHash(text);

            // Retourneer het resultaat als een BASE-64 encoded string
            return new HashResult(algorithm.ToString(), Convert.ToBase64String(salt), Convert.ToBase64String(hash));
        }