为了账号安全,请及时绑定邮箱和手机立即绑定

为什么无论种子值如何,我总是得到随机结果?

为什么无论种子值如何,我总是得到随机结果?

Go
隔江千里 2023-07-26 19:32:32
我有一个相当复杂的 Go 应用程序。它在长链中生成许多随机结果。它仅播种一次 - 当 HTTP 请求传入时。不管种子是什么——无论是unix时间,还是我自己的字母数字种子函数——它总是生成完全随机的结果。我尝试删除我的字母数字种子函数,但这不会改变行为。我也尝试过将种子始终设置为 1111。这没有效果。这是一个示例(详细且直接从源代码中提取,因为这是所要求的):func main() {    sentryDSN := os.Getenv("SENTRY_DSN")    sentry.Init(sentry.ClientOptions{        Dsn: sentryDSN,    })    sentryHandler := sentryhttp.New(sentryhttp.Options{        Repanic: true,    })    r := chi.NewRouter()    r.Use(middleware.RequestID)    r.Use(middleware.RealIP)    r.Use(middleware.Logger)    r.Use(middleware.Recoverer)    r.Use(middleware.URLFormat)    r.Use(middleware.SetHeader("Content-Type", "application/json"))    r.Use(middleware.Timeout(60 * time.Second))    r.Get("/buildingstyle", sentryHandler.HandleFunc(getBuildingStyleRandom))    r.Get("/buildingstyle/{id}", sentryHandler.HandleFunc(getBuildingStyle))    r.Get("/character", sentryHandler.HandleFunc(getCharacterRandom))    r.Get("/character/{id}", sentryHandler.HandleFunc(getCharacter))    r.Get("/climate", sentryHandler.HandleFunc(getClimateRandom))    r.Get("/climate/{id}", sentryHandler.HandleFunc(getClimate))    port := 7531    fmt.Printf("World Generator API is running on http://localhost:%d.\n", port)    log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), r))}func SeedFromString(source string) error {    h := md5.New()    _, err := io.WriteString(h, source)    if err != nil {        err = fmt.Errorf("Failed to seed random number generator: %w", err)        return err    }    seed := binary.BigEndian.Uint64(h.Sum(nil))    rand.Seed(int64(seed))    return nil}func getClimate(w http.ResponseWriter, r *http.Request) {    id := chi.URLParam(r, "id")    var o climate.SimplifiedClimate    err := random.SeedFromString(id)    if err != nil {        handleError(w, r, err)        return    }许多函数会doStuff()从切片中返回 n 个随机元素,并应用一些过滤。当同一种子用于多次运行时,我希望所有这些都保持一致和相同。然而,这种情况并非如此。相反,无论种子值如何,每次结果都是随机的。是否有一些我不知道的基本操作rand.Intn()?rand.Seed()
查看完整描述

1 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

您正在播种默认源,系统的许多部分都使用该源。在一个大型、复杂的项目中,很可能有其他部分根据环境消耗不确定数量的随机值。甚至有可能在代码中的其他地方调用了rand.Seed().

如果您希望随机值是独立的,请创建自己的随机值rand.Rand并将其用于您想要由种子确定的部分。

如果您可以在一段独立的代码中重现这一点,那么我们可以探索特定的情况,但我预计当您创建一段独立的代码时,问题将会消失,因为您将删除其他值消费者( s)。


查看完整回答
反对 回复 2023-07-26
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信