Function Reference

A complete catalogue of PruTAN's ~130 built-in fn.* functions (sections 1–11), grouped by how they are used in real testing work — synthetic data generation, payments/banking data, verification, transformation, and payment-security (HSM). Sections 12–14 cover the sibling binding objects available in the same scripts and rules — JWE/MAC on the message object, EMV chip cryptograms (emv), and script memory (ctx).

For an introduction to what functions are and how they resolve, see Functions. Example outputs below are illustrative; values are randomized on every run.

  • In a request body, call a function as {{$functionName(args)}}.
  • In a script or rule (Pre-request Script, Sandbox / Interceptor rules), call it as fn.functionName(args).
  • Arguments may be quoted or unquoted; quoting (fn.generateCard("12","3")) is the safe habit.
  • emv.*, ctx.*, and the message object's own methods (req.jweEncrypt(...), res.stampMAC(...)) don't take the fn. prefix — see sections 12–14.

1. Identity & User Data

For seeding realistic, PII-free user records in API and onboarding tests.

FunctionExample outputNotes
randomFirstName()Noah
randomLastName()Johnson
randomFullName()Liam Jones
randomNamePrefix()Dr.
randomNameSuffix()PhD
randomUserName()Jarrell.Gutkowski
randomEmail()4bwh7gg4g@sample.comRandom domain
randomExampleEmail()Kerluke73@example.comSafe @example.* domain
randomPhoneNumber()706-172-6732
randomPhoneNumberExt()85-301-355-9096With extension
generateRandomMobileNumber()648913210410-digit mobile

2. Finance & Payments

The core set for card, ISO 8583 and UPI/bank testing.

FunctionExample outputNotes
generateCard()876331051006698116-digit default
generateCard(10)6740787467Length only
generateCard(12, 3)365941689603Length + BIN
generateAmount()113785-digit default
generateAmount(3)920Integer amount
generateAmount(4, 2)5675.92Digits + decimals
generateCountryCode("india")356Any case works (india/INDIA/India)
generateCurrencyCode("india")INRAny case works
generateRandomIFSC()BARB08863827Indian bank IFSC
generateUPIAddress()y1iykwe@axisbankRandom handle
generateUPIAddress("hdfc")mw1wn6ur4@hdfcbankBank hint
randomBankAccount()22293803
randomBankAccountBic()ZZBHCA4J2WRSWIFT/BIC
randomBankAccountIban()YF76CQVWIE1YMYQO68GLRE3SQDAVM33IBAN
randomBankAccountName()Business Account
randomCreditCardMask()4765Last-4 mask
randomBitcoin()1Whyzk53g4cTZvxamzvAyBb7k8argBTC address
randomCurrencyCode()IDRISO 4217 code
randomCurrencyName()Danish Krone
randomCurrencySymbol()₸
randomTransactionType()Purchase

3. Geo & Location

FunctionExample output
randomCity()Greenville
randomCountry()Austria
randomCountryCode()US
randomLatitude()61.25626319907147
randomLongitude()-105.95563595525634
randomStreetAddress()83152 General Street
randomStreetName()Kuhic Island

4. Internet, System & Tech

FunctionExample output
randomIP()158.42.179.24
randomIPV6()9dca:9b16:8990:c41b:efde:120a:482f:c87f
randomMACAddress()6c:36:eb:e0:76:90
randomUUID() / guid()84896dba-d93d-47f7-9354-55f2dcdf1115
randomUserAgent()Mozilla/5.0 (Windows NT 10.0; …)
randomProtocol()http
randomSemver()9.6.4
randomPassword()j8FdufH2dpuVf3x
randomDomainName()gracie.biz
randomDomainSuffix()info
randomDomainWord()donnell
randomUrl()https://portal.co
randomLocale()bm
getRandomOS()Windows 10
randomDatabaseCollation()utf8_general_ci
randomDatabaseColumn()status
randomDatabaseEngine()CSV
randomDatabaseType()blob

5. Business & Company

FunctionExample output
randomCompanyName()Walker and Sons
randomCompanySuffix()Inc
randomJobArea()Support
randomJobDescriptor()Dynamic
randomJobTitle()Chief Configuration Manager
randomJobType()Engineer
randomBs()synergize scalable platforms
randomBsAdjective()agile
randomBsBuzz()synergize
randomBsNoun()platforms
randomCatchPhrase()Seamlessly integrated modular system
randomCatchPhraseAdjective()Business-focused
randomCatchPhraseDescriptor()needs-based
randomCatchPhraseNoun()framework

