C/C++ 0x20 ~ 0x7e 可打印字节编码二进制加解密算法,仅供参考,感兴趣的朋友欢迎提供可改善意见。

用处巨大,自行领悟。 

#include <iostream>
#include <cstdint>
#include <string>
#include <vector>
#include <Windows.h>

using namespace std;

/* 96 printable characters(include tab)	*/
/* remove \ for compatibility			*/
/* remove tab for uniformity			*/
/* luckly, 11/9 > log(256)/log(94)		*/

enum
{
    BASE94_SYMBOL_COUNT = 94,
    BASE94_INPUT_BLOCK_SIZE = 9,
    BASE94_OUTPUT_BLOCK_SIZE = 11,
};

static constexpr void base94_decimalToBase94(uint64_t num, uint64_t base94[10], int& base94_size)
{
    uint64_t n = num;
    base94_size = 0;
    do {
        n /= 94;
        base94_size++;
    } while (n > 0);

    int k = 0;
    n = num;
    do {
        uint64_t c = (n % 94) + 0x20;
        n /= 94;
        base94[base94_size - ++k] = c;
    } while (n > 0);
}

static constexpr uint64_t base94_base94ToDecimal(uint8_t*& p, int size)
{
    uint64_t n = 0;
    for (uint8_t* k = p + size; p != k; )
    {
        uint8_t v = (*p++ - 0x20);
        n = n * 94 + v;
    }
    return n;
}

template <typename T>
static constexpr void base94_decimalToBase94(std::vector<uint8_t>& bytes, uint8_t*& p, int mode)
{
    uint64_t base94[BASE94_OUTPUT_BLOCK_SIZE];
    int base94_size;
    base94_decimalToBase94(*(T*)p, base94, base94_size);
    p += sizeof(T);

    uint8_t h = base94_size | mode << 4;
    h += 0x20;

    bytes.push_back(h);
    for (int i = 0; i < base94_size; i++)
    {
        uint64_t v = base94[i];
        bytes.push_back(v);
    }
}

template <typename T>
static constexpr bool base94_base94ToDecimal(std::vector<uint8_t>& bytes, uint8_t*& p)
{
    uint8_t n1 = (*p++) - 0x20;
    if (n1 < 1)
    {
        return false;
    }

    uint8_t n2 = n1 >> 4;
    if (n2 < 1 || n2 > 4)
    {
        return false;
    }
    else
    {
        n1 = n1 & 0x0f;
        n2 = 1 << (n2 - 1);
    }

    if (n1 > BASE94_OUTPUT_BLOCK_SIZE)
    {
        return false;
    }

    T v = base94_base94ToDecimal(p, n1);
    uint8_t* b = (uint8_t*)&v;
    for (int k = 0; k < n2; k++)
    {
        uint8_t v = b[k];
        bytes.push_back(v);
    }
    return true;
}

bool base94_encode(const void* data, int data_size, std::vector<uint8_t>& bytes, int& bytes_size)
{
    uint8_t* stream = (uint8_t*)data;
    bytes_size = data_size * ceil((double)BASE94_OUTPUT_BLOCK_SIZE / (double)BASE94_INPUT_BLOCK_SIZE) + 1;
    bytes.reserve(bytes_size);

    int stream_size = data_size >> 3;
    data_size %= sizeof(uint64_t);
    for (int i = 0; i < stream_size; i++)
    {
        base94_decimalToBase94<uint64_t>(bytes, stream, 4);
    }

    stream_size = data_size >> 2;
    data_size %= sizeof(uint32_t);
    for (int i = 0; i < stream_size; i++)
    {
        base94_decimalToBase94<uint32_t>(bytes, stream, 3);
    }

    stream_size = data_size >> 1;
    data_size %= sizeof(uint16_t);
    for (int i = 0; i < stream_size; i++)
    {
        base94_decimalToBase94<uint16_t>(bytes, stream, 2);
    }

    stream_size = data_size;
    data_size = 0;
    for (int i = 0; i < stream_size; i++)
    {
        base94_decimalToBase94<uint8_t>(bytes, stream, 1);
    }

    bytes_size = bytes.size();
    return true;
}

bool base94_decode(const void* data, int data_size, std::vector<uint8_t>& bytes, int& bytes_size)
{
    uint8_t* stream = (uint8_t*)data;
    bytes_size = data_size * ceil((double)BASE94_INPUT_BLOCK_SIZE / (double)BASE94_OUTPUT_BLOCK_SIZE) + 1;
    bytes.reserve(bytes_size);

    int stream_size = data_size >> 3;
    data_size %= sizeof(uint64_t);
    for (int i = 0; i < stream_size; i++)
    {
        if (!base94_base94ToDecimal<uint64_t>(bytes, stream))
        {
            return false;
        }
    }

    stream_size = data_size >> 2;
    data_size %= sizeof(uint32_t);
    for (int i = 0; i < stream_size; i++)
    {
        if (!base94_base94ToDecimal<uint32_t>(bytes, stream))
        {
            return false;
        }
    }

    stream_size = data_size >> 1;
    data_size %= sizeof(uint16_t);
    for (int i = 0; i < stream_size; i++)
    {
        if (!base94_base94ToDecimal<uint16_t>(bytes, stream))
        {
            return false;
        }
    }

    stream_size = data_size;
    data_size = 0;
    for (int i = 0; i < stream_size; i++)
    {
        if (!base94_base94ToDecimal<uint8_t>(bytes, stream))
        {
            return false;
        }
    }

    bytes_size = bytes.size();
    return true;
}

int main() {
    uint8_t messages[] = "您好!";
    uint64_t last = GetTickCount64();
    for (int i = 0; i < 100000; i++)
    {
        int bytes_size;
        std::vector<uint8_t> bytes;
        base94_encode(messages, sizeof(messages), bytes, bytes_size);

        int output_size;
        std::vector<uint8_t> output;
        base94_decode(bytes.data(), bytes_size, output, output_size);
    }

    uint64_t diff = GetTickCount64() - last;
    printf("tick: %llu\n", diff);
    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值