Cosmos/source/Cosmos.IL2CPU/ElfHash.cs
2014-11-26 01:13:58 +00:00

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)
};
}
}
}