我试图创建一个简单的磁盘缓存,但是每次运行该应用程序时,我在结构上相等的记录都具有不同的哈希值。
当我在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
总是会返回相同的值。
答案 0 :(得分:4)
F#使用标准的.NET哈希函数。每次执行新进程(或旧.NET框架中的AppDomain)时,这些种子都会应用特殊的随机种子。这使得它们在不同过程之间不一致。这样做的原因是安全性:保持哈希值不变将是一个漏洞,该漏洞可用于例如。确定性哈希碰撞攻击。
如果要具有快速一致的哈希,则需要诸如Murmur3或CityHash之类的东西。它们在散列任何字节序列方面非常快,并提供了相当好的冲突避免。但是,在F#/。NET中不支持开箱即用。
如果要使用.NET标准库中已经存在的某些内容,则可以使用MD5,但是请记住,它的速度比上述两者差很多。还被认为更容易发生碰撞。