50

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

1
  • This question is similar to: Generate random string/characters in JavaScript. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Mar 13 at 21:28

17 Answers 17

72

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));

Sign up to request clarification or add additional context in comments.

2 Comments

What are the chances that it cannot be unique when 2 clients generate
@Naga not safe enough. I ended up creating a miro-service to keep track of 16 char hex strings across clients
56

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.

Comments

10

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;
}

Comments

8

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

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

Comments

7

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('')
}

3 Comments

The length of the returned string will be numBytes * 2
crypto.getRandomValues doesn’t exist until Node 19 so if you need your code to run in the browser and Node, this way is a real pain.
Could be simplified using Uint8Array.toHex(), but that is not supported by all browsers yet.
3

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);

Comments

2

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('');

1 Comment

and if you want only 4 digits I think you can change that first 16 to 4.
1

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));

Comments

0

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;
}

Comments

0

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)

Comments

0

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}`);

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0

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);

Comments

0

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}`);

Comments

0
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

Comments

0

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("")

Comments

0
const randomHex = (Math.random() * 0xFFFFFFFFFFFFF).toString(16).slice(0, 10)

If a shorter hex string is needed, modify the second argument of slice(). To obtain a longer one, you can repeat the code—for instance, twice to produce 20 characters.

Comments

-1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.