Alessandro Dionisi
Alessandro Dionisi

Reputation: 2684

How to generate random hex string in javascript

How to generate a random string containing only hex characters (0123456789abcdef) of a given length?

Upvotes: 48

Views: 66267

Answers (16)

Jankapunkt
Jankapunkt

Reputation: 8423

On modern browsers there is also the Web Crypto API. It also allows to generate (cryptographically strong) random values, similar to what node:crypto does:

const randomHex = (bytes = 8) => {
  // fill typed array with random numbers
  // from 0..255 per entry
  const array = new Uint8Array(bytes)
  window.crypto.getRandomValues(array)

  // wrap to array and convert numbers to hex
  // then join to single string
  return [...array]
    .map(n => n.toString(16))
    .join('')
}

examples usage

console.debug(randomHex(2)) // 47be
console.debug(randomHex(4)) // 414c34a2
console.debug(randomHex(8)) // 53f5d393e13bd86

Resources

https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues

Upvotes: -1

hong developer
hong developer

Reputation: 13926

I think we can make a unique random hex value using Date class.

const makeSize = 2
const uniqueHexValue = [...Array(makeSize)].map(() => Math.floor(Math.random() * new Date().valueOf()).toString(16)).join("")

Upvotes: 0

Ahmed Ismail
Ahmed Ismail

Reputation: 31

Length of the array is the length of the random string.

const randomHex = Array.from({ length: 32 }, () => "0123456789ABCDEF".charAt(Math.floor(Math.random() * 16))).join('');
console.log(randomHex);

Upvotes: 3

K.tin
K.tin

Reputation: 475

You can use a hexa number 0xfffff to random a hex string

getHexaNumb() {
    return Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")
}

Upvotes: 7

TechHermit
TechHermit

Reputation: 1

let generateMacAdd = (function () {
    let hexas = '0123456789ABCDEF'
    let storeMac = []
    let i = 0
    do {
        let random1st = hexas.charAt(Math.floor(Math.random() * hexas.length))
        let random2nd = hexas.charAt(Math.floor(Math.random() * hexas.length))
        storeMac.push(random1st + random2nd)
        i++
    } while (i <= 6)
    return storeMac.join(':')
})()
console.log(generateMacAdd);       //will generate a formatted mac address

I use self invoking function here so you can just call the variable w/o any arguments

I also use do while here, just for my own convenience, you can do any kind of loop depends what you're comfortable

Upvotes: 0

Vidya Sagar Mehar
Vidya Sagar Mehar

Reputation: 1

Here is a simplified program to generate random hexadecimal Colour code:

let items = ["a", "b", "c", "d", "e", "f"];
let item = items[Math.floor(Math.random() * items.length)];
console.log(item);

let random = Math.random().toString().slice(2, 6);
console.log(`#${item}${random}${item}`);

Upvotes: 0

Brian Westphal
Brian Westphal

Reputation: 6305

Using Math.random, you can do 13 characters at a time in a convenient way. If you want an arbitrary length string, you can still do it with a "one-liner":

const makeRandomHexString = (length: number) =>
  Array.from({ length: Math.ceil(length / 13) })
    .map(() =>
      Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER / 2))
        .toString(16)
        .padStart(13, '0')
    )
    .join('')
    .substring(0, length);

Upvotes: 0

Sekh Soyeb Ali
Sekh Soyeb Ali

Reputation: 11

Using for Loop, charAt and Math.random

let result = "";
let hexChar = "0123456789abcdef";
for (var i = 0; i < 6; i++) {
  result += hexChar.charAt(Math.floor(Math.random() * hexChar.length));
}
console.log(`#${result}`);

Upvotes: 0

Simon
Simon

Reputation: 1493

Up to 7 characters may be quickly taken from one Math.random() call (A):

const halfBytesIn35 = 7 // = 3.5 bytes
const byte35 = Math.pow(16, halfBytesIn35)
const bytes35 = () => ((Math.random() * byte35) | 0).toString(16).padStart(halfBytesIn35,'0')
console.log('A: ' + bytes35())

const bytes65 = len => Math.floor(Math.random() * Math.pow(16, len*2)).toString(16).padStart(len,'0')
console.log('B: ' + bytes65(6))

