繁体   English   中英

16字节无符号char数组作为数字吗?

[英]16 byte unsigned char array as a number?

我正在使用128位密钥进行某种加密,这需要使用16字节数据块,并将其存储为16字节无符号字符数组。

unsigned char nonce_counter[16] = "xCv6Jk0neeV5GoSZ";

我经常需要将值当作一个数字来进行一些数学运算,但是我似乎找不到一种安全的方法来强制转换该值。

如何将16byte值转换为数字数据类型?

具体来说,我需要使用按位XOR A ^ B并递增A ++

我知道我可以做显而易见的事情,并使用for循环并独立处理数组的每个元素,但是我担心这样做会降低效率。

我的系统不支持__uint128_t

如何将16byte值转换为数字数据类型?
我的系统不支持__uint128_t。

如果编译器不支持128位类型,则没有数值数据类型解决方案。


一个有用的替代方法是union

避免将字符数组指针转换为较宽整数的指针。 可能会导致对齐错误(总线故障)。

对于这种类型的应用程序,使用uint8_t而不是unsigned char更为清楚。

#include <stdint.h>
typedef union {
  uint8_t u8[16];
  uint64_t u64[2];
} my_uint128;

如下所示的代码将需要解决字节序问题。

void foo() {
  my_uint128 nonce_counter = { .u8 =  "xCv6Jk0neeV5GoSZ"};
  btoh_128(&nonce_counter); // this would be a no-op on a BE machine
  ...

^是字节序安全的。

inline my_uint128 xor_128(my_uint128 a, my_uint128 b) {
  return (my_uint128) { .u64[0] = a.u64[0] ^ b.u64[0], .u64[1] = a.u64[1] ^ b.u64[1]};
}

增量需要更多的工作。 根据字节序将LSB_128定义为0或1。

inline my_uint128 inc_128(my_uint128 a) {
  if (++a.u64[LS_128] == 0) { 
    ++a.u64[MS_128]
  }
  return a;
}

我担心这样做会失去效率。

尝试上述方法,并在放弃此方法之前验证效率损失。 给您的编译器一个优化的机会。


uint64_t u64[2];的替代方法uint64_t u64[2]; LS_128将是struct { uint64_t ms,ls; }; struct { uint64_t ms,ls; }; ls, ms按照平台的字节序排序。


这种方法的一个优点是,如果受支持,则该union可以包含uint128_t成员。 然后,各种例程可以使用直接的128位数学运算,而无需更改调用代码。

如果使用的是gcc,则可以使用__uint128_t指针并通过它修改数组:

unsigned char nonce_counter[16] = "xCv6Jk0neeV5GoSZ";
__uint128_t* A = (__uint128_t*)nonce_counter;

*A += 1;
*A ^= *B;

暂无
暂无

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

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