2

I need to generate an accurate 32 bits random alphanumeric string in JavaScript.
Is there any direct function to do it ?

Filburt
  • 17,626
  • 12
  • 64
  • 115
Rahul
  • 1,070
  • 3
  • 21
  • 47

5 Answers5

8

Using crypto and a typed array;

function random32bit() {
    let u = new Uint32Array(1);
    window.crypto.getRandomValues(u);
    let str = u[0].toString(16).toUpperCase();
    return '00000000'.slice(str.length) + str;
}

This gives us a 32-bit crypto-random number represented as a zero-padded string of 8 chars (base 16)


If you want to extend this to arbitrary numbers of chars;

function randomHash(nChar) {
    let nBytes = Math.ceil(nChar = (+nChar || 8) / 2);
    let u = new Uint8Array(nBytes);
    window.crypto.getRandomValues(u);
    let zpad = str => '00'.slice(str.length) + str;
    let a = Array.prototype.map.call(u, x => zpad(x.toString(16)));
    let str = a.join('').toUpperCase();
    if (nChar % 2) str = str.slice(1);
    return str;
}

In ES5, with comments

function randomHash(nChar) {
    // convert number of characters to number of bytes
    var nBytes = Math.ceil(nChar = (+nChar || 8) / 2);

    // create a typed array of that many bytes
    var u = new Uint8Array(nBytes);

    // populate it wit crypto-random values
    window.crypto.getRandomValues(u);

    // convert it to an Array of Strings (e.g. "01", "AF", ..)
    var zpad = function (str) {
        return '00'.slice(str.length) + str
    };
    var a = Array.prototype.map.call(u, function (x) {
        return zpad(x.toString(16))
    });

    // Array of String to String
    var str = a.join('').toUpperCase();
    // and snip off the excess digit if we want an odd number
    if (nChar % 2) str = str.slice(1);

    // return what we made
    return str;
}
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • _"This gives us a 32-bit crypto-random number"_ Would 64 bits be returned at first example? – guest271314 May 22 '16 at 19:19
  • 1
    @guest271314 I've written a method which lets you generate any multiple of 4 bits :) also, I don't see where you think a 64 bit value would be coming from in my first code block - it's using a `Uint32Array` – Paul S. May 22 '16 at 19:23
  • Is it a JS ? Its giving syntax error of missing semicolon – Rahul May 22 '16 at 19:26
  • @Rahul this is ES6, if you want ES5 then you just have to write the two arrow functions the old fashioned way as function expressions – Paul S. May 22 '16 at 19:27
  • @PaulS. thank you for your support but can you provide me with the function for ES5 as it is tough for me to understand. Thank you. – Rahul May 22 '16 at 19:29
  • @PaulS. _"also, I don't see where you think a 64 bit value would be coming from in my first code block"_ https://jsfiddle.net/91hb2n7k/4/ , see http://stackoverflow.com/a/12205668/ – guest271314 May 22 '16 at 19:32
  • @Rahul Added ES5, comments, bells and whistles. – Paul S. May 22 '16 at 19:34
  • @PaulS. Note, first example appears to return all uppercase letter characters? – guest271314 May 22 '16 at 19:37
  • @guest271314 now make a 4096 bit one :) – Paul S. May 22 '16 at 19:38
  • @PaulS. Note, 32 bits is equivalent to 4 bytes. Both examples appear return 8 bytes, or 64 bits? If you adjust `/ 2` to `/ 4` 32 bits should be returned – guest271314 May 22 '16 at 19:45
  • @guest271314 `randomHash(); // "9151E796"` is `91` `51` `E7` `96`, 4 bytes = 32 bits.... – Paul S. May 22 '16 at 20:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/112625/discussion-between-paul-s-and-guest271314). – Paul S. May 22 '16 at 20:58
  • Actually the requirement is to send a 32 bit string as a token in a post request. Rest thank you for all the efforts you guys put. – Rahul May 23 '16 at 09:03
2

I need to generate an accurate 32 bits random alphanumeric string in JavaScript.

If you mean 32 characters, you can use URL.createObjectURL, String.prototype.slice(), String.prototype.replace()

var rand = URL.createObjectURL(new Blob([])).slice(-36).replace(/-/g, "")
guest271314
  • 1
  • 15
  • 104
  • 177
  • What is the size of a character in JS ? – Rahul May 22 '16 at 18:56
  • @Rahul What do you mean by "size"? – guest271314 May 22 '16 at 18:57
  • @Rahul See [How many bytes in a JavaScript string?](http://stackoverflow.com/questions/2219526/how-many-bytes-in-a-javascript-string) , https://jsfiddle.net/91hb2n7k/ – guest271314 May 22 '16 at 19:01
  • Thank you. I am trying the answers provided. Will reply back soon and @guest271314 thank you for the link. – Rahul May 22 '16 at 19:03
  • @Rahul Since 4 bytes is equivalent to 32 bits you remove `.replace()`, use `-4` at `.slice()` `var rand = URL.createObjectURL(new Blob([])).slice(-4)` https://jsfiddle.net/91hb2n7k/1/ – guest271314 May 22 '16 at 19:10
  • @guest271314 do you realize 32 bits is different to 32 characters. If 1 character was 1 bit we'd be really limited when trying to have a discussion. – vdegenne Nov 04 '19 at 17:29
2

Inspired by Paul S.'s answer but a little simpler:

const Token = () => {
  const array = new Uint32Array(1)
  window.crypto.getRandomValues(array)
  return array[0].toString(36)
}
Empowerful
  • 21
  • 1
0

You can use this function:

function returnHash(){
    abc = "abcdefghijklmnopqrstuvwxyz1234567890".split("");
    var token=""; 
    for(i=0;i<32;i++){
         token += abc[Math.floor(Math.random()*abc.length)];
    }
    return token; //Will return a 32 bit "hash"
}

Use by calling returnHash()

Bubble Hacker
  • 6,425
  • 1
  • 17
  • 24
0

This will generate the 32 bit random alphanumeric string as requested:

crypto.getRandomValues(new Uint8Array(4)).reduce((p,c)=>p+String.fromCharCode(c))
Jonathan
  • 1,007
  • 16
  • 12