为什么散列F#记录每次运行都会返回不同的值

时间:2019-06-28 03:43:09

标签: .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总是会返回相同的值。

1 个答案:

答案 0 :(得分:4)

下面的

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

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

如果要使用.NET标准库中已经存在的某些内容,则可以使用MD5,但是请记住,它的速度比上述两者差很多。还被认为更容易发生碰撞。