Files
GateDge2023_ljy/00.SDK/E_ZKEccTopSdk/Uitl/TopUtils.cs

272 lines
9.6 KiB
C#
Raw Normal View History

2024-04-29 17:57:07 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
namespace E_ZKEccTopSdk.Uitl
{
/// <summary>
/// TOP系统工具类。
/// </summary>
public abstract class TopUtils
{
private static readonly JSONParameters jp = new JSONParameters();
private static string intranetIp;
static TopUtils()
{
jp.UseApiNamingStyle = true;
jp.UseExtensions = false;
jp.SerializeNullValues = false;
}
/// <summary>
/// 给TOP请求签名。
/// </summary>
/// <param name="parameters">所有字符型的TOP请求参数</param>
/// <param name="secret">签名密钥</param>
/// <param name="signMethod">签名方法可选值md5, hmac</param>
/// <returns>签名</returns>
public static string SignTopRequest(IDictionary<string, string> parameters, string secret, string signMethod)
{
return SignTopRequest(parameters, null, secret, signMethod);
}
/// <summary>
/// 给TOP请求签名。
/// </summary>
/// <param name="parameters">所有字符型的TOP请求参数</param>
/// <param name="body">请求主体内容</param>
/// <param name="secret">签名密钥</param>
/// <param name="signMethod">签名方法可选值md5, hmac</param>
/// <returns>签名</returns>
public static string SignTopRequest(IDictionary<string, string> parameters, string body, string secret, string signMethod)
{
// 第一步把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters, StringComparer.Ordinal);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
if (Constants.SIGN_METHOD_MD5.Equals(signMethod))
{
query.Append(secret);
}
foreach (KeyValuePair<string, string> kv in sortedParams)
{
if (!string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value))
{
query.Append(kv.Key).Append(kv.Value);
}
}
// 第三步:把请求主体拼接在参数后面
if (!string.IsNullOrEmpty(body))
{
query.Append(body);
}
// 第四步使用MD5/HMAC加密
byte[] bytes;
if (Constants.SIGN_METHOD_HMAC.Equals(signMethod))
{
HMACMD5 hmac = new HMACMD5(Encoding.UTF8.GetBytes(secret));
bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
}
else if (Constants.SIGN_METHOD_HMAC_SHA256.Equals(signMethod))
{
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
}
else
{
query.Append(secret);
MD5 md5 = MD5.Create();
bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
}
// 第五步:把二进制转化为大写的十六进制
StringBuilder result = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
result.Append(bytes[i].ToString("X2"));
}
return result.ToString();
}
/// <summary>
/// 清除字典中值为空的项。
/// </summary>
/// <param name="dict">待清除的字典</param>
/// <returns>清除后的字典</returns>
public static IDictionary<string, T> CleanupDictionary<T>(IDictionary<string, T> dict)
{
IDictionary<string, T> newDict = new Dictionary<string, T>(dict.Count);
foreach (KeyValuePair<string, T> kv in dict)
{
if (kv.Value != null)
{
newDict.Add(kv.Key, kv.Value);
}
}
return newDict;
}
/// <summary>
/// 把对象转换为JSON字符串。
/// </summary>
public static string ObjectToJson(object obj)
{
return JSON.ToJSON(obj, jp);
}
/// <summary>
/// 把对象转换为JSON字符串。
/// </summary>
public static string ObjectToJson(object obj, JSONParameters newjp)
{
return JSON.ToJSON(obj, newjp);
}
/// <summary>
/// 把JSON字符串转换为对象。
/// </summary>
public static object JsonToObject(string json)
{
return JSON.Parse(json);
}
/// <summary>
/// 把JSON解释为API响应对象。
/// </summary>
/// <typeparam name="T">API响应类型</typeparam>
/// <param name="json">JSON字符串</param>
/// <returns>API响应对象</returns>
public static T ParseResponse<T>(string json) where T : TopResponse
{
TopJsonParser<T> parser = new TopJsonParser<T>();
return parser.Parse(json);
}
/// <summary>
/// 获取从1970年1月1日到现在的毫秒总数。
/// </summary>
/// <returns>毫秒数</returns>
public static long GetCurrentTimeMillis()
{
return (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
}
/// <summary>
/// 获取本机的局域网IP。
/// </summary>
public static string GetIntranetIp()
{
if (intranetIp == null)
{
NetworkInterface[] nis = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in nis)
{
if (OperationalStatus.Up == ni.OperationalStatus && (NetworkInterfaceType.Ethernet == ni.NetworkInterfaceType || NetworkInterfaceType.Wireless80211 == ni.NetworkInterfaceType))
{
foreach (UnicastIPAddressInformation info in ni.GetIPProperties().UnicastAddresses)
{
if (AddressFamily.InterNetwork == info.Address.AddressFamily)
{
intranetIp = info.Address.ToString();
break;
}
}
if (intranetIp != null) break;
}
}
}
if (intranetIp == null)
{
intranetIp = "127.0.0.1";
}
return intranetIp;
}
public const string CHARSET_UTF8 = "UTF-8";
public const string SIGN_METHOD_SHA256 = "sha256";
public const string SIGN_METHOD_HMAC_SHA256 = "HmacSHA256";
public static string SignApiRequest(IDictionary<string, string> aparams, string appSecret, string signMethod, string apiName)
{
// 如果是调用原平台迁移方法请将方法名作为请求参数放入params中参与排序
// 第一步:检查参数是否已经排序
string[]
keys = aparams.Keys.ToArray();
Array.Sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
// 如果是调用新平台注册方法,请执行第三步,直接拼接方法名
// 第三步将API名拼接在字符串开头
query.Append(apiName);
foreach (string key in keys)
{
string value = aparams[key];
if (aparams.ContainsKey(key))
{
query.Append(key).Append(value);
}
}
// 第四步:使用加密算法
byte[] bytes = null;
//var ttt = query.ToString();
if (signMethod.Equals(SIGN_METHOD_SHA256))
{
bytes = encryptHMACSHA256(query.ToString(), appSecret);
}
// 第五步:把二进制转化为大写的十六进制(正确签名应该为32大写字符串此方法需要时使用)
return byte2hex(bytes);
}
private static byte[] encryptHMACSHA256(string data, string secret)
{
byte[] bytes = null;
try
{
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
//SecretKey secretKey = new SecretKeySpec(secret.(CHARSET_UTF8), SIGN_METHOD_HMAC_SHA256);
//Mac mac = Mac.getInstance(hmac.getAlgorithm());
//mac.init(secretKey);
//bytes = Encoding.UTF8.GetBytes(secret);
}
catch (Exception ex)
{
throw;
}
return bytes;
}
/**
* Transfer binary array to HEX string.
*/
public static String byte2hex(byte[] bytes)
{
// 第五步:把二进制转化为大写的十六进制
StringBuilder result = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
result.Append(bytes[i].ToString("X2"));
}
return result.ToString();
}
}
}