-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Revert "Revert "Shorten UTD marker file (#9387)" except Microsoft.Common.Curr…" This reverts commit 5af9301. * Make FNV hash compatible across endianness * Add StableStringHash intrinsic function overloads
- Loading branch information
1 parent
d68cc3a
commit 23f7752
Showing
5 changed files
with
236 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Runtime.InteropServices; | ||
using System; | ||
|
||
namespace Microsoft.NET.StringTools | ||
{ | ||
/// <summary> | ||
/// Fowler/Noll/Vo hashing. | ||
/// </summary> | ||
public static class FowlerNollVo1aHash | ||
{ | ||
// Fowler/Noll/Vo hashing. | ||
// http://www.isthe.com/chongo/tech/comp/fnv/ | ||
// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash | ||
// http://www.isthe.com/chongo/src/fnv/hash_32a.c | ||
|
||
// 32 bit FNV prime and offset basis for FNV-1a. | ||
private const uint fnvPrimeA32Bit = 16777619; | ||
private const uint fnvOffsetBasisA32Bit = 2166136261; | ||
|
||
// 64 bit FNV prime and offset basis for FNV-1a. | ||
private const long fnvPrimeA64Bit = 1099511628211; | ||
private const long fnvOffsetBasisA64Bit = unchecked((long)14695981039346656037); | ||
|
||
/// <summary> | ||
/// Computes 32 bit Fowler/Noll/Vo-1a hash of a string (regardless of encoding). | ||
/// </summary> | ||
/// <param name="text">String to be hashed.</param> | ||
/// <returns>32 bit signed hash</returns> | ||
public static int ComputeHash32(string text) | ||
{ | ||
uint hash = fnvOffsetBasisA32Bit; | ||
|
||
unchecked | ||
{ | ||
for (int i = 0; i < text.Length; i++) | ||
{ | ||
char ch = text[i]; | ||
byte b = (byte)ch; | ||
hash ^= b; | ||
hash *= fnvPrimeA32Bit; | ||
|
||
b = (byte)(ch >> 8); | ||
hash ^= b; | ||
hash *= fnvPrimeA32Bit; | ||
} | ||
} | ||
|
||
return unchecked((int)hash); | ||
} | ||
|
||
/// <summary> | ||
/// Computes 32 bit Fowler/Noll/Vo-1a inspired hash of a string. | ||
/// The hashing algorithm process the data by the whole 16bit chars, instead of by bytes. | ||
/// this speeds up the hashing process almost by 2x, while not significantly increasing collisions rate. | ||
/// Analysis: https://github.com/KirillOsenkov/MSBuildStructuredLog/wiki/String-Hashing#faster-fnv-1a | ||
/// </summary> | ||
/// <param name="text">String to be hashed.</param> | ||
/// <returns>32 bit unsigned hash</returns> | ||
public static int ComputeHash32Fast(string text) | ||
{ | ||
uint hash = fnvOffsetBasisA32Bit; | ||
|
||
unchecked | ||
{ | ||
for (int i = 0; i < text.Length; i++) | ||
{ | ||
char ch = text[i]; | ||
|
||
hash = (hash ^ ch) * fnvPrimeA32Bit; | ||
} | ||
} | ||
|
||
return unchecked((int)hash); | ||
} | ||
|
||
/// <summary> | ||
/// Computes 64 bit Fowler/Noll/Vo-1a inspired hash of a string. | ||
/// The hashing algorithm process the data by the whole 16bit chars, instead of by bytes. | ||
/// this speeds up the hashing process almost by 2x, while not significantly increasing collisions rate. | ||
/// Analysis: https://github.com/KirillOsenkov/MSBuildStructuredLog/wiki/String-Hashing#faster-fnv-1a | ||
/// </summary> | ||
/// <param name="text">String to be hashed.</param> | ||
/// <returns>64 bit unsigned hash</returns> | ||
public static long ComputeHash64Fast(string text) | ||
{ | ||
long hash = fnvOffsetBasisA64Bit; | ||
|
||
unchecked | ||
{ | ||
for (int i = 0; i < text.Length; i++) | ||
{ | ||
char ch = text[i]; | ||
|
||
hash = (hash ^ ch) * fnvPrimeA64Bit; | ||
} | ||
} | ||
|
||
return hash; | ||
} | ||
|
||
/// <summary> | ||
/// Computes 64 bit Fowler/Noll/Vo-1a hash of a string (regardless of encoding). | ||
/// </summary> | ||
/// <param name="text">String to be hashed.</param> | ||
/// <returns>64 bit unsigned hash</returns> | ||
public static long ComputeHash64(string text) | ||
{ | ||
long hash = fnvOffsetBasisA64Bit; | ||
|
||
unchecked | ||
{ | ||
for (int i = 0; i < text.Length; i++) | ||
{ | ||
char ch = text[i]; | ||
byte b = (byte)ch; | ||
hash ^= b; | ||
hash *= fnvPrimeA64Bit; | ||
|
||
b = (byte)(ch >> 8); | ||
hash ^= b; | ||
hash *= fnvPrimeA64Bit; | ||
} | ||
} | ||
|
||
return hash; | ||
} | ||
|
||
/// <summary> | ||
/// Combines two 64 bit hashes generated by <see cref="FowlerNollVo1aHash"/> class into one. | ||
/// </summary> | ||
/// <param name="left">First hash value to be combined.</param> | ||
/// <param name="right">Second hash value to be combined.</param> | ||
/// <returns></returns> | ||
public static long Combine64(long left, long right) | ||
{ | ||
unchecked | ||
{ | ||
return (left ^ right) * fnvPrimeA64Bit; | ||
} | ||
} | ||
} | ||
} |