Skip to content

QR Code Generator — C source

Turn any text or URL into a downloadable QR code. Full ISO encoder with all error-correction levels, versions 1-40, SVG and PNG export, colors and quiet-zone control — runs entirely in your browser.

This is the C implementation — the same logic the interactive tool runs, in a shareable, citable form.

/* qr-code-generator — C port: QR format information (BCH).
 *
 * Display snippet: assembling the module matrix is too long to show here;
 * this ports formatInfoString(ecLevel, mask) from the TypeScript lib
 * (src/lib/qr.ts), split into the EC-bits lookup and the BCH remainder.
 * The full encoder (modes, Reed-Solomon EC, masking, matrix) lives in the
 * TypeScript/Go sources.
 *
 * The 15-bit format string protects 5 data bits — 2 error-correction level
 * bits (L=01 M=00 Q=11 H=10) followed by the 3-bit mask pattern — with a
 * BCH(15,5) code using generator 0x537, then XORs the result with the
 * fixed 0x5412 pattern so an all-zero string is never valid.
 */
#include <stddef.h>
#include <stdint.h>

char *format_info_bch(unsigned data5, char out[16]);

/* Error-correction level indicator bits (ISO/IEC 18004 table C.1); -1 = unknown. */
static int ec_format_bits(char ec_level)
{
    switch (ec_level) {
    case 'L': return 1; /* 0b01 */
    case 'M': return 0; /* 0b00 */
    case 'Q': return 3; /* 0b11 */
    case 'H': return 2; /* 0b10 */
    default:  return -1;
    }
}

/* 15-bit format info string (MSB first) for (ec_level, mask); NULL on unknown level. */
char *format_info(char ec_level, int mask, char out[16])
{
    int bits = ec_format_bits(ec_level);
    if (bits < 0)
        return NULL;
    return format_info_bch((bits << 3) | mask, out);
}

/* 15-bit format info string (MSB first) for a 5-bit data value. */
char *format_info_bch(unsigned data5, char out[16])
{
    unsigned v = data5 << 10;
    const unsigned g = 0x537; /* BCH(15,5) generator polynomial */
    for (int i = 14; i >= 10; i--) {
        if (v & (1u << i))
            v ^= g << (i - 10); /* polynomial long division */
    }
    unsigned full = ((data5 << 10) | (v & 0x3FFu)) ^ 0x5412u; /* apply the mask pattern */
    for (int i = 14; i >= 0; i--)
        out[14 - i] = (full >> i) & 1u ? '1' : '0';
    out[15] = '\0';
    return out;
}

/* Example:
 *   format_info('L', 0, buf) -> "111011111000100" (0x77C4, matching the published tables)
 */

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 →