ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
strings.c
Go to the documentation of this file.
1
6#include "acds/strings.h"
7#include "log/logging.h"
8#include <sodium.h>
9#include <string.h>
10#include <ctype.h>
11
12// Embedded wordlists (minimal for now - ~100 words each)
13// Future: Load from wordlists/adjectives.txt and wordlists/nouns.txt
14
15static const char *adjectives[] = {
16 "swift", "quiet", "bright", "gentle", "bold", "calm", "dark", "free", "golden", "happy",
17 "icy", "jolly", "kind", "lively", "noble", "proud", "rapid", "silver", "tall", "warm",
18 "wild", "wise", "young", "brave", "clever", "eager", "fair", "great", "huge", "just",
19 "keen", "lucky", "mild", "neat", "open", "pure", "quick", "red", "safe", "true",
20 "vast", "white", "yellow", "zealous", "amber", "blue", "cool", "deep", "easy", "fast",
21 "good", "high", "jade", "long", "new", "old", "pink", "rich", "slow", "thin",
22 "vivid", "wide", "zenithed", "assured", "clear", "divine", "ethereal", "firm", "grand", "honest",
23 "iron", "jade", "keen", "loyal", "mellow", "noble", "open", "prime", "quiet", "radiant",
24 "serene", "tranquil", "unique", "vibrant", "warm", "xenial", "youthful", "zestful", "agile", "brilliant",
25 "crisp", "deft", "elegant", "fluid", "graceful", "humble", "intense", "jovial", "kinetic", "lucid",
26 "mystic", "nimble", "ornate", "placid"};
27
28static const char *nouns[] = {
29 "river", "mountain", "forest", "ocean", "valley", "peak", "lake", "hill", "meadow",
30 "canyon", "delta", "ridge", "cliff", "shore", "stream", "bay", "cove", "dune",
31 "field", "grove", "isle", "marsh", "plain", "reef", "stone", "trail", "vista",
32 "wave", "aurora", "beacon", "cloud", "dawn", "ember", "flame", "glow", "horizon",
33 "island", "jungle", "moon", "nebula", "oasis", "planet", "quasar", "star", "thunder",
34 "universe", "volcano", "wind", "crystal", "diamond", "echo", "frost", "glacier", "harbor",
35 "iceberg", "jade", "keystone", "lagoon", "mesa", "nexus", "orbit", "prism", "quartz",
36 "reef", "summit", "temple", "umbra", "vertex", "waterfall", "xenolith", "zenith", "abyss",
37 "bridge", "castle", "dome", "echo", "fountain", "garden", "haven", "inlet", "mesa",
38 "obelisk", "portal", "quarry", "rapids", "sanctuary", "tower", "vault", "whirlpool", "asylum",
39 "bastion", "citadel", "fortress", "sanctuary", "stronghold", "threshold"};
40
41static const size_t adjectives_count = sizeof(adjectives) / sizeof(adjectives[0]);
42static const size_t nouns_count = sizeof(nouns) / sizeof(nouns[0]);
43
45 // libsodium's randombytes is already initialized by sodium_init()
46 // which should be called at program startup
47 if (sodium_init() < 0) {
48 return SET_ERRNO(ERROR_CRYPTO_INIT, "Failed to initialize libsodium");
49 }
50
51 log_debug("Session string generator initialized (%zu adjectives, %zu nouns)", adjectives_count, nouns_count);
52 return ASCIICHAT_OK;
53}
54
55asciichat_error_t acds_string_generate(char *output, size_t output_size) {
56 if (!output || output_size < 48) {
57 return SET_ERRNO(ERROR_INVALID_PARAM, "output buffer must be at least 48 bytes");
58 }
59
60 // Pick random adjective
61 uint32_t adj_idx = randombytes_uniform((uint32_t)adjectives_count);
62 const char *adj = adjectives[adj_idx];
63
64 // Pick two random nouns
65 uint32_t noun1_idx = randombytes_uniform((uint32_t)nouns_count);
66 uint32_t noun2_idx = randombytes_uniform((uint32_t)nouns_count);
67 const char *noun1 = nouns[noun1_idx];
68 const char *noun2 = nouns[noun2_idx];
69
70 // Format: adjective-noun-noun
71 int written = snprintf(output, output_size, "%s-%s-%s", adj, noun1, noun2);
72 if (written < 0 || (size_t)written >= output_size) {
73 return SET_ERRNO(ERROR_BUFFER_OVERFLOW, "Session string too long for buffer");
74 }
75
76 log_debug("Generated session string: %s", output);
77 return ASCIICHAT_OK;
78}
79
80bool acds_string_validate(const char *str) {
81 if (!str) {
82 return false;
83 }
84
85 size_t len = strlen(str);
86 if (len == 0 || len > 47) {
87 return false;
88 }
89
90 // Must not start or end with hyphen
91 if (str[0] == '-' || str[len - 1] == '-') {
92 return false;
93 }
94
95 // Count hyphens and validate characters
96 int hyphen_count = 0;
97 for (size_t i = 0; i < len; i++) {
98 char c = str[i];
99 if (c == '-') {
100 hyphen_count++;
101 // No consecutive hyphens
102 if (i > 0 && str[i - 1] == '-') {
103 return false;
104 }
105 } else if (!islower(c)) {
106 // Only lowercase letters and hyphens allowed
107 return false;
108 }
109 }
110
111 // Must have exactly 2 hyphens (3 words)
112 return hyphen_count == 2;
113}
unsigned int uint32_t
Definition common.h:58
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
@ ASCIICHAT_OK
Definition error_codes.h:48
@ ERROR_CRYPTO_INIT
Definition error_codes.h:55
@ ERROR_INVALID_PARAM
@ ERROR_BUFFER_OVERFLOW
Definition error_codes.h:98
#define log_debug(...)
Log a DEBUG message.
📝 Logging API with multiple log levels and terminal output control
asciichat_error_t acds_string_init(void)
Initialize random number generator for string generation.
Definition strings.c:44
bool acds_string_validate(const char *str)
Validate session string format.
Definition strings.c:80
asciichat_error_t acds_string_generate(char *output, size_t output_size)
Generate random session string.
Definition strings.c:55
Session string generation for discovery service.