6. Images

All return a URL (or data URI) — useful for profile / catalogue fields.

randomAbstractImage(), randomAnimalsImage(), randomAvatarImage(), randomBusinessImage(), randomCatsImage(), randomCityImage(), randomFashionImage(), randomFoodImage(), randomNatureImage(), randomNightlifeImage(), randomPeopleImage(), randomSportsImage(), randomTransportImage(), randomImageUrl(), randomImageDataUri().

randomAvatarImage()  →  https://s3.amazonaws.com/uifaces/faces/twitter/…/128.jpg
randomImageUrl()     →  https://picsum.photos/640/480/

7. Text & Miscellaneous

FunctionExample outputNotes
randomAbbreviation()HTML
randomAlphaNumeric()3Single char
generateAlphaNumeric(9)sMv5tLO7AFixed length
generateAlphabet(7)fYyvKrBLetters only
generateAlphabet()DTeAbKzbNo-arg → 8 chars
generateRandomNumber(6)945008Fixed length
generateRandomNumber()478212No-arg → 6 digits
randomBoolean()falseSee boolean note below
randomColor()purple
randomHexColor()#566bf7
randomInt()995

8. Date & Time

FunctionExample outputNotes
generateDate("yyyy-MM-dd HH:mm:ss")2026-09-10 06:57:28Format tokens + -1days / +1months offsets — see Functions
isPastDate("26-09-2025 06:30:00", "dd-MM-yyyy HH:mm:ss")trueVerification — is the date in the past
randomDateFuture()2027-02-10T06:57:28
randomDatePast()2025-07-07T06:57:28
randomDateRecent()2026-07-16T06:57:28
randomMonth()April
randomWeekday()Monday
timestamp()1786431448Unix epoch (seconds)
isoTimestamp()2026-08-11T06:57:28.025ZISO-8601

9. Verification & Validation

Return a boolean — use them in if() conditions and validation rules.

FunctionExamplePurpose
startsWith("Bearer", "Bearer abc.def")truePrefix check (e.g. auth header)
compare("original", "original")trueEquality check
match("\\bworld\\b", "Hello world")trueRegex match
isPastDate(date, format)trueDate is in the past
typeOf("1234", "number")falseType assertion
// use directly in a rule condition
if(fn.startsWith(req.getHeader("Authorization"), "Bearer")) {
  res.setBody("authScheme", "bearer");
}

10. Transformation & Utility

FunctionExamplePurpose
concatenate("Johnm", "Doe")JohnmDoeJoin values (variadic)
subString("HelloWorld", "2", "5")lloWoSlice by index
length("Hello World")11Length of string or array (length([a,b,c,d,e]) → 5)
size([1,2,3])3Array size (also accepts a stringified array)
toString(1434.92)1434.92Number → string
stringify({"id":1,"name":"John"}){"id":1,"name":"John"}Object → JSON string
parseJson('{"id":1}'){"id":1}JSON string → object/array. Throws if the string isn't valid JSON.
guid()ff463c05-8be8-4cab-9c40-4a3dfd9e634bUUID v4
sleep(1500)1500Pauses this rule for that many milliseconds, then continues. Returns the number of milliseconds it actually slept. The pause is capped at 10 s (the executor setting RULE_SLEEP_MAX_MS). A bigger value is cut down to the cap. In a Sandbox or Interceptor rule, the pause holds only that one connection. Stress Lab runs no rules, so it never applies there.

11. Payment Security — HSM, PIN & Crypto

Advanced payment functions that operate against a Key Management entry (Certificate & Key Management). Pass the entry name (e.g. "API Keys") — not raw key bytes.

Why "API Keys"?"API Keys" is simply the name of a Key Management entry in Certificate & Key Management that stores the working keys (PEK / MAK / TEK). The HSM and PIN functions take that entry name and look up the stored keys internally — so you never paste raw key material into a rule. Create your own entry (any name works), add the required keys, then pass that name to the function. In these examples the entry happens to be named "API Keys".Not to be confused with the API Keys feature (CI/CD authentication tokens) — unrelated, despite the similar name.

