dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.89k stars 4.63k forks source link

[API Proposal]: ability to have stable hash codes #88031

Open insouciiance opened 1 year ago

insouciiance commented 1 year ago

Background and motivation

Currently, certain types & methods use Interop.GetRandomBytes (e.g. HashCode or string.GetHashCode) to have a random seed for hash codes, meaning they return different hash for the same value on different program runs.

However it would really nice to have the ability to stabilize all hash codes across multiple runs. One use case for this feature would be to detect changes in behaviour on CI and verify if those were intended or not. To have deterministic rendering results we would expect deterministic hash codes so that, for example, enumerating a set or a dictionary is stable (of course no ordering is expected at all, but it should be deterministic).

API Proposal

[AttributeUsage(AttributeTargets.Assembly)]
public sealed class AssemblyStabilizedHashCodeAlgorithmAttribute : Attribute
{
    public bool Enabled { get; }

    public AssemblyStabilizedHashCodeAlgorithmAttribute(bool enabled);
}

API Usage

<ItemGroup>
  <AssemblyAttribute Include="System.Runtime.AssemblyStabilizedHashCodeAlgorithm">
    <_Parameter1>true</_Parameter1>
  </AssemblyAttribute>
</ItemGroup>

or

[assembly: System.Runtime.AssemblyStabilizedHashCodeAlgorithm(true)]

Alternative Designs

<PropertyGroup>
    <UseStabilizedHashCodeAlgorithm>true</UseStabilizedHashCodeAlgorithm>
</PropertyGroup>

Risks

Hash code randomization is good for security, prevention against DoS attacks, etc. Having stable hash codes across runs may result in hash flooding, so it needs to be toggled explicitly via the assembly attribute or the .csrpoj property.

ghost commented 1 year ago

Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.

Issue Details
### Background and motivation Currently, certain types & methods use `Interop.GetRandomBytes` (e.g. `HashCode` or `string.GetHashCode`) to have a random seed for hash codes, meaning they return different hash for the same value on different program runs. However it would really nice to have the ability to stabilize all hash codes across multiple runs. One use case for this feature would be to detect changes in behaviour on CI and verify if those were intended or not. To have deterministic rendering results we would expect deterministic hash codes so that, for example, enumerating a set or a dictionary is stable (of course no ordering is expected at all, but it should be deterministic). ### API Proposal ```cs [AttributeUsage(AttributeTargets.Assembly)] public sealed class AssemblyStabilizedHashCodeAlgorithmAttribute : Attribute { public bool Enabled { get; } public AssemblyStabilizedHashCodeAlgorithmAttribute(bool enabled); } ``` ### API Usage ```xml <_Parameter1>true ``` or ```cs [assembly: System.Runtime.AssemblyStabilizedHashCodeAlgorithm(true)] ``` ### Alternative Designs ```xml true ``` ### Risks Hash code randomization is good for security, prevention against DoS attacks, etc. Having stable hash codes across runs may result in hash flooding, so it needs to be toggled explicitly via the assembly attribute or the .csrpoj property.
Author: insouciiance
Assignees: -
Labels: `api-suggestion`, `area-System.Runtime`, `untriaged`
Milestone: -