-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
math/rand: make global Seed a no-op #67273
Comments
I am tangentially responsible for a codebase that does use fixed seeding to produce reproducible random numbers, and so I was initially concerned by this proposal, but I see that it's talking specifically about the global That seems very reasonable to me. Expecting the shared global source to have a predictable seed, even though literally anything in the program could reseed it at any time, seems like an unreasonable expectation. The current docs for
|
Indeed. I added "global" to the title. Thanks for pointing out the potential confusion.
No, the promise would be broken, just with a 2+ year grace period. We already broke the promise for what happens when you don't seed, so it's the same promise, broken twice. |
This proposal has been added to the active column of the proposals project |
Have all remaining concerns about this proposal been addressed? The proposal details are in #67273 (comment). |
Based on the discussion above, this proposal seems like a likely accept. The proposal details are in #67273 (comment). |
No change in consensus, so accepted. 🎉 The proposal details are in #67273 (comment). |
Change https://go.dev/cl/606055 mentions this issue: |
In Go 1.24, I propose to make rand.Seed (the top-level function) a no-op, controlled by GODEBUG=randseednop=1. (Because it is GODEBUG-controlled, specific programs could opt back to the old behavior using a //go:debug line, through Go 1.27 at least.)
The rationale is that rand.Seed is already deprecated, but it is preventing math/rand users from getting more secure randomness by default. There exist imported packages that call
rand.Seed(time.Now().UnixNano())
“just in case”, and that makes math/rand fall back to the old Go 1 generator.There no doubt exist some programs that use rand.Seed correctly for a reproducible simulation or the like, with only one goroutine at a time using the randomness, and being careful not to call any standard library or other packages that themselves contain even a single call to
rand.Int
or any other top-level function. It is possible, but it is fragile. (This is the same argument we made to auto-seed and deprecate Seed in the first place.)Those programs can do what we said back then: instead of
rand.Seed(s)
, user := rand.New(rand.NewSource(s))
and passr
around. They can even name the variablerand
to minimize code updates. They can even:Making those already-fragile programs convert to this form will remove the fragility, and it will let us fix the majority case of programs that don't care about reproducibility but are getting the insecure Go 1 generator when they could instead be getting the secure ChaCha8 generator.
If Go 1.28 retired the GODEBUG (following our “minimum four release” policy for GODEBUGs), then at that point we could make math/rand's top-level functions trivial wrappers around math/rand/v2's top-level functions, making them eligible for gofix to update. (Note that Go 1.28 would not arrive until the year 2027 - this is very much playing the long game.)
The text was updated successfully, but these errors were encountered: