繁体   English   中英

如何将16位值的数组转换为base64?

[英]How to convert an array of 16-bit values to base64?

所以我现在正在研究C ++中的加密/解密方法。 它以std::string作为输入(加上用于加密消息的“密钥”),并生成代表加密字符串的std::string输出。

在加密过程中,我将std::string转换为uint16_t数组,并在加密过程中对此进行了一些计算。 其中的原因很简单,因为一个uint_16_t值通过算法则给出了更净空加密原始值char一样。

问题是,为了以std::string返回加密的消息,我需要以某种方式将uint_16_t值的数组转换为可读的内容(即适合char数组的内容而不溢出)。 为此,我以为我可以使用base64,但是我发现的所有base64实现都只将std::stringchar*作为输入(8位/元素)。 显然,如果我将其提供给uint16_t数组,我将永远无法找回原始值,因为base64函数会在转换之前将其转换为8位。

所以这是我的问题:有人知道将uint16_t数组编码为可打印的字符串(如base64)并返回而不会丢失任何数据的方法吗?

我知道我必须获取数据的字节才能使用base64,但是我不确定该怎么做。

感谢您的任何帮助!

您可以使用base-n微型库,该库提供基于迭代器的通用I / O。

以下代码按预期方式将“ 1 2 3 4 65535”输出到stdout:

uint16_t arr[] { 1, 2, 3, 4, 65535 };
const int len = sizeof(arr)/sizeof(arr[0]);
std::string encoded;
bn::encode_b64(arr, arr + len, std::back_inserter(encoded));
uint16_t out[len] { 0 };
bn::decode_b64(encoded.begin(), encoded.end(), out);
for (auto c : out) {
    std::cout << c << " ";
}

强制性披露:我是图书馆的作者

假设uint16_t值的范围从零到63,并且您使用的是ASCII,只需将0x21(十六进制21)添加到每个值并将其输出。 这将创建一个可打印的字符串,但是出于显示目的,您可能还希望在一定数量的字符后打印新行,而不是显示一个很长的字符串。 任何解码器都必须从从文件中读取的每个字符中减去0x21(如果文件中有换行符,则将其忽略(在减去0x21之前进行此检查))。

在此处查看上一个问题: c ++中的base64解码代码段

uint16_t*强制转换为unsigned const char*并进行编码,如下所示:

// Data to base64 encode
std::vector<uint16_t> some_data;

// Populate some_data...
// ...

// base64 encode it
std::string base64_data = base64_encode((unsigned char const*)&some_data[0], some_data.size()*2 );

所以我终于解决了。 我发布它是为了防止其他人需要这样的东西。 基本上,我将uint16_t值分别分成两个uint8_t ,并且由于它们是8位值,因此它们可以与任何base64实现一起使用。 这是我的方法:

#include <iostream>
using namespace std;

#define BYTE_T uint8_t
#define TWOBYTE_T uint16_t
#define LOWBYTE(x)          ((BYTE_T)x)
#define HIGHBYTE(x)         ((TWOBYTE_T)x >> 0x8)
#define BYTE_COMBINE(h, l)  (((BYTE_T)h << 0x8) + (BYTE_T)l)

int main() {

    // an array with 16-bit integers
    uint16_t values[5] = {1, 2, 3, 4, 65535};

    // split the 16-bit integers into an array of 8-bit ones
    uint8_t split_values[10]; // notice that you need an array twice as big (16/8 = 2)
    int val_count = 0;
    for (int i=0; i<10; i+=2) {
        split_values[i] = HIGHBYTE(values[val_count]);
        split_values[i+1] = LOWBYTE(values[val_count]);
        val_count++;
    }

    // base64 encode the 8-bit values, then decode them back
    // or do whatever you want with them that requires 8-bit numbers

    // then reunite the 8-bit integers to the original array of 16-bit ones
    uint16_t restored[5];
    int rest_count = 0;
    for (int i=0; i<10; i+=2) {
        restored[rest_count] = BYTE_COMBINE(split_values[i], split_values[i+1]);
        rest_count++;
    }

    for (const auto &i : restored) cout << i << " ";
    cout << endl;

    return 0;
}

当然,相同的方法将适用于任何长度。 您只需要更改for循环的位即可。 可以轻松修改此代码,以将32位int拆分为16位int或任何其他内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM