161 lines
5.8 KiB
C#
161 lines
5.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
|
||
namespace JoyD.Windows.CS
|
||
{
|
||
/// <summary>
|
||
/// 通用工具和方法
|
||
/// </summary>
|
||
public static class Utils
|
||
{
|
||
/// <summary>
|
||
/// 使用CRC16/XMODEM算法计算字节数组的CRC16校验值
|
||
/// </summary>
|
||
/// <param name="data">要计算CRC16的数据字节数组</param>
|
||
/// <param name="startIndex">计算的起始位置索引</param>
|
||
/// <param name="length">要计算的字节长度</param>
|
||
/// <returns>计算得到的CRC16校验值</returns>
|
||
public static ushort CalculateCRC16(byte[] data, int startIndex, int length)
|
||
{
|
||
ushort crc = 0;
|
||
int endIndex = startIndex + length;
|
||
for (int i = startIndex; i < endIndex && i < data.Length; i++)
|
||
{
|
||
crc ^= (ushort)(data[i] << 8);
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
if ((crc & 0x8000) != 0)
|
||
crc = (ushort)((crc << 1) ^ 0x1021);
|
||
else
|
||
crc <<= 1;
|
||
}
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 使用CRC32-MPEG2算法计算字节数组的CRC32校验值
|
||
/// </summary>
|
||
/// <param name="data">要计算CRC32的数据字节数组</param>
|
||
/// <returns>计算得到的CRC32校验值</returns>
|
||
public static uint CalculateCRC32(byte[] data)
|
||
{
|
||
return CalculateCRC32(data, 0xFFFFFFFF);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 支持增量计算的CRC32-MPEG2算法实现
|
||
/// </summary>
|
||
/// <param name="crc">上次CRC值(用于增量计算,首次为0xFFFFFFFF)</param>
|
||
/// <param name="data">要计算CRC32的数据字节数组</param>
|
||
/// <returns>计算得到的CRC32校验值</returns>
|
||
public static uint CalculateCRC32(byte[] data, uint crc = 0xFFFFFFFF)
|
||
{
|
||
uint polynomial = 0x04C11DB7;
|
||
|
||
for (int i = 0; i < data.Length; i++)
|
||
{
|
||
crc ^= (uint)data[i] << 24;
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
if ((crc & 0x80000000) != 0)
|
||
crc = (crc << 1) ^ polynomial;
|
||
else
|
||
crc <<= 1;
|
||
}
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过文件路径计算文件的CRC32校验值
|
||
/// </summary>
|
||
/// <param name="filePath">文件的完整路径</param>
|
||
/// <returns>计算得到的CRC32校验值</returns>
|
||
/// <exception cref="ArgumentException">当文件路径为空或无效时抛出</exception>
|
||
/// <exception cref="FileNotFoundException">当指定路径的文件不存在时抛出</exception>
|
||
/// <exception cref="IOException">当文件读取失败时抛出</exception>
|
||
public static uint CalculateFileCRC32(string filePath)
|
||
{
|
||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||
{
|
||
return CalculateCRC32(fs);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过已打开的文件流计算文件的CRC32校验值
|
||
/// </summary>
|
||
/// <param name="fs">已打开的文件流</param>
|
||
/// <returns>计算得到的CRC32校验值</returns>
|
||
/// <exception cref="ArgumentNullException">当文件流为null时抛出</exception>
|
||
/// <exception cref="IOException">当文件读取失败时抛出</exception>
|
||
public static uint CalculateCRC32(FileStream fs)
|
||
{
|
||
uint crc = 0xFFFFFFFF;
|
||
uint polynomial = 0x04C11DB7;
|
||
|
||
// 保存当前位置
|
||
long originalPosition = fs.Position;
|
||
|
||
try
|
||
{
|
||
// 重置到文件开头
|
||
fs.Seek(0, SeekOrigin.Begin);
|
||
|
||
byte[] buffer = new byte[4096];
|
||
int bytesRead;
|
||
|
||
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
|
||
{
|
||
for (int i = 0; i < bytesRead; i++)
|
||
{
|
||
crc ^= (uint)buffer[i] << 24;
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
if ((crc & 0x80000000) != 0)
|
||
crc = (crc << 1) ^ polynomial;
|
||
else
|
||
crc <<= 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
// 恢复到原始位置
|
||
fs.Seek(originalPosition, SeekOrigin.Begin);
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将字节数组转换为Base64编码的字符串
|
||
/// </summary>
|
||
/// <param name="data">要转换的字节数组</param>
|
||
/// <returns>Base64编码的字符串</returns>
|
||
/// <exception cref="ArgumentNullException">当输入数据为null时抛出</exception>
|
||
public static string ByteArrayToBase64(byte[] data)
|
||
{
|
||
return Convert.ToBase64String(data);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将Base64编码的字符串转换为字节数组
|
||
/// </summary>
|
||
/// <param name="base64">Base64编码的字符串</param>
|
||
/// <returns>转换后的字节数组</returns>
|
||
/// <exception cref="ArgumentNullException">当输入字符串为null时抛出</exception>
|
||
/// <exception cref="FormatException">当输入字符串不是有效的Base64格式时抛出</exception>
|
||
public static byte[] Base64ToByteArray(string base64)
|
||
{
|
||
return Convert.FromBase64String(base64);
|
||
}
|
||
}
|
||
}
|