3

I need to generate a 256 bits random unsigned number as a decimal string (with nearly zero probability of collision with anything generated earlier).

How to do this in JavaScript (in a browser)?

Sascha
  • 4,576
  • 3
  • 13
  • 34
porton
  • 5,214
  • 11
  • 47
  • 95
  • What have you tried, and what exactly is the problem with it? – jonrsharpe Jul 29 '20 at 22:38
  • @jonrsharpe I tried `Math.random()` but it generates a too short number of random bits. I am also unsure if `Math.random()` is reliably seed in all popular browsers. – porton Jul 29 '20 at 22:39
  • [GUID / UUIDs](https://stackoverflow.com/questions/105034/how-to-create-guid-uuid) are 128 bit and are good enough for basically any use case. Doubling the number of bits is almost certainly overkill and only produces a false sense of security (at this point implementation errors are already way more likely than actual random collisions). – Joachim Sauer Jul 29 '20 at 22:40
  • JavaScript numbers are doubles, 64-bit floats, so if you really want 256 bits you'll have to pick 4. And what do you mean "reliably seed"? – jonrsharpe Jul 29 '20 at 22:41
  • [`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) will probably be involved in the solution. – Joachim Sauer Jul 29 '20 at 22:42
  • @JoachimSauer I need a 256 bit number for an Ethereum `uint256` type. Well, I could use a smaller number like UUID, but I need to pass all the 256 bit through the network anyway. – porton Jul 29 '20 at 22:50
  • 1
    @porton - some more info about your use-case would be helpful. Sometimes you can find out that the core issue is with design and that it can be solved in much better way. Just from your comment I can assume you want to generate some unique number from BROWSER! You cannot rely on browser for that in general, any browser do anything with it and any junior programmer can change the generation logic if he/she wants... However I am just assuming a lot of it, because I dont know the context, only very little you provided... – libik Jul 29 '20 at 22:51
  • @libik I generate a unique number in a browser, then check that it is really unique in the blockchain side. I use this number as a unique ID. Really, the only thing I need is to generate a unique number in browser. It is not very important that it takes all the 256 bit, but why not to be dull? – porton Jul 29 '20 at 22:53

2 Answers2

7

You can use the new JavaScript tools if you are not very limited:

function rnd256() {
  const bytes = new Uint8Array(32);
  
  // load cryptographically random bytes into array
  window.crypto.getRandomValues(bytes);
  
  // convert byte array to hexademical representation
  const bytesHex = bytes.reduce((o, v) => o + ('00' + v.toString(16)).slice(-2), '');
  
  // convert hexademical value to a decimal string
  return BigInt('0x' + bytesHex).toString(10);
}

console.log( rnd256() );
VisioN
  • 143,310
  • 32
  • 282
  • 281
2

This code uses a loop to generate a 256 character long string of random binary digits, then converts it to a BigInt. You can then convert it to a string if you like, or whatever else you please.

    var temp = '0b';
    for (let i = 0; i < 256; i++) {
      temp += Math.round(Math.random());
    }

    const randomNum = BigInt(temp);
    console.log(randomNum.toString());
Robert Clarke
  • 475
  • 4
  • 14
  • *"remove code runner because stackoverflow won’t run it"* -- it actually runs it well and prints the output to the improvised console. – VisioN Jul 30 '20 at 07:57
  • `Math.random` is not guaranteed to be a cryptographically secure random number generator (on most modern browsers it's not terrible). Using the `crypto` API would be preferable for this use case. – Joachim Sauer Jul 30 '20 at 09:05
  • @VisioN Code runner doesn’t work for me when it’s only Javascript. I’ve only seen it work when there’s HTML, CSS and Javascript – Robert Clarke Jul 30 '20 at 10:32