#include #include #include typedef struct { char* data; int length; } Message; Message* msg_create(const char* data, int length) { Message* m = (Message*)malloc(sizeof(Message)); m->data = (char*)malloc(length + 1); memcpy(m->data, data, length); m->data[length] = '\0'; m->length = length; return m; } void msg_free(Message* m) { free(m->data); free(m); } char* msg_to_hex(Message* m) { char* hex = (char*)malloc(m->length * 2 + 1); for (int i = 0; i < m->length; i++) { sprintf(hex + i * 2, "%02x", (unsigned char)m->data[i]); } hex[m->length * 2] = '\0'; return hex; } Message* msg_from_hex(const char* hex) { int len = strlen(hex); int data_len = len / 2; char* data = (char*)malloc(data_len); for (int i = 0; i < data_len; i++) { sscanf(hex + i * 2, "%2hhx", &data[i]); } return msg_create(data, data_len); } char* msg_to_base64(Message* m) { static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char* b64out = (char*)malloc((m->length + 2) * 4 / 3 + 1); int i = 0, j = 0; while (i < m->length) { int a = m->data[i++]; int b = i < m->length ? m->data[i++] : 0; int c = i < m->length ? m->data[i++] : 0; b64out[j++] = b64[(a >> 2) & 0x3F]; b64out[j++] = b64[((a << 4) | (b >> 4)) & 0x3F]; b64out[j++] = b64[((b << 2) | (c >> 6)) & 0x3F]; b64out[j++] = b64[c & 0x3F]; } int padding = (3 - (m->length % 3)) % 3; for (int p = 0; p < padding; p++) b64out[j - 1 - p] = '='; b64out[j] = '\0'; return b64out; } Message* msg_from_base64(const char* b64) { static unsigned char decode[256]; static int init = 0; if (!init) { memset(decode, 0xFF, 256); const char* b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; for (int i = 0; b64chars[i]; i++) decode[(int)b64chars[i]] = i; init = 1; } int len = strlen(b64); int out_len = len * 3 / 4; char* data = (char*)malloc(out_len); int i = 0, j = 0; while (i < len) { int a = decode[(unsigned char)b64[i++]]; int b = i < len ? decode[(unsigned char)b64[i++]] : 0; int c = i < len ? decode[(unsigned char)b64[i++]] : 0; int d = i < len ? decode[(unsigned char)b64[i++]] : 0; if (a < 0 || b < 0) continue; data[j++] = (a << 2) | (b >> 4); if (c < 0xFF) data[j++] = (b << 4) | (c >> 2); if (d < 0xFF) data[j++] = (c << 6) | d; } return msg_create(data, j); } int msg_get_length(Message* m) { return m->length; } char* msg_get_data(Message* m) { return m->data; }