mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +00:00
145 lines
3.6 KiB
C#
145 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace Cosmos.IL2CPU
|
|
{
|
|
|
|
|
|
public class Elf32 : HashAlgorithm
|
|
{
|
|
private UInt32 hash;
|
|
|
|
public Elf32()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
public override void Initialize()
|
|
{
|
|
hash = 0;
|
|
}
|
|
|
|
protected override void HashCore(byte[] buffer, int start, int length)
|
|
{
|
|
hash = CalculateHash(hash, buffer, start, length);
|
|
}
|
|
|
|
protected override byte[] HashFinal()
|
|
{
|
|
byte[] hashBuffer = UInt32ToBigEndianBytes(hash);
|
|
this.HashValue = hashBuffer;
|
|
return hashBuffer;
|
|
}
|
|
|
|
public override int HashSize
|
|
{
|
|
get { return 32; }
|
|
}
|
|
|
|
public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
|
|
{
|
|
return CalculateHash(seed, buffer, 0, buffer.Length);
|
|
}
|
|
|
|
private static UInt32 CalculateHash(UInt32 seed, byte[] buffer, int start, int size)
|
|
{
|
|
UInt32 hash = seed;
|
|
|
|
for (int i = start; i < size; i++)
|
|
unchecked
|
|
{
|
|
hash = (hash << 4) + buffer[i];
|
|
UInt32 work = (hash & 0xf0000000);
|
|
if (work != 0)
|
|
hash ^= (work >> 24);
|
|
hash &= ~work;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
private byte[] UInt32ToBigEndianBytes(UInt32 x)
|
|
{
|
|
return new byte[] {
|
|
(byte)((x >> 24) & 0xff),
|
|
(byte)((x >> 16) & 0xff),
|
|
(byte)((x >> 8) & 0xff),
|
|
(byte)(x & 0xff)
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public class Elf64 : HashAlgorithm
|
|
{
|
|
private UInt64 hash;
|
|
|
|
public Elf64()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
public override void Initialize()
|
|
{
|
|
hash = 0;
|
|
}
|
|
|
|
protected override void HashCore(byte[] buffer, int start, int length)
|
|
{
|
|
hash = CalculateHash(hash, buffer, start, length);
|
|
}
|
|
|
|
protected override byte[] HashFinal()
|
|
{
|
|
byte[] hashBuffer = UInt64ToBigEndianBytes(hash);
|
|
this.HashValue = hashBuffer;
|
|
return hashBuffer;
|
|
}
|
|
|
|
public override int HashSize
|
|
{
|
|
get { return 32; }
|
|
}
|
|
|
|
public static UInt64 Compute(UInt64 polynomial, UInt64 seed, byte[] buffer)
|
|
{
|
|
return CalculateHash(seed, buffer, 0, buffer.Length);
|
|
}
|
|
|
|
//not sure if this is valid.
|
|
private static UInt64 CalculateHash(UInt64 seed, byte[] buffer, int start, int size)
|
|
{
|
|
UInt64 hash = seed;
|
|
|
|
for (int i = start; i < size; i++)
|
|
unchecked
|
|
{
|
|
hash = (hash << 4) + buffer[i];
|
|
UInt64 work = (hash & 0xf000000000000000L);
|
|
if (work != 0)
|
|
hash ^= (work >> 56);
|
|
hash &= ~work;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
private byte[] UInt64ToBigEndianBytes(UInt64 x)
|
|
{
|
|
return new byte[]
|
|
{
|
|
(byte)((x >> 56) & 0xff),
|
|
(byte)((x >> 48) & 0xff),
|
|
(byte)((x >> 40) & 0xff),
|
|
(byte)((x >> 32) & 0xff),
|
|
(byte)((x >> 24) & 0xff),
|
|
(byte)((x >> 16) & 0xff),
|
|
(byte)((x >> 8) & 0xff),
|
|
(byte)(x & 0xff)
|
|
};
|
|
}
|
|
}
|
|
|
|
}
|