C# 创建一个相同的;“随机”;基于多数据的浮点运算

C# 创建一个相同的;“随机”;基于多数据的浮点运算,c#,unity3d,random,hash,C#,Unity3d,Random,Hash,我正在制作一个游戏(Unity),我需要基于多个int和/或float创建一个随机浮点值(0到1之间) 我认为手动为函数创建单个字符串会更容易,但它可能接受int和/或float的列表 结果示例: “[5-91]-52-1”0.158756.. 要点: 结果分布(0和1之间)必须相等(不希望90%的结果在0.45和0.55之间) 对同一字符串询问两次必须返回完全相同的结果(即使我重新加载应用程序,或在不同的计算机上启动应用程序,…) 结果不必是唯一的 奖励积分: 有时我需要类似于clo

我正在制作一个游戏(Unity),我需要基于多个
int
和/或
float
创建一个随机浮点值(0到1之间)

我认为手动为函数创建单个字符串会更容易,但它可能接受
int
和/或
float
的列表

结果示例:

  • “[5-91]-52-1”
    0.158756..
要点:

  • 结果分布(0和1之间)必须相等(不希望90%的结果在0.45和0.55之间)
  • 对同一字符串询问两次必须返回完全相同的结果(即使我重新加载应用程序,或在不同的计算机上启动应用程序,…)
  • 结果不必是唯一的
奖励积分:

  • 有时我需要类似于close的字符串返回close结果,但不是每次都需要。“随机生成”有可能处理具有此功能的布尔值吗

    • 我建议使用hashcode(或类似的东西)作为
      随机对象的种子。对于相同的字符串,哈希代码必须相同,因此您将始终返回相同的序列

      正如Nuf所指出的,hashcodes只保证在同一个应用程序域中是相同的;因此,它可能无法跨重启工作


      至于你的奖励点,不写你自己的RNG就很难做到。种子中的任何变化都可能并且应该导致结果序列中的大量变化。

      您所描述的本质上是散列函数的定义

      所以只需使用一个,并将结果标准化到您想要的范围内。大多数基本情况都可以使用
      GetHashCode
      ,但不能保证在不同版本的框架中产生相同的结果

      保证跨机器提供完全相同结果的稳定版本是使用众所周知的好的类似散列的加密散列SHA256,并将结果的前几个字节作为整数进行规范化。加密散列函数还可以方便地将字节数组作为输入,这样您就可以直接将多个值组合为字节,并获得稳定的结果

          var intValue = 42;
      
          var bytesToHash = BitConverter.GetBytes(intValue);
          var hash = System.Security.Cryptography.SHA256Managed.Create()
                   .ComputeHash(bytesToHash);
          var toNormalize = BitConverter.ToUInt32(hash,0);
          var fancyRandom = (double)toNormalize/UInt32.MaxValue;
      
      要将多个值组合到字节数组中,您可以手动组合
      位转换器.GetBytes的结果,也可以使用
      MemoryStream
      上的
      BinaryWriter

      或者,您可以使用生成的整数作为伪随机生成器的某些自定义实现的种子(因为.Net中的整数不能保证跨机器/版本的.Net提供相同的结果),正如评论中所建议的,但我认为它不会提供明显更好的分布

      注意:确保生成的数字“足够随机”地分布在您的案例中。加密散列函数可能会给出您想要的结果,但我不确定如何证明这一点


      对于“奖金”部分:若你们能找到一个伪随机发生器,它能持续地为“相似”种子产生相近的结果,我会非常惊讶。相反,您可以对单独的部分使用与上述相同的方法-一个是“相同”的,另一个是处理变化的(即,对于稳定的部分,
      intValue&0xffff00
      ,对于“小差异”),然后合并产生的“随机”具有一定权重的数字:
      randomFromStable+0.05*randomFromDifference

      使用字符串的哈希代码作为
      Random
      对象的种子可能?看起来是个不错的解决方案,谢谢。我正在检查。我只关心创建一个新的
      随机
      对象,并为每个请求设置一个新的种子,不是很重吗?与其设置种子并在其上请求多个数字(
      normal
      use),创建多个实例并不繁重;它通常只会导致您实际想要的场景(复制序列);这通常是不受欢迎的好吧,非常感谢。最后一个问题(接近奖励点),hashcode的分布情况以及它与种子设置的连接是什么?例如:如果我用
      [
      说明每个字符串,它会影响结果分布还是根本不影响?(如果您需要在重新启动程序后(或在程序的多个实例之间)结果相同,是否也可以创建一个应答以设为应答),您应该知道,保证只在原始应用程序域中返回相同的值,否则您可能需要创建自己的哈希函数实现,即使在应用程序域之间也能返回稳定的结果。太棒了,我正在寻找所有这些。