Repository navigation
Expand file tree
/
Copy pathcommon.cs
More file actions
178 lines (154 loc) · 6.28 KB
/
Copy pathcommon.cs
File metadata and controls
178 lines (154 loc) · 6.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Web;
namespace QQLogin
{
public class common
{
#region URL参数相关方法
/// <summary>
/// 将 URL 参数按 ASCII 码排序(区分大小写)
/// </summary>
/// <param name="queryString">URL 参数字符串(格式 key1=value1&key2=value2)</param>
/// <param name="encodeValue">是否对值进行 URL 编码(默认不编码)</param>
/// <returns>按 ASCII 排序后的参数字符串</returns>
public static string SortUrlParameters(string queryString, bool encodeValue = false)
{
if (string.IsNullOrWhiteSpace(queryString))
return string.Empty;
// 拆分成键值对
var parameters = new Dictionary<string, string>();
var keyValuePairs = queryString.Split('&', StringSplitOptions.RemoveEmptyEntries);
foreach (var pair in keyValuePairs)
{
var kv = pair.Split('=', 2);
if (kv.Length == 0) continue;
string key = kv[0];
string value = kv.Length > 1 ? kv[1] : "";
// 仅保留第一个参数值(可选)
if (!parameters.ContainsKey(key))
{
// 选择性进行 URL 编码
value = encodeValue ? WebUtility.UrlEncode(value) : value;
parameters.Add(key, value);
}
}
// 按 ASCII 顺序排序(区分大小写)
var sorted = parameters
.OrderBy(kv => kv.Key, StringComparer.Ordinal) // ASCII 顺序
.ToArray();
// 构建排序后的字符串
var sb = new StringBuilder();
foreach (var (key, value) in sorted)
{
if (sb.Length > 0) sb.Append('&');
sb.Append(key).Append('=').Append(value);
}
return sb.ToString();
}
/// <summary>
/// 对整个 URL 进行参数排序(保留协议和域名部分)
/// </summary>
public static string SortUrlParametersInFullUrl(string url, bool encodeValues = false)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
throw new ArgumentException("无效的 URL");
// 分离基本 URL 和参数部分
var baseUri = uri.GetLeftPart(UriPartial.Path);
var query = uri.Query.TrimStart('?');
// 处理片段部分(锚点)
string fragment = string.IsNullOrEmpty(uri.Fragment)
? "" : "#" + uri.Fragment.TrimStart('#');
// 排序参数
string sortedQuery = SortUrlParameters(query, encodeValues);
return baseUri + (string.IsNullOrEmpty(sortedQuery)
? "" : "?" + sortedQuery) + fragment;
}
/// <summary>
/// 将查询字符串转换为字典
/// </summary>
/// <param name="queryString">查询字符串,格式为key1=value1&key2=value2</param>
/// <returns>包含键值对的字典</returns>
public static Dictionary<string, string> QueryStringToDictionary(string queryString)
{
var parameters = new Dictionary<string, string>();
if (string.IsNullOrWhiteSpace(queryString))
return parameters;
// 移除可能的问号前缀
if (queryString.StartsWith('?'))
queryString = queryString.Substring(1);
var keyValuePairs = queryString.Split('&', StringSplitOptions.RemoveEmptyEntries);
foreach (var pair in keyValuePairs)
{
var kv = pair.Split('=', 2);
if (kv.Length == 0) continue;
string key = kv[0];
string value = kv.Length > 1 ? kv[1] : "";
// URL解码值
value = WebUtility.UrlDecode(value);
// 如果键已存在,则覆盖
if (parameters.ContainsKey(key))
parameters[key] = value;
else
parameters.Add(key, value);
}
return parameters;
}
/// <summary>
/// 将字典转换为查询字符串
/// </summary>
/// <param name="dictionary">包含键值对的字典</param>
/// <param name="encodeValue">是否对值进行URL编码(默认编码)</param>
/// <returns>格式化的查询字符串,格式为key1=value1&key2=value2</returns>
public static string DictionaryToQueryString(Dictionary<string, string> dictionary, bool encodeValue = true)
{
if (dictionary == null || dictionary.Count == 0)
return string.Empty;
var sb = new StringBuilder();
foreach (var kvp in dictionary)
{
if (sb.Length > 0)
sb.Append('&');
sb.Append(kvp.Key);
sb.Append('=');
// 根据参数决定是否对值进行URL编码
string value = encodeValue ? WebUtility.UrlEncode(kvp.Value ?? "") : (kvp.Value ?? "");
sb.Append(value);
}
return sb.ToString();
}
#endregion
private static readonly Random _random = new Random();
/// <summary>
/// 生成随机时间戳
/// </summary>
public static string refreshCode()
{
double refreshCode = _random.NextDouble();
return $"{refreshCode:F16}";
}
/// <summary>
/// 计算QQ的g_tk值
/// </summary>
/// <param name="skey">Cookie中的skey值</param>
/// <returns>计算后的g_tk值</returns>
public static int Get_G_tk(string skey)
{
int Base = 5381;
int length = skey.Length;
for (int count = 0; count < length; count++)
{
Base = Base + (Base << 5) + (int)skey[count];
}
// 保持32位整数
return Base & 2147483647;
}
}
}