可逆地组合两个uint32_t而不更改数据类型

时间:2014-01-16 17:50:33

标签: c++ integer encryption uint32-t

这是我的问题:我需要通过单个uint32_t传回两个uint32_t(因为API的设置方式......)。我可以硬编码我需要的任何其他值来反转操作,但函数之间传递的参数需要保持单个uint32_t。

如果我可以将两个32位的int位移位到一个64位的int(就像解释here那样),这将是微不足道的,但是编译器不会那样。我也看过数学pairing functions,但我不确定这是否是我在这种情况下所需要的。

我想过设置一个简单的密码:unint32_t可能是密文,我可以硬编码密钥。这是一个example,但这似乎有点矫枉过正。

这甚至可能吗?

3 个答案:

答案 0 :(得分:3)

仅使用32位不能存储超过32位的信息。这是信息理论的基本结果。

如果你知道你只使用每个值的低16位,你可以将一个左16位移位并以这种方式组合它们。但绝对没有办法将64位信息(甚至33位)转换成32位周期。

答案 1 :(得分:2)

根据真正值得多少麻烦,您可以:

  1. 创建一个全局数组或vector std::pair<uint32_t,uint32_t>
  2. 将索引传递给函数,然后“反向”函数只查找数组中的结果。
  3. 编写一些代码来决定在要传递一对时使用哪个索引。该索引不需要被其他任何人使用,并且由于该数组是全局的,因此可能存在线程安全问题。基本上你正在写的是一个简单的内存分配器。
  4. 作为一种特殊情况,在具有32位数据指针的机器上,您可以为reinterpret_cast分配结构和uint32_t指针。所以你不需要任何全局变量。

    请注意,您需要知道传入值的函数是否可以将值存储在某个地方以便稍后“解码”,在这种情况下,您遇到的资源管理问题比函数确定的要困难得多。在它返回时已经完成使用它。

    在简单的情况下,如果您编写的代码根本不需要重入,那么您一次只需要使用一个索引。这意味着您不需要一个数组,只需要一个pair。无论值如何,您都可以将0传递给函数,并让解码器忽略其输入并查看全局位置。

    如果两个特殊情况都适用(32位且没有保留值),那么你可以将pair放在堆栈上,并且即使你的代码确实需要重新使用也不使用全局和动态分配-entrant。

    这些都不是真的推荐,但它可以解决你的问题。

答案 2 :(得分:1)

您可以使用中间全局数据结构在其上存储uint32_t对,使用您唯一的uint32_t参数作为结构索引:

struct my_pair {
  uint32_t a, b;
};

std::map<uint32_t, my_pair> global_pair_map;

uint32_t register_new_pair(uint32_t a, uint32_t b) {
  // Add the pair of (a, b) to the map global_pair_map on a new key, and return the
  // new key value.
}

void release_pair(uint32_t key) {
  // Remove the key from the global_pair_map.
}

void callback(uint32_t user_data) {
  my_pair& p = global_pair_map[user_data];

  // Use your pair of uint32_t with p.a, and p.b.
}

void main() {
  uint32_t key = register_new_pair(number1, number2);

  register_callback(callback, key);
}