//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 loyalsoft. All rights reserved.
// Homepage: http://www.game7000.com/
// Feedback: http://www.game7000.com/
//------------------------------------------------------------
using System;
using System.IO;
namespace GameFramework
{
public static partial class Utility
{
///
/// 校验相关的实用函数。
///
public static partial class Verifier
{
private const int CachedBytesLength = 0x1000;
private static readonly byte[] s_CachedBytes = new byte[CachedBytesLength];
private static readonly Crc32 s_Algorithm = new Crc32();
///
/// 计算二进制流的 CRC32。
///
/// 指定的二进制流。
/// 计算后的 CRC32。
public static int GetCrc32(byte[] bytes)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
return GetCrc32(bytes, 0, bytes.Length);
}
///
/// 计算二进制流的 CRC32。
///
/// 指定的二进制流。
/// 二进制流的偏移。
/// 二进制流的长度。
/// 计算后的 CRC32。
public static int GetCrc32(byte[] bytes, int offset, int length)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
if (offset < 0 || length < 0 || offset + length > bytes.Length)
{
throw new GameFrameworkException("Offset or length is invalid.");
}
s_Algorithm.HashCore(bytes, offset, length);
int result = (int)s_Algorithm.HashFinal();
s_Algorithm.Initialize();
return result;
}
///
/// 计算二进制流的 CRC32。
///
/// 指定的二进制流。
/// 计算后的 CRC32。
public static int GetCrc32(Stream stream)
{
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
while (true)
{
int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength);
if (bytesRead > 0)
{
s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead);
}
else
{
break;
}
}
int result = (int)s_Algorithm.HashFinal();
s_Algorithm.Initialize();
Array.Clear(s_CachedBytes, 0, CachedBytesLength);
return result;
}
///
/// 获取 CRC32 数值的二进制数组。
///
/// CRC32 数值。
/// CRC32 数值的二进制数组。
public static byte[] GetCrc32Bytes(int crc32)
{
return new byte[] { (byte)((crc32 >> 24) & 0xff), (byte)((crc32 >> 16) & 0xff), (byte)((crc32 >> 8) & 0xff), (byte)(crc32 & 0xff) };
}
///
/// 获取 CRC32 数值的二进制数组。
///
/// CRC32 数值。
/// 要存放结果的数组。
public static void GetCrc32Bytes(int crc32, byte[] bytes)
{
GetCrc32Bytes(crc32, bytes, 0);
}
///
/// 获取 CRC32 数值的二进制数组。
///
/// CRC32 数值。
/// 要存放结果的数组。
/// CRC32 数值的二进制数组在结果数组内的起始位置。
public static void GetCrc32Bytes(int crc32, byte[] bytes, int offset)
{
if (bytes == null)
{
throw new GameFrameworkException("Result is invalid.");
}
if (offset < 0 || offset + 4 > bytes.Length)
{
throw new GameFrameworkException("Offset or length is invalid.");
}
bytes[offset] = (byte)((crc32 >> 24) & 0xff);
bytes[offset + 1] = (byte)((crc32 >> 16) & 0xff);
bytes[offset + 2] = (byte)((crc32 >> 8) & 0xff);
bytes[offset + 3] = (byte)(crc32 & 0xff);
}
internal static int GetCrc32(Stream stream, byte[] code, int length)
{
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
if (code == null)
{
throw new GameFrameworkException("Code is invalid.");
}
int codeLength = code.Length;
if (codeLength <= 0)
{
throw new GameFrameworkException("Code length is invalid.");
}
int bytesLength = (int)stream.Length;
if (length < 0 || length > bytesLength)
{
length = bytesLength;
}
int codeIndex = 0;
while (true)
{
int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength);
if (bytesRead > 0)
{
if (length > 0)
{
for (int i = 0; i < bytesRead && i < length; i++)
{
s_CachedBytes[i] ^= code[codeIndex++];
codeIndex %= codeLength;
}
length -= bytesRead;
}
s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead);
}
else
{
break;
}
}
int result = (int)s_Algorithm.HashFinal();
s_Algorithm.Initialize();
Array.Clear(s_CachedBytes, 0, CachedBytesLength);
return result;
}
}
}
}