JWT Debugger — C++ source
Decode a JSON Web Token and inspect its header and payload as pretty JSON, with exp/iat claim awareness and an expiry badge. Runs entirely in your browser.
This is the C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.
// JWT base64url decoding helper — C++ (C++20) port of the jwt tool.
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>
namespace jwt {
// Decode a base64url segment (JWT header/payload) to a byte-faithful string.
// The C++ standard library has no base64 codec, so the decoder is carried
// here. Throws std::invalid_argument on input outside the base64url
// alphabet — the TS throw analogue. std::string is byte-oriented, so the
// result keeps each decoded byte as one character, mirroring JS atob.
std::string b64urlDecode(std::string_view str) {
// 1. URL-safe alphabet -> standard base64 alphabet.
std::string s(str);
for (char &c : s) {
if (c == '-') c = '+';
else if (c == '_') c = '/';
}
// 2. Restore stripped '=' padding so the length is a multiple of 4.
if (s.size() % 4 == 1) throw std::invalid_argument("invalid base64url length");
s.append((4 - s.size() % 4) % 4, '=');
// 3. Strict decode: 4-char blocks -> 3 bytes, validating every char.
auto index = [](char c) -> int {
if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return -1; // '=' is only legal as the final 1-2 chars
};
std::string out;
out.reserve(s.size() / 4 * 3);
for (size_t q = 0; q < s.size(); q += 4) {
int v[4] = {0, 0, 0, 0};
int pad = 0;
for (int k = 0; k < 4; ++k) {
char c = s[q + k];
if (c == '=') { ++pad; continue; }
if (pad != 0 || (v[k] = index(c)) < 0)
throw std::invalid_argument("invalid base64url input");
}
if (pad > 2 || (pad != 0 && q + 4 != s.size()))
throw std::invalid_argument("invalid base64url padding");
unsigned triple = ((unsigned)v[0] << 18) | ((unsigned)v[1] << 12) |
((unsigned)v[2] << 6) | (unsigned)v[3];
out += static_cast<char>(triple >> 16);
if (pad < 2) out += static_cast<char>(triple >> 8);
if (pad < 1) out += static_cast<char>(triple);
}
// 4. Bytes are kept byte-faithful (std::string is a byte buffer).
return out;
}
} // namespace jwt
int main() {
// eyJhbGciOiJIUzI1NiJ9 decodes to {"alg":"HS256"}
std::cout << jwt::b64urlDecode("eyJhbGciOiJIUzI1NiJ9") << '\n';
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →