Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarEncode.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarEncode.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/core/StarEncode.cpp')
-rw-r--r--source/core/StarEncode.cpp226
1 files changed, 226 insertions, 0 deletions
diff --git a/source/core/StarEncode.cpp b/source/core/StarEncode.cpp
new file mode 100644
index 0000000..b3a8b79
--- /dev/null
+++ b/source/core/StarEncode.cpp
@@ -0,0 +1,226 @@
+#include "StarEncode.hpp"
+
+namespace Star {
+
+size_t hexEncode(char const* data, size_t len, char* output, size_t outLen) {
+ static char const hex[] = "0123456789abcdef";
+
+ len = std::min(len, outLen / 2);
+ for (size_t i = 0; i < len; ++i) {
+ output[i * 2] = hex[(data[i] & 0xf0) >> 4];
+ output[i * 2 + 1] = hex[(data[i] & 0x0f)];
+ }
+
+ return len * 2;
+}
+
+size_t hexDecode(char const* src, size_t len, char* output, size_t outLen) {
+ for (size_t i = 0; i < len / 2; ++i) {
+ if (i >= outLen)
+ return i;
+
+ uint8_t b1 = 0;
+ char c1 = src[i * 2];
+ if (c1 >= '0' && c1 <= '9')
+ b1 = c1 - '0';
+ else if (c1 >= 'A' && c1 <= 'F')
+ b1 = c1 - 'A' + 10;
+ else if (c1 >= 'a' && c1 <= 'f')
+ b1 = c1 - 'a' + 10;
+
+ uint8_t b2 = 0;
+ char c2 = src[i * 2 + 1];
+ if (c2 >= '0' && c2 <= '9')
+ b2 = c2 - '0';
+ else if (c2 >= 'A' && c2 <= 'F')
+ b2 = c2 - 'A' + 10;
+ else if (c2 >= 'a' && c2 <= 'f')
+ b2 = c2 - 'a' + 10;
+
+ *output++ = (b1 << 4) | b2;
+ }
+
+ return len / 2;
+}
+
+size_t nibbleDecode(char const* src, size_t len, char* output, size_t outLen) {
+ for (size_t i = 0; i < len; ++i) {
+ if (i >= outLen)
+ return i;
+
+ uint8_t b = 0;
+ char c = src[i];
+ if (c >= '0' && c <= '9')
+ b = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ b = c - 'A' + 10;
+ else if (c >= 'a' && c <= 'f')
+ b = c - 'a' + 10;
+
+ *output++ = b;
+ }
+
+ return len;
+}
+
+static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+size_t base64Encode(char const* data, size_t len, char* output, size_t outLen) {
+ if (outLen == 0)
+ return 0;
+ size_t written = 0;
+
+ unsigned char ca3[3] = {0, 0, 0};
+ unsigned char ca4[4] = {0, 0, 0, 0};
+ const unsigned char* inPtr = (const unsigned char*)data;
+ int i = 0, j = 0, in_len = len;
+
+ while (in_len--) {
+ ca3[i++] = *(inPtr++);
+ if (i == 3) {
+ ca4[0] = (ca3[0] & 0xfc) >> 2;
+ ca4[1] = ((ca3[0] & 0x03) << 4) + ((ca3[1] & 0xf0) >> 4);
+ ca4[2] = ((ca3[1] & 0x0f) << 2) + ((ca3[2] & 0xc0) >> 6);
+ ca4[3] = ca3[2] & 0x3f;
+ for (i = 0; (i < 4); i++) {
+ --outLen;
+ *output = base64_chars[ca4[i]];
+ ++output;
+ ++written;
+
+ if (outLen == 0)
+ return written;
+ }
+ i = 0;
+ }
+ }
+
+ if (i) {
+ for (j = i; j < 3; j++)
+ ca3[j] = '\0';
+ ca4[0] = (ca3[0] & 0xfc) >> 2;
+ ca4[1] = ((ca3[0] & 0x03) << 4) + ((ca3[1] & 0xf0) >> 4);
+ ca4[2] = ((ca3[1] & 0x0f) << 2) + ((ca3[2] & 0xc0) >> 6);
+ ca4[3] = ca3[2] & 0x3f;
+ for (j = 0; (j < i + 1); j++) {
+ --outLen;
+ *output = base64_chars[ca4[j]];
+ ++output;
+ ++written;
+
+ if (outLen == 0)
+ return written;
+ }
+ while ((i++ < 3)) {
+ --outLen;
+ *output = '=';
+ ++output;
+ ++written;
+
+ if (outLen == 0)
+ return written;
+ }
+ }
+
+ return written;
+}
+
+static inline bool is_base64(unsigned char c) {
+ return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+size_t base64Decode(char const* src, size_t len, char* output, size_t outLen) {
+ if (outLen == 0)
+ return 0;
+
+ size_t written = 0;
+
+ int i = 0, j = 0, in_ = 0, in_len = len;
+ unsigned char ca4[4], ca3[3];
+
+ while (in_len-- && (src[in_] != '=') && is_base64(src[in_])) {
+ ca4[i++] = src[in_++];
+ if (i == 4) {
+ for (i = 0; i < 4; i++)
+ ca4[i] = base64_chars.find(ca4[i]);
+ ca3[0] = (ca4[0] << 2) + ((ca4[1] & 0x30) >> 4);
+ ca3[1] = ((ca4[1] & 0xf) << 4) + ((ca4[2] & 0x3c) >> 2);
+ ca3[2] = ((ca4[2] & 0x3) << 6) + ca4[3];
+ for (i = 0; (i < 3); i++) {
+ --outLen;
+ *output = ca3[i];
+ ++output;
+ ++written;
+
+ if (outLen == 0)
+ return written;
+ }
+ i = 0;
+ }
+ }
+
+ if (i) {
+ for (j = i; j < 4; j++)
+ ca4[j] = 0;
+ for (j = 0; j < 4; j++)
+ ca4[j] = base64_chars.find(ca4[j]);
+ ca3[0] = (ca4[0] << 2) + ((ca4[1] & 0x30) >> 4);
+ ca3[1] = ((ca4[1] & 0xf) << 4) + ((ca4[2] & 0x3c) >> 2);
+ ca3[2] = ((ca4[2] & 0x3) << 6) + ca4[3];
+ for (j = 0; (j < i - 1); j++) {
+ --outLen;
+ *output = ca3[j];
+ ++output;
+ ++written;
+
+ if (outLen == 0)
+ return written;
+ }
+ }
+
+ return written;
+}
+
+String hexEncode(char const* data, size_t len) {
+ std::string res(len * 2, '\0');
+ size_t encoded = hexEncode(data, len, &res[0], res.size());
+ _unused(encoded);
+ starAssert(encoded == res.size());
+ return move(res);
+}
+
+String base64Encode(char const* data, size_t len) {
+ std::string res(len * 4 / 3 + 3, '\0');
+ size_t encoded = base64Encode(data, len, &res[0], res.size());
+ _unused(encoded);
+ starAssert(encoded <= res.size());
+ res.resize(encoded);
+ return move(res);
+}
+
+String hexEncode(ByteArray const& data) {
+ return hexEncode(data.ptr(), data.size());
+}
+
+ByteArray hexDecode(String const& encodedData) {
+ ByteArray res(encodedData.size() / 2, 0);
+ size_t decoded = hexDecode(encodedData.utf8Ptr(), encodedData.size(), res.ptr(), res.size());
+ _unused(decoded);
+ starAssert(decoded == res.size());
+ return res;
+}
+
+String base64Encode(ByteArray const& data) {
+ return base64Encode(data.ptr(), data.size());
+}
+
+ByteArray base64Decode(String const& encodedData) {
+ ByteArray res(encodedData.size() * 3 / 4, 0);
+ size_t decoded = base64Decode(encodedData.utf8Ptr(), encodedData.size(), res.ptr(), res.size());
+ _unused(decoded);
+ starAssert(decoded <= res.size());
+ res.resize(decoded);
+ return res;
+}
+
+}