.net-core - 为什么散列 F# 记录在每次运行时返回不同的值

标签 .net-core f# record deterministic

我正在尝试创建一个简单的磁盘缓存,但每次运行应用程序时,我的结构相等的记录都有不同的哈希值。

当我在 LINQPad 中运行它或者记录只包含一个整数时,该行为似乎是正确的(确定性的)。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>

</Project>

type Test = { test : string }

[<EntryPoint>]
let main argv =
    { test = "test" }
    |> hash
    |> printfn "%i"

    0

我希望运行 hash在结构相等的记录上总是返回相同的值。

最佳答案

F# underneat 使用标准的 .NET 散列函数。每次执行新进程(或旧 .NET 框架中的 AppDomain)时,它们都会应用一个特殊的随机种子。这使得它们在不同的过程中不一致。这样做的原因是安全性:保持哈希不变将是一个漏洞,可用于例如。确定性哈希冲突攻击。

如果你想要快速一致的哈希,你需要像 Murmur3 或 CityHash 这样的东西。它们在散列任何字节序列方面非常快,并提供了相当好的冲突避免。但是,它们在 F#/.NET 中不受开箱即用的支持。

如果你想使用 .NET 标准库中已经存在的东西,你可能会使用 MD5,但请记住,它的速度比上面两个要弱得多。它也被认为更容易发生碰撞。

关于.net-core - 为什么散列 F# 记录在每次运行时返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56800639/

相关文章:

c# - F# 中的事件和委托(delegate)

Delphi:(Indy)发送一个标题 Record 后跟一个文件

delphi - 记录文件升级和向后兼容性

docker - 无法使用 Visual Studio 2017 调试我的 Docker 容器

c# - C# for 循环的语法和时间复杂度差异

asp.net-core - 为什么 Giraffe/AspNetCore + SignalR 依赖注入(inject)无法解析 MailboxProcessor 单例?

java - 在android中录制语音通话

c# - Ocelot 无法匹配上游路径的路由配置

c# - Assembly.LoadFile、Assembly.LoadFrom 和 Assembly.Load 的替代方案?

asynchronous - F# 异步文件复制