Calculating Elf-32 in C# and .NET

GitHub has the latest version of Elf32

Because you can never have enough hashing algorithms at your disposal this one is compatible with the elf_hash function that forms part of the Executable and Linkable Format.

using System;
using System.Security.Cryptography;

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

[)amien

4 responses

  1. Avatar for bitRAKE

    if (work != 0) hash ^= (work >> 24);

    Makes me wonder if it costs more to avoid this than to just do it anyway when work==0? As it has no effect on hash when work==0, and I'm almost certain it'll always be slower to branch.

    bitRAKE 4 December 2007
  2. Avatar for Damien Guard

    Yeah you are probably right. I will revise it.

    Damien Guard 9 January 2008
  3. Avatar for QuangCanh

    hi Damien,

    Can this algorithm duplicate?

    private static uint GetELF(string str)
    {
           int i;
           uint x;
           uint result = 10;
           byte[] b = ASCIIEncoding.Unicode.GetBytes(str);
           for (i = 0; i < b.Length; i++)
           {
                  unchecked
                  {
                         result = (result <> 24);
                         result &amp;= ~x;
                         }
                  }
           return result;
    }
    

    hash code of "mj9d" and "oj9f" is the same.

    regards, Canh

    QuangCanh 20 October 2008
  4. Avatar for Damien Guard

    All hash functions can return the same hash code for a different input sets. If they didn't they would instead be very effective compression algorithms.

    Damien Guard 20 October 2008