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

时间:2014-07-28 22:27:52

标签: c++ arrays string encryption base64

所以我现在正在使用C ++加密/解密方法。它需要一个std::string作为输入(加上一个用于加密消息的“密钥”),它会产生一个std::string输出,表示加密的字符串。

在加密过程中,我将std::string转换为uint16_t数组,并对其进行一些计算,作为加密的一部分。这样做的原因很简单,因为uint_16_t值通过算法加密原始值提供了更多的余量,然后是char

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

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

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

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

您可以使用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 << " ";
}

强制披露:我是lib的作者

答案 1 :(得分:0)

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

答案 2 :(得分:0)

请在此处查看上一个问题:base64 decode snippet in c++

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 );

答案 3 :(得分:0)

所以我终于解决了。我发布它以防其他人需要这样的东西。 基本上我将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位整数拆分为16位整数,或者实际上是什么。