Skip to main content Accessibility Feedback


Generate, hash, and encode cryptographically random strings.

Source Code


// 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);
	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(/=+$/, '');

Preorder my new course on Web Components! Want to learn how to build Web Components from scratch, master best practices, and more? Preorder today and get $100 off of the launch price.

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