Skip to main content Accessibility Feedback

randomString.js

Generate, hash, and encode cryptographically random strings.

Source Code

Example

// Create and store a new PKCE code_verifier (the plaintext random secret)
let rand = generateRandomString();

// Hash and base64-urlencode the secret to use as the challenge
sha256(rand).then(function (hash) {
	let encoded = base64urlencode(hash);
  console.log(rand, hash, encoded);
});

The helper functions

/**
 * Generate a secure random string using the browser crypto functions
 * @return {String} A random string
 */
function generateRandomString () {
	var array = new Uint32Array(28);
	window.crypto.getRandomValues(array);
	return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
}

/**
 * Calculate the SHA256 hash of the input text
 * @param  {String}  plain The plaintext string
 * @return {Promise}       Resolves as a hash
 */
function sha256 (plain) {
	const encoder = new TextEncoder();
	const data = encoder.encode(plain);
	return window.crypto.subtle.digest('SHA-256', data);
}

/**
 * Base64-urlencode a string
 * @param  {String} str The unencoded string
 * @return {String}     The encoded string
 */
function base64urlencode (str) {
	// Convert the ArrayBuffer to string using Uint8 array to conver to what btoa accepts.
	// btoa accepts chars only within ascii 0-255 and base64 encodes them.
	// Then convert the base64 encoded to base64url encoded
	// (replace + with -, replace / with _, trim trailing =)
	return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))
		.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

Find this useful? You can support my work by purchasing an annual membership.