Related pages: Certificate & Key Management · Crypto · EMV Function

format below is the ISO 9564 PIN block format number: 0/1/3 for 3DES keys, 4 for AES keys — must match the entry's saved key Mode.

FunctionExamplePurpose
generatePinBlock("1234", "4111111111111111", "0", "API Keys")2OAfNMxXF0y8o8LM8LaLXQ== (hex)Build a PIN block under the entry's PEK
verifyPinBlock(block, "1234", "4111111111111111", "0", "API Keys")trueVerify a PIN block
translatePinBlock(block, "4111111111111111", "0", "API Keys", "0", "API Keys")2OAfNMxXF0…Re-encipher under another key/format
encryptPin("1234", key) / decryptPin(enc, key)… / 1234PIN encrypt / decrypt
getPEK("API Keys") / getMAK / getTEK / getKEK / getIMKA0EA903BE63A0FD0…Read the PIN / MAC / TEK / KEK / IMK key
setPEK("API Keys", "<hex>") / setMAK / setTEK / setKEK / setIMK—Set a key on the entry
decryptTR31KeyBlock(block, "API Keys")<hex key><KCV>Unwrap a TR-31 key block under the entry's KEK — see TR-31 key exchange
generateEmvDates()—Not implemented yet — always returns nothing. Do not use.
generateTMK(...) / generateTPK(...)—Master / PIN key generation (needs real key material)

For general (non-PIN) encryption use encrypt / decrypt with a certificate key — see Crypto.

12. Message Security — JWE & MAC

These live on the message object (req/res/ireq/ires), not on fn — a stamp or a JWE covers the whole message, and an interceptor has four messages in flight, so there's no single implicit target for fn to write to.

JWE (RFC 7516) — encrypt/decrypt against a stored certificate or a shared key:

FunctionPurpose
req.jweEncrypt(text, "certName", header?, secrets?)Encrypt text/object into a compact JWE. Default RSA-OAEP-256 + A256GCM; header overrides alg/enc/kid.
req.jweDecrypt(text, "certName")Decrypt a compact JWE back to text — algorithm is read from the token's own header
req.jweVerify(text, "certName")true/false — does it decrypt cleanly. Never throws.
req.jweHeader(text)The token's header (alg, enc, kid, …) read without decrypting — no key needed
req.jweTrace()Every step of the last jweEncrypt/jweDecrypt/jweVerify on this message, for print()
res.setBody("token", req.jweEncrypt(req.getBody("card"), "PartnerCert"));

MAC — ISO messages only, needs an ISO spec/key service wired into the run:

FunctionPurpose
req.generateMAC("API Keys", fieldKey?, includeHeader?)Compute the stamp as hex; the script places it. fieldKey defaults to DE128 when a field above 64 is used, else DE64.
req.stampMAC("API Keys", fieldKey?, includeHeader?)generateMAC + write it into that field in one call — the one function here that writes to the message
req.verifyMAC("API Keys", fieldKey?, includeHeader?)true/false — does the stamp already in the message match a fresh one
req.macTrace()Shows what went into the last MAC this script made: each part, the whole input (hex and text) and the MAC. It never shows the key.
res.stampMAC("API Keys"); // computes DE64 (or DE128) and writes it in

MAC over selected fields. Some switches (FSS, for example) make the MAC from only some fields and put it in a field of their own. To do this, pass a settings map instead of fieldKey:

req.stampMAC("FSS Keys", { fields: [2, 3, 4, 7, 11, 37, 41], into: "126.10" });
print(req.macTrace());

Only the listed fields go into the MAC, in the order you list them. The MAC goes into into. That can be any field or subfield, and it is not part of the MAC itself. generateMAC and verifyMAC take the same map. Write a subfield as text, for example "126.10". Written as a number, 126.10 would read as 126.1.

SettingWhat it doesDefault
fieldsThe fields that go into the MAC, in this orderrequired
intoThe field the MAC goes intoDE64, or DE128 above field 64
mtiPut the message type (MTI) firstno
lengthsInclude each field's length prefix, as it is sentno
textUse each value's characters instead of the bytes as sent. Useful when the spec packs numbers as BCD.no
separatorText put between fields, for example " "none
missingA listed field that is not in the message: "skip" it, or "error". A field that is there but empty still counts as there."skip"
padding3DES only: "zero" or "iso2""zero"
widthMAC length in bytesthe into field's fixed size, else 8

