Skip to content

Password Generator — C++ source

Generate cryptographically-random passwords with a CSPRNG using rejection sampling (no modulo bias). Shows live entropy in bits, a 5-tier strength meter, average offline-GPU crack time, and a Pro mode with the entropy formula, a crack-time-vs-length curve, and a 4-scenario attack table. Everything runs locally - nothing is sent anywhere.

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

// password-generator — CSPRNG password generation + entropy scoring. Language: C++ (C++17; /dev/urandom — std::random_device is not guaranteed to be a CSPRNG). Port of src/lib/password.ts.

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
namespace {
const std::string LOWER = "abcdefghijklmnopqrstuvwxyz", UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const std::string NUMBERS = "0123456789", SYMBOLS = "!@#$%^&*()-_=+[]{};:,.<>?/";
const std::string AMBIGUOUS = "O0Il1|"; // O/0, I/l/1, pipe — dropped on request
struct PasswordOptions {
    int length;
    bool upper = false, lower = false, numbers = false, symbols = false;
    bool excludeAmbiguous = false;
};
// One uint32 from the OS CSPRNG — the kernel entropy source, read directly.
uint32_t secure_u32()
{
    uint32_t v = 0;
    std::ifstream("/dev/urandom", std::ios::binary).read(reinterpret_cast<char *>(&v), sizeof v);
    return v;
}
// Concat the selected pools, then drop ambiguous glyphs (mirrors buildCharset).
std::string build_charset(const PasswordOptions &o)
{
    std::string cs;
    if (o.lower) cs += LOWER;
    if (o.upper) cs += UPPER;
    if (o.numbers) cs += NUMBERS;
    if (o.symbols) cs += SYMBOLS;
    if (o.excludeAmbiguous)
        cs.erase(std::remove_if(cs.begin(), cs.end(),
                     [&](char c) { return AMBIGUOUS.find(c) != std::string::npos; }),
                 cs.end());
    return cs;
}
// Uniform index in [0, n): reject uint32 CSPRNG draws >= the largest multiple
// of n fitting in 2^32, so `% n` carries no modulo bias.
size_t unbiased_index(size_t n)
{
    const uint64_t MAX = 1ULL << 32;
    uint64_t limit = MAX - MAX % n, r;
    do { r = secure_u32(); } while (r >= limit);
    return static_cast<size_t>(r % n);
}
// Returns "" for an empty pool or length < 1 — same contract as the TS lib.
std::string generate_password(const PasswordOptions &o)
{
    std::string cs = build_charset(o);
    if (cs.empty() || o.length < 1) return "";
    std::string pw;
    pw.reserve(o.length);
    for (int i = 0; i < o.length; i++) pw.push_back(cs[unbiased_index(cs.size())]);
    return pw;
}
// Theoretical entropy in bits: length * log2(|alphabet|).
double entropy_bits(int length, size_t charset_size)
{
    return (length <= 0 || charset_size <= 1) ? 0.0 : length * std::log2(charset_size);
}
// Strength meter tiers, 1:1 with the TS thresholds.
const char *strength_tier(double bits)
{
    return bits >= 100 ? "very strong" : bits >= 70 ? "strong"
         : bits >= 45 ? "fair" : bits >= 28 ? "weak" : "very weak";
}
} // namespace

int main()
{
    PasswordOptions o{20, true, true, true, true, true};
    std::string cs = build_charset(o);
    double bits = entropy_bits(o.length, cs.size());
    std::cout << generate_password(o) << " — " << bits << " bits, " << strength_tier(bits) << "\n";
    return 0;
}

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 →