Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Implemented FnvHash
  • Loading branch information
jamescrosswell committed Feb 10, 2025
commit 02593ece9d14947cc3e7206eeff55b93c807112c
43 changes: 43 additions & 0 deletions src/Sentry/Internal/FnvHash.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace Sentry.Internal;

/// <summary>
/// FNV is a non-cryptographic hash.
///
/// See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_hash_parameters
/// </summary>
/// <remarks>
/// We use a struct to avoid heap allocations.
/// </remarks>
internal struct FnvHash
{
public FnvHash()
{
}

private const int Offset = unchecked((int)2166136261);
private const int Prime = 16777619;

private int HashCode { get; set; } = Offset;

private void Combine(byte data)
{
unchecked
{
HashCode ^= data;
HashCode *= Prime;
}
}

private static int ComputeHash(byte[] data)
{
var result = new FnvHash();
foreach (var b in data)
{
result.Combine(b);
}

return result.HashCode;
}

public static int ComputeHash(string data) => ComputeHash(Encoding.UTF8.GetBytes(data));
}
24 changes: 24 additions & 0 deletions test/Sentry.Tests/Internals/FnvHashTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Sentry.Tests.Internals;

public class FnvHashTests
{
[Theory]
[InlineData("", 2_166_136_261)]
[InlineData("h", 3_977_000_791)]
[InlineData("he", 1_547_363_254)]
[InlineData("hel", 179_613_742)]
[InlineData("hell", 477_198_310)]
[InlineData("hello", 1_335_831_723)]
[InlineData("hello ", 3_801_292_497)]
[InlineData("hello w", 1_402_552_146)]
[InlineData("hello wo", 3_611_200_775)]
[InlineData("hello wor", 1_282_977_583)]
[InlineData("hello worl", 2_767_971_961)]
[InlineData("hello world", 3_582_672_807)]
public void ComputeHash_WithString_ReturnsExpected(string input, uint expected)
{
var actual = FnvHash.ComputeHash(input);

Assert.Equal(unchecked((int)expected), actual);
}
}
Loading