diff --git a/docs/README.md b/docs/README.md index 33798d4c..a4729eaf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3239,6 +3239,27 @@ char buf[10]; mg_random(buf, sizeof(buf)); // `buf` is now random bytes ``` +### mg\_random\_str() + +```c +char *mg_random_str(char *buf, size_t len); +``` + +Fill in buffer `buf`, `len` with random alphanumeric characters: `a-zA-Z0-9`. +A buffer is zero-terminated. + +Parameters: +- `buf` - a pointer to a buffer +- `len` - a buffer size + +Return value: `buf` value. + +Usage example: +```c +char buf[10]; +printf("Random: %s\n", mg_random_str(buf, sizeof(buf))); +``` + ### mg\_ntohs() ```c diff --git a/mongoose.c b/mongoose.c index cca8d0de..dadab9ab 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5407,6 +5407,19 @@ void mg_random(void *buf, size_t len) { } #endif +char *mg_random_str(char *buf, size_t len) { + size_t i; + mg_random(buf, len); + for (i = 0; i < len; i++) { + uint8_t c = ((uint8_t *) buf)[i] % 62; + buf[i] = i == len - 1 ? '\0' // 0-terminate last byte + : c < 26 ? (char) ('a' + c) // lowercase + : c < 52 ? (char) ('A' + c - 26) // uppercase + : (char) ('0' + c - 52); // numeric + } + return buf; +} + uint32_t mg_ntohl(uint32_t net) { uint8_t data[4] = {0, 0, 0, 0}; memcpy(&data, &net, sizeof(data)); diff --git a/mongoose.h b/mongoose.h index bf6699ce..fc00967b 100644 --- a/mongoose.h +++ b/mongoose.h @@ -858,6 +858,7 @@ bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...); void mg_random(void *buf, size_t len); +char *mg_random_str(char *buf, size_t len); uint16_t mg_ntohs(uint16_t net); uint32_t mg_ntohl(uint32_t net); uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len); diff --git a/src/util.c b/src/util.c index 4dce7ed4..06b3fd7c 100644 --- a/src/util.c +++ b/src/util.c @@ -21,6 +21,19 @@ void mg_random(void *buf, size_t len) { } #endif +char *mg_random_str(char *buf, size_t len) { + size_t i; + mg_random(buf, len); + for (i = 0; i < len; i++) { + uint8_t c = ((uint8_t *) buf)[i] % 62; + buf[i] = i == len - 1 ? '\0' // 0-terminate last byte + : c < 26 ? (char) ('a' + c) // lowercase + : c < 52 ? (char) ('A' + c - 26) // uppercase + : (char) ('0' + c - 52); // numeric + } + return buf; +} + uint32_t mg_ntohl(uint32_t net) { uint8_t data[4] = {0, 0, 0, 0}; memcpy(&data, &net, sizeof(data)); diff --git a/src/util.h b/src/util.h index 5bf4b070..6b4a0860 100644 --- a/src/util.h +++ b/src/util.h @@ -5,6 +5,7 @@ #include "str.h" void mg_random(void *buf, size_t len); +char *mg_random_str(char *buf, size_t len); uint16_t mg_ntohs(uint16_t net); uint32_t mg_ntohl(uint32_t net); uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len); diff --git a/test/unit_test.c b/test/unit_test.c index 773853ba..49e261b0 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -373,7 +373,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { } static void test_mqtt_ver(uint8_t mqtt_version) { - char buf[50] = {0}; + char buf[50] = {0}, client_id[16], will_topic[16]; struct mqtt_data test_data = {buf, 0, 0}; struct mg_mgr mgr; struct mg_str topic = mg_str("x/f12"), data = mg_str("hi"); @@ -410,9 +410,9 @@ static void test_mqtt_ver(uint8_t mqtt_version) { opts.will_retain = true; opts.keepalive = 20; opts.version = mqtt_version; - opts.will_topic = mg_str("mg_will_topic"); + opts.will_topic = mg_str(mg_random_str(will_topic, sizeof(will_topic))); opts.will_message = mg_str("mg_will_messsage"); - opts.client_id = mg_str("mg_unit_test"); + opts.client_id = mg_str(mg_random_str(client_id, sizeof(client_id))); c = mg_mqtt_connect(&mgr, url, &opts, mqtt_cb, &test_data); for (i = 0; i < 300 && buf[0] == 0; i++) mg_mgr_poll(&mgr, 10); if (buf[0] != 'X') MG_INFO(("[%s]", buf));