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

时间:2018-02-19 22:54:23

标签: c arrays encryption casting type-conversion

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

unsigned char nonce_counter[16] = "xCv6Jk0neeV5GoSZ";

我经常需要将值视为数字来进行数学运算,但我似乎无法找到一种安全的方式来输入值。

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

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

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

我的系统不支持__uint128_t

2 个答案:

答案 0 :(得分:3)

  

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

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

一个有用的替代方案是 return Redirect::away('http://www.google.com');

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

对于此类应用,使用union而不是uint8_t更为明确。

unsigned char

以下代码需要解决endian问题。

#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]}; } 定义为0或1,具体取决于字节序。

LSB_128
  

我担心这样做会导致效率下降。

在放弃此方法之前,请尝试以上操作并验证效率丢失。为您的编译器提供优化的机会。

inline my_uint128 inc_128(my_uint128 a) { if (++a.u64[LS_128] == 0) { ++a.u64[MS_128] } return a; } uint64_t u64[2];的替代方案是LS_128,其中struct { uint64_t ms,ls; };按照平台的结尾排序。

此方法的一个优点是ls, ms可以包含union成员,如果支持的话。然后,各种例程可以使用直接128位数学而不改变调用代码。

答案 1 :(得分:-1)

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

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

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