What's the most idiomatic way to generate random numbers in Rust while making sure we never generate the same number twice?
Asked
Active
Viewed 418 times
1
-
2The de-facto crate for random number generation in Rust is [`rand`](http://docs.rs/rand). Try to build that with it, and see if and where you get stuck. – Chayim Friedman May 15 '23 at 17:58
-
2Some more detail about your higher-level goal would be helpful, as the constraint not to generate the same number twice is a bit weird. What are you trying to do? – cdhowie May 15 '23 at 18:10
-
You may want to look at [snowflake](https://crates.io/crates/rs-snowflake). Twitter created the algorithm for generating unique database keys. [Here is the original aritcle by twitter](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake). – pigeonhands May 15 '23 at 21:07
-
Never generating the same number twice is impossible since there are only a finite number of possible values for a number. Simply drawing this number plus one values guarantees that you will have at least one duplicate. – Jmb May 16 '23 at 07:27
2 Answers
0
To generate a random number in Rust you need to add a crate and rand is by far the most popular one.
If you want to make sure you never generate the same number twice, you need to keep track of the numbers you've already generated. There are many ways to do that, depending on your case. You might store the numbers in a HashSet or you might store them in a database. We'd need more details in order to give more concrete advice.

at54321
- 8,726
- 26
- 46
-
I'm trying to generate a random "id" in a function that populates a dynamoDB table with said id every time it's called. The id will be the primary key, hence why I can't have a number repeating twice. – mnk802 May 15 '23 at 19:10
-
@mnk802 If you generate numbers with a large enough range, you can make the chance of a collision as small as you want. Are you able to detect when you try to insert a duplicate ID and try again? – Solomon Ucko May 15 '23 at 19:17
-
the ids have to be 32 bits. I made a new comment below that might be useful – mnk802 May 15 '23 at 20:42
0
Given the extra details from the comments, you have a few options.
- Generate random numbers normally, then check the database to see if it's already in use. If it is, generate more until one isn't.
- Use a one-to-one mapping and keep track of a single value, as described in this question. Increment the single value each time. This may have security implications if the IDs can be taken advantage of.
- Generate very large random numbers (128 or more bits). If you use enough bits, you can make collisions statistically impractical. How many bits will depend on how many IDs your application will generate. This is what UUID does.

drewtato
- 6,783
- 1
- 12
- 17
-
these are all great suggestions but the problem is I want to read the ids and update a new field with a new id that doesn't exist transactionally. the ids have to be 32 bits. and having a one to one mapping isn't feasible in the case a row is deleted and an id is freed up. – mnk802 May 15 '23 at 20:41
-
I'm wondering if there's a way I can perform a transaction that makes sure my RGN is not in dynamo and in the case it fails I can perform some error handling and generate a new number, trying the transaction all over again. – mnk802 May 15 '23 at 20:43
-
@mnk802 I think you'd get better answers if you made a question about your database instead of rust. – drewtato May 15 '23 at 20:45
-
@mnk802 You might find [this](https://stackoverflow.com/questions/69715151/are-128-bits-of-sha-1-hash-safer-than-an-md5-hash) helpful. It could give you a better sense on a similar practical case. With just 32 bits, the chance for a collision will probably be too high to ignore, so you can't avoid checking for collisions. I'd also recommend you post a separate question with more details about your specific case. It, indeed, has little to do with Rust, and more with the DB of choice, how many "nodes" you have, potential constraints, etc. – at54321 May 15 '23 at 20:46