//
// Created by #Suyghur, on 2021/06/11.
//

#include "include/hex_utils.h"

char *HexUtils::HexEncode(const unsigned char *input, size_t len) {
    if (input == nullptr || len == 0)
        return nullptr;

    char *out = static_cast<char *>(malloc(len * 2 + 1));
    for (int i = 0; i < len; i++) {
        out[i * 2] = "0123456789abcdef"[input[i] >> 4];
        out[i * 2 + 1] = "0123456789abcdef"[input[i] & 0x0F];
    }
    out[len * 2] = '\0';
    return out;
}

int HexUtils::Hex2Char(const char hex, char *out) {
    if (out == nullptr) return 0;

    if (hex >= '0' && hex <= '9') {
        *out = (char) (hex - '0');
    } else if (hex >= 'A' && hex <= 'F') {
        *out = (char) (hex - 'A' + 10);
    } else if (hex >= 'a' && hex <= 'f') {
        *out = (char) (hex - 'a' + 10);
    } else {
        return 0;
    }
    return 1;
}

unsigned char *HexUtils::HexDecode(const char *hex) {
    if (hex == nullptr || *hex == '\0') {
        return nullptr;
    }

    size_t len = strlen(hex);
    if (len % 2 != 0) {
        return nullptr;
    }
    len /= 2;

    auto *out = static_cast<unsigned char *>(malloc(len + 1));
    memset(out, 'A', len);

    char b1;
    char b2;
    for (int i = 0; i < len; i++) {
        if (!Hex2Char(hex[i * 2], &b1) || !Hex2Char(hex[i * 2 + 1], &b2)) {
            return 0;
        }
        (out)[i] = (unsigned char) ((b1 << 4) | b2);
    }
    out[len] = '\0';
    return out;
}
