Why every certificate carries a code you can check
A certificate is a claim about something that already happened. On its own it is a picture of a claim — and anyone with a design tool can make one of those in an afternoon. What separates a credential from a nicely typeset PDF is whether somebody who was not there can confirm it without asking you to vouch for yourself.
So every DesignSense certificate and every DesignSense License carries a code, and there is a page at /verify where anyone can enter it. No account. No contact form. You give the code to a client or an employer, they type it in, and they see who it belongs to and what it was awarded for.
That page is the product's actual claim. This is how the code behind it is built.
The shape
A certificate code looks like DS- followed by twelve characters in three groups of four. A License code starts DSL- instead. Both resolve against the same registry — the prefixes exist so that support can tell at a glance which one somebody is holding.
The alphabet is Crockford base32: the digits, and the letters minus I, L, O and U. Dropping those four is not an aesthetic decision. A credential code gets read aloud down a phone line, copied off a printed page, and retyped by somebody who is already irritated that they had to. Take out I and L and the confusion with the digit 1 goes with them. Take out O and the confusion with zero goes. U leaves for a different reason: without it, a random string is very unlikely to spell something regrettable.
Grouping in fours is the same kind of decision. Nobody reads twelve characters as twelve characters; they read them as three chunks, and they lose their place in the middle of an ungrouped string.
Two check characters, and why one is not enough
Ten of those twelve characters are random. The last two are a checksum, and there are two of them because of an arithmetic fact that is easy to miss.
A checksum over this alphabet works modulo 32. It needs to catch the two mistakes people actually make: changing one character, and swapping two neighbours.
With a single check character you get one weighted sum, and you cannot have both. Give the positions even weights and a substitution can slip through — 32 is a power of two, so an error of 16 in a position weighted 2 changes the sum by 32, which is to say by nothing. A full one-in-sixteen of single-character typos would sail past. Make every weight odd and substitutions are caught, but transposition detection breaks: catching a swap requires consecutive weights to differ by an odd amount, and consecutive odd numbers differ by an even one. The two requirements are mutually exclusive. This is not an implementation difficulty to be worked around; it is a property of the modulus.
Two characters resolve it, because two characters give you two independent invariants. The code is generated so that both hold across the whole string:
- The plain sum of the character values is zero, modulo 32. Change any single character and exactly one term moves, so the sum moves with it. That catches every single-character substitution.
- The position-weighted sum is zero, modulo 32. Swapping two adjacent characters leaves the plain sum untouched but shifts this one by the difference between them — non-zero whenever the two characters differ, which is the only case where a swap is a mistake at all. That catches every adjacent transposition.
The invariants are defined over the complete code rather than the random part alone, and that detail earns its keep: it is what catches a transposition straddling the last random character and the first check character, which a checksum computed over the body only lets straight through.
What the check characters are not
They are not security. A checksum stops a typo from being reported to somebody as "this certificate does not exist" when what actually happened is that they mistyped their own credential. It does nothing against a person who is trying.
What stands against that is the size of the space and where the codes come from. Ten random characters over a 32-symbol alphabet is about 1.1 quadrillion possibilities, and they are drawn from a cryptographic random source rather than a counter or a timestamp. A guessable code would let anyone mint a credential the platform never issued, which would make the registry worthless — so the generator does not use the ordinary random function, and the module that does the generating is deliberately kept separate from the one the browser loads to check a typed code.
Certificates and Licenses answer different questions
A course certificate records that you passed a final on a date. That fact does not change afterwards, so verification shows the holder, the course, and the date.
The DesignSense License is a professional credential valid for thirty months, and it is renewable. It can also lapse, and it can be withdrawn. A page that only said it had once been awarded would be answering the wrong question — the question an employer is asking is whether it is valid now. So a License verification shows current status and expiry date alongside everything else.
Public, but not a directory
The verification page is public and it is deliberately not indexed by search engines.
Those two things sit together more comfortably than they look. A credential should be checkable by whoever is holding the code: that is the point of issuing one. A searchable public list of every person who holds a credential is a different thing entirely, and nobody consented to being in it. Anyone with the code can check it; nobody without it can browse the registry.
The standard this sets
Everything above is checkable, which is the only reason it is worth writing down. The code format, the two invariants, and the reason there are two of them are all in the source — the checksum logic sits in one dependency-free module so that the same rules run in your browser and on our server, and it has tests that assert the invariants hold for randomly generated codes rather than for a handful of examples.
That is the bar the rest of the platform is held to. When we say a lab is graded by a person, there is a submission row with a grader on it. When we say an exam is proctored, there are proctoring events recorded against the attempt. And when we say a certificate can be verified, there is a page, a code, and a checksum that will tell you when you have mistyped it.