Skip to content

Commit 95b79ba

Browse files
Improved character hashing extension.
1 parent 873cf04 commit 95b79ba

2 files changed

Lines changed: 19 additions & 9 deletions

File tree

Source/Extensions._.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -435,23 +435,33 @@ public static string Supplant<T>(this string format, T[]? values, CultureInfo? c
435435
};
436436

437437
/// <summary>
438-
/// A hashing algorithm that is nearly as fast as the default string.GetHashCode()
438+
/// A hashing algorithm that is can be faster than the default string.GetHashCode()
439439
/// but can be used for any sequence of characters reliably.
440440
/// </summary>
441441
/// <remarks>
442-
/// Setting the <paramref name="maxChars"/> parameter to a lower number
443-
/// will dramatically increase the speed as more characters requires more iterations.
442+
/// Setting the <paramref name="maxChars"/> parameter to a low number
443+
/// will dramatically increase the speed as more characters requires more iterations
444+
/// at the expense of accuracy and possible collisions.
444445
/// </remarks>
445446
public static int GetHashCodeFromChars(this ReadOnlySpan<char> chars, int maxChars = int.MaxValue)
446447
{
447-
int hash_value = 0;
448-
int length = Math.Min(chars.Length, maxChars);
449-
for (var i = 0; i < length; i++)
448+
int length = chars.Length > maxChars ? maxChars : chars.Length;
449+
450+
long hash = 0;
451+
for (int i = 0; i < length; i++)
450452
{
451453
ref readonly char c = ref chars[i];
452-
hash_value = (hash_value * 31) ^ c;
454+
hash |= (long)c << (i * 8);
453455
}
454456

455-
return hash_value;
457+
return (int)(hash ^ (hash >> 32));
456458
}
459+
460+
/// <inheritdoc cref="GetHashCodeFromChars(ReadOnlySpan{char}, int)"/>
461+
public static int GetHashCodeFromChars(this StringSegment chars, int maxChars = int.MaxValue)
462+
=> chars.AsSpan().GetHashCodeFromChars(maxChars);
463+
464+
/// <inheritdoc cref="GetHashCodeFromChars(ReadOnlySpan{char}, int)"/>
465+
public static int GetHashCodeFromChars(this string chars, int maxChars = int.MaxValue)
466+
=> chars.AsSpan().GetHashCodeFromChars(maxChars);
457467
}

Source/Open.Text.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<RepositoryUrl>https://github.com/Open-NET-Libraries/Open.Text</RepositoryUrl>
2020
<RepositoryType>git</RepositoryType>
2121
<PackageTags>string, span, enum, readonlyspan, text, format, split, trim, equals, trimmed equals, first, last, preceding, following, stringbuilder, extensions, stringcomparable, spancomparable, stringsegment, splitassegment</PackageTags>
22-
<Version>6.5.3</Version>
22+
<Version>6.5.4</Version>
2323
<PackageReleaseNotes></PackageReleaseNotes>
2424
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2525
<PublishRepositoryUrl>true</PublishRepositoryUrl>

0 commit comments

Comments
 (0)