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