Requires C++23 (e.g.,
-std=c++23for GCC/Clang,/std:c++latestfor MSVC).
API Reference · Usage Guide · Data and Method · Releases
Devices, browsers, user agents and IP addresses that fit together: a phone model that was on sale at the date, running an OS version it supports, a browser that runs on that OS at a version released by then, the user-agent string that exact combination sends, its screen, and an address registered in the person's country.
Chrome 114 on Android 13 (Samsung Galaxy A14), 178.46.39.249
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36
-
Everything Agrees. The model came out before the reference date, the OS version is one the model runs, the browser runs on that OS version (Chrome 110 and later need Windows 10; Safari only on Apple systems; every iOS browser is WebKit), and versions are those released by the date, with newer ones spreading as they really do.
-
Real User Agents. Strings follow each browser's format at that version: Chrome's reduced user agent from version 110 on Android (
Android 10; K), the minor-version zeros from 101, Apple's frozen18_6token from iOS 26,CriOS,FxiOSandEdgiOSon iOS, iPad Safari asking for the desktop site. Chrome, Safari, Edge, Firefox, Samsung Internet, Opera and Yandex Browser. Checked against ua-parser, which reads back the browser, its major version and the OS for every generated string. -
Client Hints. Chrome and Edge also get the
Sec-CH-UA,Sec-CH-UA-MobileandSec-CH-UA-Platformheaders they send with every request, with the brand list ordered and spelled by the version as Chromium does it ("Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"). -
Real Addresses, or Safe Ones. IPv4 and IPv6 addresses come from the blocks the five regional registries list for the country, weighted by size, never from special-purpose ranges.
safegives documentation addresses only (RFC 5737, RFC 3849), so test data reaches no one. -
Any Date. A
reference_datefrom 2021 on picks the devices, OS and browser versions of that day, and maker and browser shares follow their trends (Huawei's fall outside China, Edge's rise on Windows); the library never reads the clock. -
Ask for What You Need. A
device_requestcan fix the country, the platform (user-generator's keys), the kind, the browser, the IP family and the locale (forAccept-Language). What is left out is drawn, and fixing one part leaves the others' draws unchanged. -
Deterministic Seeding. Per-call
get_device(request, seed)for reproducible results, anddevice::seed()for replaying a previous generation with the same request and data. -
Batch Generation. Generate thousands of results from one seed, on several threads with the same output for any thread count, optionally unique by a key such as the IP, and stream them as JSON Lines or CSV (see the usage guide).
-
Identical Everywhere. A seed gives the same result on every compiler, standard library and CPU (GCC, Clang, MSVC, Emscripten; x86-64 and ARM64), checked by known-answer tests.
-
Extensible Data. Sixteen TSV tables (models, releases, shares, user-agent templates, IP blocks, ...) that you can extend with layers (
extend()), checked before they are applied. -
JSON and Replay.
to_json()on every result, and asignature()recording the seed and the data it came from. -
Compiled-in Data. Define
DASMIG_DEVICE_EMBEDto build thelitetier into the program, for WebAssembly and other builds without files. -
Multi-Instance Support. Construct independent
dvginstances with their own data and random engine.
devicegen.hpp is the library released here. Keep core.hpp and the core/ directory (dasmig-core) in the same directory. Add
#include <dasmig/devicegen.hpp>to the files you want to use it in, and supply the resources folder (or define DASMIG_DEVICE_EMBED).
#include <dasmig/devicegen.hpp>
#include <iostream>
auto& gen = dasmig::dvg::instance(); // loads the lite tier
auto d = gen.get_device(dasmig::device_request{});
std::cout << d << '\n'; // Chrome 114 on Android 13 (Samsung Galaxy A14), 178.46.39.249
std::cout << d.user_agent << '\n'; // the User-Agent header
std::cout << d.to_json() << '\n'; // every field, with the seed
dasmig::device_request request;
request.country = "BR";
request.platform = "ios-phone"; // user-generator's platform keys
request.locale = "pt-BR"; // Accept-Language: pt-BR,pt;q=0.9,en;q=0.8
request.reference_date = std::chrono::year{2026} / 10 / 1;
request.safe = true; // a documentation address
auto iphone = gen.get_device(request, 42);
// The same seed gives the same result everywhere.
auto again = gen.get_device(request, iphone.seed());See the usage guide for everything else.
make # example
make test # tests
make bench # benchmarks, results in build/bench.tsv
make test-embed # tests with the lite tier compiled in
make coverage # code coverage
make lint # clang-tidy
make docs # API docs
make embed # regenerate dasmig/devicegen_data.hpp from resources/liteTested with:
- Clang 18+ (
-std=c++23) - GCC 14+ (
-std=c++23) - MSVC 19.38+ (
/std:c++latest) - Emscripten 3.1.74
| Dependency | Version | Bundled | Purpose |
|---|---|---|---|
| dasmig-core | 1.4 | Yes (core.hpp, core/) |
Platform-independent random engine and distributions, data layers, JSON |
| Catch2 | 3.x | Yes (amalgamated) | Unit testing |
| Library | Description |
|---|---|
| address-generator | Postal addresses with real streets by place |
| biodata-generator | Procedural human physical characteristics |
| birth-generator | Demographically plausible birthdays |
| city-generator | Weighted city selection by population |
| country-generator | Weighted country selection by population |
| email-generator | Email addresses in each country's style |
| entity-generator | ECS-based entity generation |
| interest-generator | Religion, hobbies and favourite media by country, age and sex |
| name-generator | Culturally appropriate full names |
| nickname-generator | Gamer-style nicknames |
| occupation-generator | Employment status, education and occupation by country, age and sex |
| persona-generator | Complete characters composed from the other generators |
| phone-generator | Phone numbers valid in each country's numbering plan |
| relationship-generator | Families around a person: parents, siblings, partners and children |
| trait-generator | Personality traits with conflicts, synergies and Big Five axes |
| user-generator | Complete user records: account, username, email, phone and address |
This library is released under the MIT License. The data's sources are listed in LICENSE_DATA.txt and doc/data.md.
MIT License
Copyright (c) 2026 Diego Dasso Migotto
