2021-04-08 20:09:59 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
namespace libx
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public static class Utilitys
|
|
|
|
|
{
|
|
|
|
|
private static readonly MD5 md5 = MD5.Create();
|
|
|
|
|
private static readonly CRC32 crc32 = new CRC32();
|
|
|
|
|
|
|
|
|
|
public static string GetMD5Hash(string input)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return ToHash(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetMD5Hash(Stream input)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] data = md5.ComputeHash(input);
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return ToHash(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool VerifyMd5Hash(string input, string hash)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return 0 == comparer.Compare(input, hash);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetCRC32Hash(Stream input)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] data = crc32.ComputeHash(input);
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return ToHash(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static uint GetCrc(byte[] bytes)
|
|
|
|
|
{
|
|
|
|
|
return CRC32.Compute(bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetCRC32Hash(byte[] bytes)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] data = crc32.ComputeHash(bytes);
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return ToHash(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static string ToHash(byte[] data)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
foreach (byte t in data)
|
2021-04-08 20:09:59 +08:00
|
|
|
|
sb.Append(t.ToString("x2"));
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetCRC32Hash(string input)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] data = crc32.ComputeHash(Encoding.UTF8.GetBytes(input));
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return ToHash(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool VerifyCrc32Hash(string input, string hash)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
|
2021-04-08 20:09:59 +08:00
|
|
|
|
return 0 == comparer.Compare(input, hash);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sealed class CRC32 : HashAlgorithm
|
|
|
|
|
{
|
|
|
|
|
private const UInt32 DefaultPolynomial = 0xedb88320u;
|
|
|
|
|
private const UInt32 DefaultSeed = 0xffffffffu;
|
|
|
|
|
|
|
|
|
|
static UInt32[] _defaultTable;
|
|
|
|
|
|
|
|
|
|
readonly UInt32 _seed;
|
|
|
|
|
readonly UInt32[] _table;
|
|
|
|
|
UInt32 _hash;
|
|
|
|
|
|
|
|
|
|
public CRC32()
|
|
|
|
|
: this(DefaultPolynomial, DefaultSeed)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public CRC32(UInt32 polynomial, UInt32 seed)
|
|
|
|
|
{
|
|
|
|
|
if (!BitConverter.IsLittleEndian)
|
|
|
|
|
throw new PlatformNotSupportedException("Not supported on Big Endian processors");
|
|
|
|
|
|
|
|
|
|
_table = InitializeTable(polynomial);
|
|
|
|
|
this._seed = _hash = seed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
{
|
|
|
|
|
_hash = _seed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void HashCore(byte[] array, int ibStart, int cbSize)
|
|
|
|
|
{
|
|
|
|
|
_hash = CalculateHash(_table, _hash, array, ibStart, cbSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override byte[] HashFinal()
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] hashBuffer = UInt32ToBigEndianBytes(~_hash);
|
2021-04-08 20:09:59 +08:00
|
|
|
|
HashValue = hashBuffer;
|
|
|
|
|
return hashBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int HashSize
|
|
|
|
|
{
|
|
|
|
|
get { return 32; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static UInt32 Compute(byte[] buffer)
|
|
|
|
|
{
|
|
|
|
|
return Compute(DefaultSeed, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static UInt32 Compute(UInt32 seed, byte[] buffer)
|
|
|
|
|
{
|
|
|
|
|
return Compute(DefaultPolynomial, seed, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
|
|
|
|
|
{
|
|
|
|
|
return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static UInt32[] InitializeTable(UInt32 polynomial)
|
|
|
|
|
{
|
|
|
|
|
if (polynomial == DefaultPolynomial && _defaultTable != null)
|
|
|
|
|
return _defaultTable;
|
|
|
|
|
|
2021-04-11 19:50:39 +08:00
|
|
|
|
uint[] createTable = new UInt32[256];
|
|
|
|
|
for (int i = 0; i < 256; i++)
|
2021-04-08 20:09:59 +08:00
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
uint entry = (UInt32) i;
|
|
|
|
|
for (int j = 0; j < 8; j++)
|
2021-04-08 20:09:59 +08:00
|
|
|
|
if ((entry & 1) == 1)
|
|
|
|
|
entry = (entry >> 1) ^ polynomial;
|
|
|
|
|
else
|
|
|
|
|
entry >>= 1;
|
|
|
|
|
createTable[i] = entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (polynomial == DefaultPolynomial)
|
|
|
|
|
_defaultTable = createTable;
|
|
|
|
|
|
|
|
|
|
return createTable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList<byte> buffer, int start, int size)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
uint hash = seed;
|
|
|
|
|
for (int i = start; i < start + size; i++)
|
2021-04-08 20:09:59 +08:00
|
|
|
|
hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff];
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static byte[] UInt32ToBigEndianBytes(UInt32 uint32)
|
|
|
|
|
{
|
2021-04-11 19:50:39 +08:00
|
|
|
|
byte[] result = BitConverter.GetBytes(uint32);
|
2021-04-08 20:09:59 +08:00
|
|
|
|
|
|
|
|
|
if (BitConverter.IsLittleEndian)
|
|
|
|
|
Array.Reverse(result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|