If you don't know a host's exact rule, try the settings and compare req.macTrace() with the host's log until the input matches. If a part holds a card secret (PIN, CVV, iCVV or CVV2), macTrace() hides that part.

A map without fields makes the usual whole-message MAC. For example, { into: "128", header: true } is the same as "128", true.

13. EMV Chip Cryptograms — ARQC/ARPC

The emv binding builds and checks EMV chip cryptograms (CVN 10/18/22 Visa, 16/17/18/20/21 Mastercard). Every call takes a plain data map and returns a value — nothing here writes into a message, not even parseChip, which only reads one.

Key names resolve against a Key Management entry's IMK box — the same entries as section 11, different box.

FunctionPurpose
emv.parseChip(tlvHex, source?)Parse EMV TLV (e.g. field 55) into a data map
emv.generateArqc({key, profile, data})The chip's one-time stamp — returns it, the script places it (e.g. tag 9F26)
emv.verifyArqc({key, profile, data, arqc})Recompute the ARQC and compare it to the one that arrived
emv.generateArpc({key, profile, data, arqc, arc|csu})The bank's reply cryptogram for an ARQC that arrived
emv.verifyArpc({..., arpc})Recompute the expected reply cryptogram and compare (prefix match — issuer data may follow it on the wire)
emv.nextAtc(cardKey)Advance and return this card's saved ATC counter (tag 9F36) — persists via the environment, wraps at 65535
emv.trace()Every step of the last chip calculation, for print()
chip = emv.parseChip(req.getBody("55"));
arqc = emv.generateArqc({key: "chip_imk", profile: "visa18", data: chip});
req.setEMVTagValue("55", "9F26", arqc);

14. Script Memory — ctx

ctx isn't a generator — it's a plain per-test-run scratch space. A Pre-request Script and the Validation/Rules step normally get a brand-new, empty set of bindings each; ctx is the one object that's the same dict across both, for one test run. It does not survive between separate runs — for that, use the environment (the way emv.nextAtc does).

FunctionPurpose
ctx.set(key, value)Store a value for later in this same run
ctx.get(key, default?)Read it back; default if never set
ctx.has(key)true/false — was it set
// Pre-request Script
ctx.set("startedAt", fn.timestamp());

// Validation / Rules, same run
res.setBody("elapsed", fn.timestamp() - ctx.get("startedAt", 0));

Using Functions in Rules (Sandbox & Interceptor)

Functions behave identically in Studio templating and in the rule engine — only the call form and the object you write to change.

ContextPrefixWrite-back object
Studio request body{{$fn()}}— (resolves in place)
Studio Pre-request Scriptfn.req (request)
Sandbox (Host) rulefn.res (response), req (incoming request)
Interceptor request rulefn.ireq
Interceptor response rulefn.ires

emv and ctx (sections 13–14) are bound wherever fn is. JWE and MAC (section 12) aren't separate bindings at all — they're methods on whichever message object (req/res/ireq/ires) is in scope.

The Validation tab has req, res, pv, fn, emv and ctx bound too, so all of the above run there. In practice you'll mostly use print() for logging and fn.* verification functions (compare, match, startsWith, isPastDate, typeOf) for assertions — generator functions (generateCard(), fn.guid(), etc.) work too, but writes don't feed back into the request/response being tested.

Sandbox host response rule:

res.setBody("txnId", fn.guid());
res.setBody("cardNumber", fn.generateCard("16"));
res.setBody("amount", fn.generateAmount("4","2"));
res.setBody("pinBlock", "" + fn.generatePinBlock("1234", req.getBody("cardNumber"), "0", "API Keys"));

Interceptor response rule (ires):

ires.setBody("traceId", fn.guid());
ires.setBody("stan", fn.generateRandomNumber("6"));

ISO 8583 rules write to numbered fields, not JSON keys:

res.setBody("2",  "" + fn.generateCard("16"));         // PAN
res.setBody("4",  "" + fn.generateRandomNumber("12")); // amount
res.setBody("11", "" + fn.generateRandomNumber("6"));  // STAN
res.setBody("52", "" + fn.generatePinBlock("1234", req.getBody("2"), "0", "API Keys")); // PIN block, format 0