-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExtensionMethods.cs
165 lines (159 loc) · 6.17 KB
/
ExtensionMethods.cs
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
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace AntiOnlineDecompression
{
public static class ExtensionMethods
{
private static readonly SHA256 SHA256 = SHA256.Create();
/// <summary>
/// 计算SHA256Hash
/// </summary>
/// <param name="inputStream">数据流</param>
/// <returns>SHA256Hash字节数组</returns>
public static async Task<byte[]> SHA256HashAsync(this Stream inputStream)
{
long save = inputStream.Position;
byte[] SHA256Hash = await SHA256.ComputeHashAsync(inputStream);
inputStream.Seek(save, SeekOrigin.Begin);
return SHA256Hash;
}
/// <summary>
/// 字节数组转16进制字符串
/// </summary>
/// <param name="byteDatas"></param>
/// <returns></returns>
public static string BytesToHexString(this byte[] byteDatas)
{
StringBuilder builder = new();
for (int i = 0; i < byteDatas.Length; i++)
{
builder.Append(string.Format("{0:X2}", byteDatas[i]));
}
return builder.ToString();
}
/// <summary>
/// 字节数组是否相等
/// </summary>
/// <param name="byteDatas"></param>
/// <returns></returns>
public static bool SequenceCompare(this byte[]? a, byte[]? b)
{
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
if (a.Length != b.Length) return false;
return a.SequenceEqual(b);
}
public static string TimeFormat(this TimeSpan timeSpan)
{
return string.Format("{0}{1}{2}{3}{4}",
timeSpan.Days > 0 ? $"{timeSpan.Days}天" : "",
timeSpan.Hours > 0 ? $"{timeSpan.Hours}小时" : "",
timeSpan.Minutes > 0 ? $"{timeSpan.Minutes}分钟" : "",
timeSpan.Seconds > 0 ? $"{timeSpan.Seconds}秒" : "",
timeSpan.Milliseconds > 0 ? $"{timeSpan.Milliseconds}毫秒" : "低于1毫秒").Trim();
}
public static async Task VerifyHash(this Stream stream, byte[] hash)
{
Console.WriteLine("校验中...");
Stopwatch stopwatch = new();
stopwatch.Restart();
byte[] streamHash = await stream.SHA256HashAsync();
stopwatch.Stop();
if (!streamHash.SequenceCompare(hash))
{
throw new Exception($"校验失败!耗时{stopwatch.Elapsed.TimeFormat()}{Environment.NewLine}(A)SHA256:{streamHash.BytesToHexString()}{Environment.NewLine}(B)SHA256:{hash.BytesToHexString()}");
}
Console.WriteLine($"校验完成。耗时{stopwatch.Elapsed.TimeFormat()}");
}
public static byte[] RandomBytes(int length)
{
return RandomNumberGenerator.GetBytes(length);
}
public static byte[] StreamRead(this Stream stream, long a, long b)
{
if ((b - a) > int.MaxValue || stream.Length < 4) throw new OverflowException();
long save = stream.Position;
byte[] ReadData;
stream.Seek(a, SeekOrigin.Begin);
ReadData = stream.StreamRead((int)(b - a));
stream.Seek(save, SeekOrigin.Begin);
return ReadData;
}
public static byte[] StreamRead(this Stream stream, int length)
{
byte[] buffer = new byte[length];
int offset = 0;
int count = buffer.Length;
int bytesRead;
while (count > 0 && (bytesRead = stream.Read(buffer, offset, count)) > 0)
{
offset += bytesRead; // 增加偏移量
count -= bytesRead; // 减少剩余字节数
}
return buffer;
}
public static byte[] StringToBytes(string value)
{
return Encoding.UTF8.GetBytes(value);
}
public static byte[] IntToBytes(int value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
return bytes;
}
public static string BytesToString(this byte[] value)
{
return Encoding.UTF8.GetString(value);
}
public static int BytesToInt(this byte[] value)
{
if (BitConverter.IsLittleEndian)
{
Array.Reverse(value);
}
return BitConverter.ToInt32(value);
}
public static void CoverWrite(string s)
{
int oldX = Console.CursorLeft;
int oldY = Console.CursorTop;
Console.Write(s);
Console.SetCursorPosition(oldX, oldY);
}
public static async Task Encrypto(this Stream data, Stream encrypted, byte[] key, byte[] iv)
{
int bytesRead;
byte[] buffer = new byte[1024 * 1024 * 4];
ChaCha20 Encrypto = new(key, iv, 0);
while ((bytesRead = await data.ReadAsync(buffer)) != 0)
{
byte[] encryptedBuffer = new byte[bytesRead];
Encrypto.EncryptBytes(encryptedBuffer, buffer.AsMemory(0, bytesRead).ToArray());
await encrypted.WriteAsync(encryptedBuffer);
CoverWrite($" {(data.Position / (double)data.Length) * 100:f2}%");
}
}
public static async Task Decrypto(this Stream encrypted, Stream data, byte[] key, byte[] iv)
{
int bytesRead;
byte[] buffer = new byte[1024 * 1024 * 4];
ChaCha20 Decrypto = new(key, iv, 0);
while ((bytesRead = await encrypted.ReadAsync(buffer)) != 0)
{
byte[] decryptedBuffer = new byte[bytesRead];
Decrypto.DecryptBytes(decryptedBuffer, buffer.AsMemory(0, bytesRead).ToArray());
await data.WriteAsync(decryptedBuffer);
CoverWrite($" {(encrypted.Position / (double)encrypted.Length) * 100:f2}%");
}
}
}
}