function moreBytes (len) {
  len *= 2; // alternative: len <<= 1 if you do not use half bytes. This might allow optimizations based on len always being an Integer then.
  let builder = "";
  while (len > 0) {
    builder += bytes35()
    len -= 7
  }
  return builder.slice(0,len)
}
console.log('C: ' + moreBytes(16))

Store the Math.pow constant if you plan to use this with high frequency.

An 8th letter overflows into the sign bit in the binary floor.

You can reach up to 13 characters from one call by using Math.floor instead (B) or even loop the generator for an arbitrary length (C).

Note that this could be used to define premature optimization. If your bottleneck really is the creation of Random Numbers consider using LUTs. This is common if you are developing for embedded. (And in this case somehow got stuck using javascript, but do not have the timebuget to generate random Numbers)

Upvotes: 0

Aminu Kano
Aminu Kano

Reputation: 2855

NodeJS Users

You can use randomBytes available in the crypto module, to generate cryptographically strong pseudorandom data of a given size. And you can easily convert it to hex.

import crypto from "crypto";

const randomString = crypto.randomBytes(8).toString("hex");

console.log(randomString)  // ee48d32e6c724c4d

The above code snippet generates a random 8-bytes hex number, you can manipulate the length as you wish.

Upvotes: 55

Kannan Goundan
Kannan Goundan

Reputation: 5232

This securely generates a 32-byte random string and encodes it as hex (64 characters).

Array.from(crypto.getRandomValues(new Uint8Array(32)))
    .map(b => b.toString(16).padStart(2, '0')).join('');

Long version:

function generateRandomHexString(numBytes) {
    const bytes = crypto.getRandomValues(new Uint8Array(numBytes));
    const array = Array.from(bytes);
    const hexPairs = array.map(b => b.toString(16).padStart(2, '0'));
    return hexPairs.join('')
}

Upvotes: 6

d0g
d0g

Reputation: 1399

This works for lengths up to 13:

randomHex = length => (
        '0'.repeat(length) 
        + Math.floor((Math.random() * 16 ** length))
        .toString(16)
    ).slice(-length);

console.log(randomHex(4));
console.log(randomHex(6));
console.log(randomHex(13));
console.log(randomHex(20));

Upvotes: 1

RedMatt
RedMatt

Reputation: 545

Here's a version that avoids building one digit at a time; it's probably only suitable for short lengths.

function genHexString(len) {
    const str = Math.floor(Math.random() * Math.pow(16, len)).toString(16);
    return "0".repeat(len - str.length) + str;
}

Upvotes: 0

zer00ne
zer00ne

Reputation: 43950

Short alternative using spread operator and .map()


Demo 1

const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');

console.log(genRanHex(6));
console.log(genRanHex(12));
console.log(genRanHex(3));


  1. Pass in a number (size) for the length of the returned string.

  2. Define an empty array (result) and an array of strings in the range of [0-9] and [a-f] (hexRef).

  3. On each iteration of a for loop, generate a random number 0 to 15 and use it as the index of the value from the array of strings from step 2 (hexRef) -- then push() the value to the empty array from step 2 (result).

  4. Return the array (result) as a join('')ed string.


Demo 2

const getRanHex = size => {
  let result = [];
  let hexRef = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];

  for (let n = 0; n < size; n++) {
    result.push(hexRef[Math.floor(Math.random() * 16)]);
  }
  return result.join('');
}

console.log(getRanHex(6));
console.log(getRanHex(12));
console.log(getRanHex(3));

Upvotes: 72

IceMetalPunk
IceMetalPunk

Reputation: 5556

There are a few ways. One way is to just pull from a predefined string:

function genHexString(len) {
    const hex = '0123456789ABCDEF';
    let output = '';
    for (let i = 0; i < len; ++i) {
        output += hex.charAt(Math.floor(Math.random() * hex.length));
    }
    return output;
}

The other way is to append a random number between 0 and 15 converted to hex with toString:

function genHexString(len) {
    let output = '';
    for (let i = 0; i < len; ++i) {
        output += (Math.floor(Math.random() * 16)).toString(16);
    }
    return output;
}

Upvotes: 9

Alessandro Dionisi
Alessandro Dionisi

Reputation: 2684

If you can use lodash library here is the code snippet to generate a 16 chars string:

let randomString = _.times(16, () => (Math.random()*0xF<<0).toString(16)).join('');

Upvotes: 2

Related Questions