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

我有一个相当复杂的 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()


隔江千里
浏览 106回答 1
1回答

动漫人物

您正在播种默认源,系统的许多部分都使用该源。在一个大型、复杂的项目中,很可能有其他部分根据环境消耗不确定数量的随机值。甚至有可能在代码中的其他地方调用了rand.Seed().如果您希望随机值是独立的,请创建自己的随机值rand.Rand并将其用于您想要由种子确定的部分。如果您可以在一段独立的代码中重现这一点,那么我们可以探索特定的情况,但我预计当您创建一段独立的代码时,问题将会消失,因为您将删除其他值消费者( s)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go