Skip to content

Commit 02bc087

Browse files
committed
Добавлены методы CRC для FileInfo и тесты к ним
Добавлены синхронные и асинхронные методы вычисления CRC-8, CRC-16, CRC-32, CRC-64 для файлов в FileInfoExtensions с поддержкой настройки параметров. Для новых методов добавлены XML-комментарии. В проект тестов добавлен файл с модульными тестами, покрывающими различные сценарии использования CRC-методов. Исправлена опечатка в XML-комментарии к GetStringLines.
1 parent 7a6f25a commit 02bc087

File tree

2 files changed

+517
-1
lines changed

2 files changed

+517
-1
lines changed

MathCore/Extensions/IO/FileInfoExtensions.cs

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ public static byte[] ComputeMD5(this FileInfo file)
196196
return hash;
197197
}
198198

199+
/// <summary>Асинхронно вычисляет хеш-сумму MD5</summary>
200+
/// <param name="file">Файл, контрольную сумму которого надо вычислить</param>
201+
/// <param name="Cancel">Токен отмены операции</param>
202+
/// <returns>Массив байт контрольной суммы</returns>
199203
public static async Task<byte[]> ComputeMD5Async(this FileInfo file, CancellationToken Cancel = default)
200204
{
201205
#if NET8_0_OR_GREATER
@@ -207,6 +211,192 @@ public static async Task<byte[]> ComputeMD5Async(this FileInfo file, Cancellatio
207211
return hash;
208212
}
209213

214+
#if NET5_0_OR_GREATER
215+
/// <summary>Вычисляет CRC-8 для файла</summary>
216+
/// <param name="file">Файл для вычисления CRC-8</param>
217+
/// <param name="Polynomial">Полином для вычисления CRC-8 (по умолчанию 0x07)</param>
218+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0x00)</param>
219+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0x00)</param>
220+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
221+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
222+
/// <returns>Вычисленное значение CRC-8</returns>
223+
public static byte ComputeCRC8(
224+
this FileInfo file,
225+
byte Polynomial = 0x07,
226+
byte InitialValue = 0x00,
227+
byte XOROut = 0x00,
228+
bool RefIn = false,
229+
bool RefOut = false)
230+
{
231+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
232+
return CRC8.Hash(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut);
233+
}
234+
235+
/// <summary>Асинхронно вычисляет CRC-8 для файла</summary>
236+
/// <param name="file">Файл для вычисления CRC-8</param>
237+
/// <param name="Polynomial">Полином для вычисления CRC-8 (по умолчанию 0x07)</param>
238+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0x00)</param>
239+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0x00)</param>
240+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
241+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
242+
/// <param name="Cancel">Токен отмены операции</param>
243+
/// <returns>Вычисленное значение CRC-8</returns>
244+
public static async Task<byte> ComputeCRC8Async(
245+
this FileInfo file,
246+
byte Polynomial = 0x07,
247+
byte InitialValue = 0x00,
248+
byte XOROut = 0x00,
249+
bool RefIn = false,
250+
bool RefOut = false,
251+
CancellationToken Cancel = default)
252+
{
253+
#if NET8_0_OR_GREATER
254+
await using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
255+
#else
256+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
257+
#endif
258+
return await CRC8.HashAsync(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut, Cancel).ConfigureAwait(false);
259+
}
260+
261+
/// <summary>Вычисляет CRC-16 для файла</summary>
262+
/// <param name="file">Файл для вычисления CRC-16</param>
263+
/// <param name="Polynomial">Полином для вычисления CRC-16 (по умолчанию 0x1021 - XMODEM)</param>
264+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0x0000)</param>
265+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0x0000)</param>
266+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
267+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
268+
/// <returns>Вычисленное значение CRC-16</returns>
269+
public static ushort ComputeCRC16(
270+
this FileInfo file,
271+
ushort Polynomial = 0x1021,
272+
ushort InitialValue = 0x0000,
273+
ushort XOROut = 0x0000,
274+
bool RefIn = false,
275+
bool RefOut = false)
276+
{
277+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
278+
return CRC16.Hash(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut);
279+
}
280+
281+
/// <summary>Асинхронно вычисляет CRC-16 для файла</summary>
282+
/// <param name="file">Файл для вычисления CRC-16</param>
283+
/// <param name="Polynomial">Полином для вычисления CRC-16 (по умолчанию 0x1021 - XMODEM)</param>
284+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0x0000)</param>
285+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0x0000)</param>
286+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
287+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
288+
/// <param name="Cancel">Токен отмены операции</param>
289+
/// <returns>Вычисленное значение CRC-16</returns>
290+
public static async Task<ushort> ComputeCRC16Async(
291+
this FileInfo file,
292+
ushort Polynomial = 0x1021,
293+
ushort InitialValue = 0x0000,
294+
ushort XOROut = 0x0000,
295+
bool RefIn = false,
296+
bool RefOut = false,
297+
CancellationToken Cancel = default)
298+
{
299+
#if NET8_0_OR_GREATER
300+
await using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
301+
#else
302+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
303+
#endif
304+
return await CRC16.HashAsync(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut, Cancel).ConfigureAwait(false);
305+
}
306+
307+
/// <summary>Вычисляет CRC-32 для файла</summary>
308+
/// <param name="file">Файл для вычисления CRC-32</param>
309+
/// <param name="Polynomial">Полином для вычисления CRC-32 (по умолчанию 0x04C11DB7 - стандартный)</param>
310+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0xFFFFFFFF)</param>
311+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0xFFFFFFFF)</param>
312+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
313+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
314+
/// <returns>Вычисленное значение CRC-32</returns>
315+
public static uint ComputeCRC32(
316+
this FileInfo file,
317+
uint Polynomial = 0x04C11DB7,
318+
uint InitialValue = 0xFFFFFFFF,
319+
uint XOROut = 0xFFFFFFFF,
320+
bool RefIn = false,
321+
bool RefOut = false)
322+
{
323+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
324+
return CRC32.Hash(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut);
325+
}
326+
327+
/// <summary>Асинхронно вычисляет CRC-32 для файла</summary>
328+
/// <param name="file">Файл для вычисления CRC-32</param>
329+
/// <param name="Polynomial">Полином для вычисления CRC-32 (по умолчанию 0x04C11DB7 - стандартный)</param>
330+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0xFFFFFFFF)</param>
331+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0xFFFFFFFF)</param>
332+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
333+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
334+
/// <param name="Cancel">Токен отмены операции</param>
335+
/// <returns>Вычисленное значение CRC-32</returns>
336+
public static async Task<uint> ComputeCRC32Async(
337+
this FileInfo file,
338+
uint Polynomial = 0x04C11DB7,
339+
uint InitialValue = 0xFFFFFFFF,
340+
uint XOROut = 0xFFFFFFFF,
341+
bool RefIn = false,
342+
bool RefOut = false,
343+
CancellationToken Cancel = default)
344+
{
345+
#if NET8_0_OR_GREATER
346+
await using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
347+
#else
348+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
349+
#endif
350+
return await CRC32.HashAsync(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut, Cancel).ConfigureAwait(false);
351+
}
352+
353+
/// <summary>Вычисляет CRC-64 для файла</summary>
354+
/// <param name="file">Файл для вычисления CRC-64</param>
355+
/// <param name="Polynomial">Полином для вычисления CRC-64 (по умолчанию 0x000000000000001B - ISO3309)</param>
356+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0x0000000000000000)</param>
357+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0x0000000000000000)</param>
358+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
359+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
360+
/// <returns>Вычисленное значение CRC-64</returns>
361+
public static ulong ComputeCRC64(
362+
this FileInfo file,
363+
ulong Polynomial = 0x000000000000001B,
364+
ulong InitialValue = 0x0000000000000000,
365+
ulong XOROut = 0x0000000000000000,
366+
bool RefIn = false,
367+
bool RefOut = false)
368+
{
369+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
370+
return CRC64.Hash(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut);
371+
}
372+
373+
/// <summary>Асинхронно вычисляет CRC-64 для файла</summary>
374+
/// <param name="file">Файл для вычисления CRC-64</param>
375+
/// <param name="Polynomial">Полином для вычисления CRC-64 (по умолчанию 0x000000000000001B - ISO3309)</param>
376+
/// <param name="InitialValue">Начальное значение CRC (по умолчанию 0x0000000000000000)</param>
377+
/// <param name="XOROut">Значение для XOR с окончательным CRC (по умолчанию 0x0000000000000000)</param>
378+
/// <param name="RefIn">Отражение входных байтов (по умолчанию false)</param>
379+
/// <param name="RefOut">Отражение выходного значения (по умолчанию false)</param>
380+
/// <param name="Cancel">Токен отмены операции</param>
381+
/// <returns>Вычисленное значение CRC-64</returns>
382+
public static async Task<ulong> ComputeCRC64Async(
383+
this FileInfo file,
384+
ulong Polynomial = 0x000000000000001B,
385+
ulong InitialValue = 0x0000000000000000,
386+
ulong XOROut = 0x0000000000000000,
387+
bool RefIn = false,
388+
bool RefOut = false,
389+
CancellationToken Cancel = default)
390+
{
391+
#if NET8_0_OR_GREATER
392+
await using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
393+
#else
394+
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
395+
#endif
396+
return await CRC64.HashAsync(stream, Polynomial, InitialValue, RefIn, RefOut, XOROut, Cancel).ConfigureAwait(false);
397+
}
398+
#endif
399+
210400
public static IEnumerable<byte> ReadBytes(this FileInfo file)
211401
{
212402
using var stream = file.NotNull().ThrowIfNotFound().OpenRead();
@@ -374,7 +564,7 @@ public static void WriteAllBytes(
374564
public static Process? Execute(this FileInfo File, string Args = "", bool UseShellExecute = true) => Process.Start(new ProcessStartInfo(UseShellExecute ? File.ToString() : File.FullName, Args) { UseShellExecute = UseShellExecute });
375565

376566
/// <summary>Получить перечисление строк файла без его загрузки в память целиком</summary>
377-
/// <param name="File">Файл, строки которого требуется прочитать</param>
567+
/// <param name="File">Файл, строки которых требуется прочитать</param>
378568
/// <returns>Перечисление строк файла</returns>
379569
public static IEnumerable<string?> GetStringLines(this FileInfo File)
380570
{

0 commit comments

Comments
 (0)