When a counterparty asks for "the log", you need to strip client IDs, account numbers and names first. Find-and-replace sounds enough, but it silently corrupts the session, because every FIX message carries two integrity fields that depend on the exact bytes.
The two fields
- BodyLength (9) is the number of bytes after the SOH that ends the 9= field, up to and including the SOH before 10=.
- CheckSum (10) is the sum of every byte from 8= through that same SOH, modulo 256, written as three digits.
Change 1=ACC-77812 to 1=ACCT_1 and both are now wrong. The receiving engine, or the vendor's parser, rejects or drops the message.
Recomputing them
const SOH = '\x01';
const enc = new TextEncoder();
// fields: [tag, value] pairs, excluding 8, 9 and 10
function finalize(fields, beginString = 'FIX.4.4') {
const body = fields.map(([t, v]) => `${t}=${v}${SOH}`).join('');
const head = `8=${beginString}${SOH}9=${enc.encode(body).length}${SOH}`;
let sum = 0;
for (const b of enc.encode(head + body)) sum += b;
return `${head}${body}10=${String(sum % 256).padStart(3, '0')}${SOH}`;
}
The five traps
- Bytes, not characters. A replacement containing é or ü is two bytes in UTF-8, so count bytes, as the code above does.
-
The display delimiter. Logs often show
|or^A. Always compute over a real SOH (0x01), then convert back for display. - Consistent tokens. Map each real value to the same pseudonym everywhere. Otherwise ClOrdID (11) and OrigClOrdID (41) no longer link a cancel to its order.
- Length-prefixed fields. RawDataLength (95), XmlDataLen (212) and similar describe the next field. If you change the data, update the length too.
- Repeating groups. NoPartyIDs (453) groups hold PartyID (448) values that are often the most sensitive data in the message. Don't skip them because they are nested.
Try it
SafeFIX does this in the browser: it pseudonymizes accounts, IDs, names and free text, keeps the token map local, and recomputes 9 and 10 for every message. Free for 100 lines. Synthetic logs to test any anonymizer against: fix-iso20022-samples.
Disclosure: I built SafeFIX.
Top comments (0)