SHA512
Returns the SHA-512 hash of the input value. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including the fact that the bytes hashed are the UTF-8 encoding of the input, and that an unrecognised encoding name aborts the page.
Syntax
SHA512(stringToConvert[, charSet]) → string
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
stringToConvert |
string | number | date | Yes | The value to hash; a number or date is hashed as the text it renders as |
charSet |
string | No | Name of the character encoding applied before hashing; defaults to UTF-8 |
Example
%%[
VAR @digest
SET @digest = SHA512("Hash probe 2026")
]%%
%%=v(@digest)=%%
Renders a 128-character value beginning bbad63c2db95ac23.
The full digest is long enough to be awkward in a link, so a shortened prefix is the common pattern:
%%[
VAR @payload, @check
SET @payload = Concat("order-4417", "|", "reader@example.org")
SET @check = Substring(SHA512(@payload), 1, 16)
]%%
<p>Reference %%=v(@check)=%%</p>
Shorten only for display — compare the full digest whenever the value is being checked rather than shown.
Return value
string — 128 lowercase hexadecimal characters with no separators, measured with Length() on the page rather than assumed.
There is no closed set of sentinel values to test for: every accepted input produces a digest, and every rejected one aborts the page instead of returning an error token.
Behaviour
The digest is the real SHA-512 of the input. Every value here was compared character for character against the same digest computed independently outside Marketing Cloud, over the same bytes, and the official reference’s own example value reproduced exactly.
The bytes hashed are the UTF-8 encoding of the input. Hashing a string containing ß, € and ä produced the digest of its UTF-8 bytes, beginning cf46d118822edbf2, rather than of the UTF-16 form the engine holds internally. An ASCII-only test could not have shown this.
The second argument genuinely changes the value. The same input under UTF-16 produced an entirely different digest beginning 133c85ecdfdec3f5, which is what UTF-16 little-endian bytes give.
The empty string is hashed, not refused. SHA512("") returned the well-known digest of zero bytes, beginning cf83e1357eefb8bd.
The encoding argument is stricter than it looks
ASCII is accepted and silently replaces every character it cannot represent with a question mark before hashing: the non-ASCII string above came back as the digest of Grus? ??, beginning b809a01fcb5e6b07. Nothing warns you.
An unrecognised name is rejected outright — passing banana aborted the page with HTTP 422 rather than falling back to the default.
Show test script
%%[
VAR @b, @a, @nb
SET @b = RequestParameter("b")
SET @a = "Hash probe 2026"
SET @nb = Concat("Grus", Char(223), " ", Char(8364), Char(228))
/* known-good control: renders on every request, so a run of HTTP 422s
can be told apart from a broken deploy */
OutputLine(Concat("CTRL=[", SHA512(@a), "]"))
/* the plain one-argument form, its length, and the empty-input digest */
IF @b == "safe" THEN
OutputLine(Concat("--- safe start ---"))
OutputLine(Concat("S5=[", SHA512(@a), "]"))
OutputLine(Concat("SL=[", Length(SHA512(@a)), "]"))
OutputLine(Concat("ES=[", SHA512(""), "]"))
OutputLine(Concat("--- safe done ---"))
ENDIF
/* the second argument really changes the digest */
IF @b == "enc" THEN
OutputLine(Concat("--- enc start ---"))
OutputLine(Concat("S8=[", SHA512(@a, "UTF-8"), "]"))
OutputLine(Concat("S16=[", SHA512(@a, "UTF-16"), "]"))
OutputLine(Concat("--- enc done ---"))
ENDIF
/* the default encoding is the UTF-8 byte sequence, not the engine's
internal UTF-16 form - only a non-ASCII input can tell them apart */
IF @b == "nonascii" THEN
OutputLine(Concat("--- nonascii start ---"))
OutputLine(Concat("NBIN=[", @nb, "]"))
OutputLine(Concat("NS8=[", SHA512(@nb), "]"))
OutputLine(Concat("NS16=[", SHA512(@nb, "UTF-16"), "]"))
OutputLine(Concat("--- nonascii done ---"))
ENDIF
/* ASCII silently substitutes a question mark for anything it cannot
represent, which changes the digest without any signal */
IF @b == "csascii" THEN
OutputLine(Concat("--- csascii start ---"))
OutputLine(Concat("CSASCII=[", SHA512(@nb, "ASCII"), "]"))
OutputLine(Concat("--- csascii done ---"))
ENDIF
/* each of the three branches below aborts the page - fetch alone */
IF @b == "csbad" THEN
OutputLine(Concat("--- csbad start ---"))
OutputLine(Concat("CSBAD=[", SHA512(@a, "banana"), "]"))
ENDIF
IF @b == "a0" THEN
OutputLine(Concat("--- a0 start ---"))
OutputLine(Concat("A0=[", SHA512(), "]"))
ENDIF
IF @b == "a3" THEN
OutputLine(Concat("--- a3 start ---"))
OutputLine(Concat("A3=[", SHA512(@a, "UTF-8", "extra"), "]"))
ENDIF
]%%
A bare string literal passed to OutputLine renders an empty line while the page still returns HTTP 200, so the marker silently vanishes and the block looks like a function that produced no output. Always wrap it — OutputLine(Concat("--- safe start ---")) — even for a single argument.
When a case involves non-ASCII characters, print the input string alongside the digest. A mangled test string produces a perfectly valid digest of the wrong bytes, which is indistinguishable from a function defect unless the input is visible in the same output.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | No |
See also
- MD5 · SHA1 · SHA256 — the same signature, shorter digests
- Official reference · ampscript.guide