Runtime verified Test scripts included

Syntax

SHA1(stringToConvert[, charSet])  →  string
1–2 arguments

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 = SHA1("Hash example 2026")
]%%
%%=v(@digest)=%%

Renders 93135d2253cdf62bb977c529a47739baaa649db4.

A typical use is a checksum over a value you send elsewhere and want to compare later:

%%[
  VAR @payload, @check
  SET @payload = Concat("order-4417", "|", "reader@example.org")
  SET @check = SHA1(@payload)
]%%
<p>Reference %%=Substring(@check, 1, 10)=%%</p>

Build the string you hash explicitly, as above — the digest changes with every separator and every space.

Return value

string — 40 lowercase hexadecimal characters with no separators.

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-1 of the input. SHA1("Hash example 2026") gives 93135d2253cdf62bb977c529a47739baaa649db4, and the official reference’s own example value matches exactly.

The bytes hashed are the UTF-8 encoding of the input. Hashing a string containing ß, and ä gave 57418a4484a6e50107c9c73d57333982344f4ebd, the digest of its UTF-8 bytes rather than of the UTF-16 form the engine holds internally. An ASCII-only test can never establish this, because ASCII text has only one plausible encoding.

The second argument genuinely changes the value. The same input under UTF-16 gave 12ebd4a9b721eda440d263131f1e29fad920fede, which is what UTF-16 little-endian bytes produce.

The empty string is hashed, not refused. SHA1("") returned da39a3ee5e6b4b0d3255bfef95601890afd80709, the well-known digest of zero bytes.

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 601fc90e786918f662cece34acf5cdb0b1f8fade, the digest of Grus? ??. 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=[", SHA1(@a), "]"))

  /* the plain one-argument form, its length, and the empty-input digest */
  IF @b == "safe" THEN
    OutputLine(Concat("--- safe start ---"))
    OutputLine(Concat("S1=[", SHA1(@a), "]"))
    OutputLine(Concat("SL=[", Length(SHA1(@a)), "]"))
    OutputLine(Concat("ES=[", SHA1(""), "]"))
    OutputLine(Concat("--- safe done ---"))
  ENDIF

  /* the second argument really changes the digest */
  IF @b == "enc" THEN
    OutputLine(Concat("--- enc start ---"))
    OutputLine(Concat("S8=[", SHA1(@a, "UTF-8"), "]"))
    OutputLine(Concat("S16=[", SHA1(@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=[", SHA1(@nb), "]"))
    OutputLine(Concat("NS16=[", SHA1(@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=[", SHA1(@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=[", SHA1(@a, "banana"), "]"))
  ENDIF

  IF @b == "a0" THEN
    OutputLine(Concat("--- a0 start ---"))
    OutputLine(Concat("A0=[", SHA1(), "]"))
  ENDIF

  IF @b == "a3" THEN
    OutputLine(Concat("--- a3 start ---"))
    OutputLine(Concat("A3=[", SHA1(@a, "UTF-8", "extra"), "]"))
  ENDIF
]%%

Availability

Platform Available
Marketing Cloud Engagement Yes
Marketing Cloud Next No

See also