The Bicep uniqueString as well as the ARM uniqueString function:
Creates a deterministic hash string based on the values provided as parameters
The actual function implementation is not documented, but is (almost certainly) a variant of the Murmur hash algorithm that maps the provided string parameters to a 64 bit hash and returns a 13 character Base32-like encoding of this hash.
The function:
- Concatenates the string parameters with a dash
-
- UTF8 encodes the resulting concatenated string
- Calculates a 64-bit hash of the encoded bytes using a variant of the Murmur hash algorithm
- Encodes the 64-bit hash as a 13 character Base32-like string using a custom Base32 alphabet
a-z,2-7
Warning
Since the ARM/Bicep function is undocumented there are no guarantees the below implementation correct. However it most likely is correct, since it is difficult for Microsoft to change the hash output without impacting existing ARM and Bicep templates.
The implementation is derived from Azure.Deployments.Expression.Functions.BuiltIn.UniqueStringFunction
in Azure.Deployments.Expression as well as Microsoft.WindowsAzure.ResourceStack.Common.Algorithms.ComputeHash
in Microsoft.PowerPlatform.ResourceStack. Both are MIT licensed.
Note
As an aside, the same hash algorithm is also used to calulate the deployment template hash in Bicep using Azure.Deployments.Core.Helpers.TemplateHelpers.ComputeTemplateHash
in Azure.Deployments.Core. The hash is based on an uppercase minified JSON representation of the template. The actual templateHash
value is the string representation of the 64-bit unsigned integer hash, which is why template hashes are numeric strings.
The PowerShell script azure-powershell-uniquestring.ps1
adds a Bicep
type with a UniqueString
static method simulating the Bicep uniqueString
function.
To verify, deploying the following Bicep template:
output empty string = uniqueString('')
output test string = uniqueString('test')
output twoparams string = uniqueString('test', 'test2')
output threeparams string = uniqueString('test', 'test2', 'test3')
Gives the result:
"empty": "aaaaaaaaaaaaa"
"test": "rbgf3xv4ufgzg"
"twoparams": "pivml2tg5alca"
"threeparams": "bqgd334z2uj64"
Which matches the output given by PowerShell:
PS C:\> [Bicep]::UniqueString("")
aaaaaaaaaaaaa
PS C:\> [Bicep]::UniqueString("test")
rbgf3xv4ufgzg
PS C:\> [Bicep]::UniqueString("test", "test2")
pivml2tg5alca
PS C:\> [Bicep]::UniqueString("test", "test2", "test3")
bqgd334z2uj64