LW IT Solutions
« Blog Overview /Data Privacy / Reading a TC String: What Sits in...
This post in other languages:

Reading a TC String: What Sits in the 213 Header Bits

Reading a TC String: What Sits in the 213 Header Bits
Contents
  1. How the String Is Packed
  2. The 213 Bits of the Header
  3. Why One String Is Short and the Next Is Endless
  4. What TCF 2.2 Turned Into an Error
  5. The Segments After the Core
  6. What This Settles in Practice

Arguments about consent usually run on assertions: the banner was configured this way, the vendor list is current, the string is fresh. All three are written down, in a cookie called euconsent-v2, and none of them needs to be argued about – because the string is not encrypted. It is packed, and unpacking it takes no key.

What follows is the layout of that packing. It is worth knowing not for its own sake but because reading a string settles in half a minute what otherwise turns into a discussion with a vendor: whether the CMP wrote what the dialogue promised, when it last did so, and against which version of the vendor list.

The core segment of a TC string as a bit strip: version, two timestamps, CMP fields, language, vendor list version and policy version, followed by the special features, purposes and legitimate interest bit fields and the vendor section
The core segment, bit by bit: 213 bits of header, then purposes and vendors.

How the String Is Packed

A TC string is a sequence of fields of fixed bit length, written one after another without separators, and then encoded in web-safe base64 – the variant that uses a dash and an underscore instead of the two characters that would need escaping in a URL. Each character carries exactly six bits.

That is why every TC string in the wild starts with the letter C: the first field is the version, six bits wide, and version 2 written in six bits is 000010, which is the character at position 2 in the alphabet. A string that starts with anything else is either not a TC string or not version 2, and both are worth noticing before anything else is read.

The 213 Bits of the Header

Everything up to the vendors sits in a fixed layout, which is what makes it readable without a library.

Field Bits What it settles
Version 6 Always 2 in practice; anything else does not belong to this format.
Created, LastUpdated 36 each Tenths of a second since 1970 – the age of the consent, to the second.
CmpId, CmpVersion 12 each Which CMP wrote the string, in which build.
VendorListVersion 12 The version of the global vendor list the dialogue was built from.
TcfPolicyVersion 6 4 and above means the string follows the TCF 2.2 rules.
SpecialFeatureOptIns 12 Precise location and device scanning, as two of twelve possible bits.
PurposesConsent, PurposesLI 24 each Eleven defined purposes, twice: consent and legitimate interest.

Together with the consent screen number, the two-letter language, the service-specific flag and the publisher country, that comes to 213 bits. From bit 214 onwards the vendors begin, and there the length stops being fixed.

Why One String Is Short and the Next Is Endless

Vendors are stored in one of two ways, and the string chooses per section. Either as a bit field, one bit per vendor up to the highest identifier – which costs 1200 bits when the list runs that far, regardless of how many vendors were actually agreed to. Or as ranges: a count, then a start and an end per range, sixteen bits each.

A visitor who agrees to everything produces a compact string, because the whole list collapses into a handful of ranges. A visitor who picks fifty vendors out of eight hundred produces the long one, because every isolated choice becomes its own range. The length of the cookie therefore says something about the shape of the decision, and nothing at all about how permissive it was.

What TCF 2.2 Turned Into an Error

Three things are worth checking in every string, and all three became firm rules rather than opinions with policy version 4.

Legitimate interest is no longer permitted for purposes 1, 3, 4, 5 and 6. A string that carries those bits was either produced under the old policy or written by a CMP that has not followed the change – and the bit is not harmless, because vendors read it as a basis for processing.

Purposes 12 to 24 exist in the format but not in the specification. Bits set there mean a CMP is writing into fields that no one defines, which is the clearest sign of a hand-rolled implementation.

And the age: the update timestamp is in the string, so a consent older than thirteen months can be recognised from the cookie alone. Together with the vendor list version, that answers the question of whether a dialogue is showing vendors the visitor has never been asked about – because the list grows, and a string written against an older version simply has nothing to say about the newcomers.

The Segments After the Core

A string can carry more than one segment, separated by dots, and each additional one begins with three bits naming its type. Type 1 lists the vendors that were disclosed on the device, type 3 carries the publisher’s own purposes – the ones a site may add for itself. Type 2 was the allowed-vendors segment and is gone in 2.2.

Anything past the first dot is therefore optional, and its absence is not a fault. What is a fault is a second segment that no one can decode because a proxy truncated the cookie at a length limit, which is the usual explanation for a string that reads correctly up to a point and then stops.

What This Settles in Practice

Three questions come up in almost every consent review, and the string answers all of them without anyone’s cooperation. Whether the CMP wrote what the dialogue promised – by comparing the purpose bits against the choices made. Whether the setup is current – by the policy version and the vendor list version. And whether a visitor is being carried on a decision from another era – by the update timestamp.

None of that replaces a look at the dialogue itself, and the string says nothing about whether a vendor honours it. But it turns three assertions into three readings, and that is usually enough to end the part of the discussion that was never about facts.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

ALL ARTICLES & CATEGORIES

CCTV

Follow this category by RSS

Data Privacy

Follow this category by RSS

Digital Analytics

Follow this category by RSS

Digital Marketing

Follow this category by RSS

IT & Networks

Follow this category by RSS

Raspberry PI

Follow this category by RSS

Smart Home

Follow this category by RSS

Web Development

Follow this category by RSS

Wordpress Hacks

Follow this category by RSS