How to generate a secure random string

Here’s a cross-platform way to generate a cryptographically-secure random string as either hex or base64 or both MacOS and Linux:

(y’know, for generating your PostgreSQL passwords and such)

Command Line

16-byte (128-bit) hex

xxd -l16 -ps /dev/urandom

24-byte (196-bit) base64

xxd -l24 -ps /dev/urandom | xxd -r -ps | base64

32-byte (256-bit) url-safe base64

xxd -l32 -ps /dev/urandom | xxd -r -ps | base64 \
    | tr -d = | tr + - | tr / _

Using other tools

I chose the xxd /dev/urandom method because it seems to be the simplest and most portable. However, openssl does a nice job too.

openssl rand -hex 16
openssl rand -base64 32

There are more fancy ways, which you can read about at https://unix.stackexchange.com/questions/230673/how-to-generate-a-random-string, but… less ninja == better in my opinion.

P.S. I wrote this up because I always have a hard time finding when I need it, so I wanted to put it in a place that I wouldn’t forget.

JavaScript

Node.js

crypto
  .randomBytes(16)
  .toString("base64")
  .replace(/\+/g, "-")
  .replace(/\//g, "_")
  .replace(/=/g, "");

Browsers

(async function () {
  var rnd = new Uint8Array(16);
  await crypto.getRandomValues(rnd);
  var b64 = [].slice
    .apply(rnd)
    .map(function (ch) {
      return String.fromCharCode(ch);
    })
    .join("");
  var secret = btoa(b64)
    .replace(/\//g, "_")
    .replace(/\+/g, "-")
    .replace(/=/g, "");
  console.info(secret);
})();

Golang

Base64

import (
	"crypto/rand"
	"encoding/base64"
)

func rnd(n int) string {
	var Rando = rand.Reader
	b := make([]byte, n)
	_, _ = Rando.Read(b)
	return base64.RawURLEncoding.EncodeToString(b)
}

Run in Golang Playground

Hex

import (
	"crypto/rand"
	"encoding/hex"
)

func rnd(n int) string {
	var Rando = rand.Reader
	b := make([]byte, n)
	_, _ = Rando.Read(b)
	return hex.EncodeToString(b)
}

Run in Golang Playground