public void Md5Test()
        {
            Assert.Equal("708171654200ecd0e973167d8826159c", ShaUtil.MD5Compute(STR_EN), ignoreCase: true);
            Assert.Equal("63551bb88226152a2276bf19761b6460", ShaUtil.HMacMD5Compute(STR_EN, SECRET), ignoreCase: true);

            Assert.Equal("86b2826fea7349ce6af96f446d7e2fcf", ShaUtil.MD5Compute(STR_CH), ignoreCase: true);
            Assert.Equal("69bcddfdb4c12c5de290f40c53d31d43", ShaUtil.HMacMD5Compute(STR_CH, SECRET), ignoreCase: true);
        }
        private static string SignRequestParameter(IDictionary <string, IConvertible> dict, string apiKey)
        {
            if (dict == null)
            {
                throw new ArgumentNullException(nameof(dict));
            }

            dict = new SortedDictionary <string, IConvertible>(
                dict.Where(e =>
                           (e.Value != null) ||
                           (e.Value is string && !string.IsNullOrWhiteSpace(e.Value.ToString()))
                           )
                .ToDictionary(k => k.Key, v => v.Value),
                StringComparer.InvariantCultureIgnoreCase
                );

            if (dict.ContainsKey("sign"))
            {
                throw new ArgumentException("The parameters to be signed cannot contain a key named \"sign\".");
            }
            if (!dict.ContainsKey("sign_type"))
            {
                throw new ArgumentException("The parameters to be signed must contain a key named \"sign_type\".");
            }

            string stringSignTemp = string.Join("&", dict.Select(e => $"{e.Key}={e.Value}").ToArray());

            stringSignTemp += "&key=" + apiKey;

            switch (dict["sign_type"])
            {
            case "MD5":
            {
                string sign = ShaUtil.MD5Compute(stringSignTemp).ToUpper();
                return(sign);
            }

            case "HMAC-SHA256":
            {
                string sign = ShaUtil.HMacSHA256Compute(stringSignTemp, apiKey).ToUpper();
                return(sign);
            }

            default:
                throw new NotSupportedException();
            }
        }