Random Numbers in Hugo "Hand Throwing Dice On Yellow" by Sarah Pflug is licensed under Burst.

Generating Random Numbers, Strings, and more in Hugo

GeekThis happily runs on Vultr. Get $300 of free hosting credits to try out their cloud compute, kubernetes engine, or managed databases. Try Vultr today to claim your free $300.

If you’ve ever needed a random number, string, or slice index from your Hugo website, this post has you covered. This article will cover selecting seeds, generating random numbers, and then how to use the random number to create random strings and select random items from slices.

Random numbers in Hugo (at least with the methods outlined in this tutorial) won’t generate a cryptographically secure value. I don’t see much worth generating cryptographically secure values for a static site.

Random Number

Most of the methods below will require you to generate a random number, or at the very least, have a seed value. You’ll need a seed, which is typically a Unix timestamp. Using a consistent seed within a page will give you the same random number sequence, which may be useful in some cases.

{{ $seed := now.Unix }}

Using the timestamp without additional equations might be “random” enough in some situations. Below is a linear congruential pseudo-random number generator. Every time you need a random number, you should change the seed to the value of the last random number you generated.

{{ $seed := now.Unix }}
{{ $rnd := {{ mod (add (mul 13 $seed) 97) 400000}} }}

You’ll usually see randomly generated numbers applied as the dividend of the modulus to select a value within a specific range.

Random Item in Slice

A slice is a data structure similar to an array. The difference between a slice and an array is that a slice can change in size. You can access items in a slice by using the index function within Hugo.

We can randomly sort a slice using the built-in function shuffle and then obtain a random value from the first index.

{{ $slice := slice "a" "b" "c" "d" }}
{{ $shuffled := shuffle $slice }}
{{ $random := index $shuffled 0 }}

Seeded Random Items in Slice

To consistently grab the same random item from a slice, you need to generate a seed that will be consistent within that context but unique to its siblings.

This method is implemented on GeekThis to grab a random affiliate for each post. This method ensures that each time we build our site, that post’s affiliate doesn’t change.

You’ll need to find a seed that will be consistent for each page but unique across pages. For our use, we used the post’s initial publication date. Look at the section below about different methods of generating seeds.

{{ $seed := .Date.Unix }}
{{ $slice := slice "a" "b" "c" "d" }}
{{ $item := index $slice (mod $seed (len $slice)) }}

The above code will grab a random item from the slice. We get a random index by setting the modulus dividend to the seed and the length of the slice as the divisor.

The random item will be consistent between builds unless you change the date of the post. You can always use a different seed method to get different results.

Random String

You can turn your seed into a random string using the sha256, md5, or base64Encode functions. With sha256 and md5, the resulting string will be a hexadecimal hash of our seed. Using base64Encode, you’ll get an alphanumeric encoding.

{{ $seed := now.Unix }}
{{ md5 $seed }}
{{ sha256 $seed }}
{{ base64Encode $seed }}

You can use printf to shorten the string by setting the precision.

{{ printf "%.10s" (sha256 $seed) }}

If you’re generating random strings for your CSS and JavaScript filenames, you might want to look into fingerprinting. With fingerprinting, your file will have a unique string appended to the filename by Hugo.

Different Seed Methods

Below are a few different methods to obtain seeds that you can use with all of the above methods of generating random content. Each method has its advantages and will give you different results based on when the seed changes.

Date and Time

Using the current epoch is a simple way to seed pseudo-random number generators and is outlined earlier in this article. This seed will change with each build.

{{ $seed := now.Unix }}

File Hash

You can use any file hash from your project. Depending on how often this file is modified, the seed may be consistent or varied. This is a good seed to use if you’re trying to get repeatable results between builds but want different pages to have random values.

{{ $seed := int ( printf "0x%.8s" (md5 (readFile .File.Path))) }}

Git Commit Hash

Using the latest git commit hash/checksum, you can get unique seeds that are repeatable per commit. Each time you make a new commit your random values will change.

{{ $seed := int ( printf "0x%.8s" .GitInfo.Hash) }}

File’s UniqueID

The file’s UniqueID is the MD5 hash of the file’s path and name. If you want a seed unique to each file, this is a good option.

{{ $seed := int ( printf "0x%.8s" .File.UniqueID) }}

What is Int Printf %.8s?

A few of the above functions may look a bit like gibberish. When you have a hexadecimal string, you can turn it into an integer with int if you prefix the string with “0x”. We can’t turn 128bits into an integer, that’s where we trim the string to 32 bits (each byte is two characters).

Related Posts

Build Script for Hugo Websites

A basic bash build script for Hugo websites to compress images, JavaScript files, and CSS before releasing your website to the public. Keeps a copy of uncompressed assets while easily compressing all files before uploading your website.

Get Hugo to Show Content from Multiple Sections

Learn how to combine posts from multiple sections into a single list and range inside of Hugo. Show content from two or more sections in a single list.

Writing GUIs in Golang

Explore the different methods to create a GUI using Golang and what method will work best for your application.

Hugo Footnotes and Citations

Add footnotes, citations, and references to your Hugo posts with this simple technique. Give your articles more credibility and improve your posts by making them more informative.