我想将64位整数len_A与64位整数len_C连接起来并将其存储到uint8_t缓冲区[16]。但即使我将len_A指定为(uint8_t *)len_A和len_C(uint8_t *)len_C,我也无法做到。
警告消息是:从不同大小的整数
转换为指针uint64_t len_A
uint64_t len_C
uint8_t buffer[16] = { 0 };
for (k = 7, l = 0; k >= 0 && l <= 7; k--, l++) {
buffer[k] = buffer[k] ^ ((uint8_t *) len_A)[l];
}
for (k = 15, l = 0; k >= 8 && l <= 7; k--, l++) {
buffer[k] = buffer[k] ^ ((uint8_t *) len_C)[l];
}
我也是以另一种方式完成的:
for (k = 15; k >= 0; k--) {
if(k==0){
buffer[k] = buffer[k] ^ (len_A && 0xff); // lowest byte 0 len_A
}
if(k!=0){
buffer[k] = buffer[k] ^ ((len_A >> 8*k) & 0xff); // byte no 2 of len_A
}
}
k=15;
for (k = 15; k>=7; k--) {
if(k==0){
buffer[k] = buffer[k] ^ (len_C && 0xff); // lowest byte 0 len_A
}
if(k!=0){
buffer[k] = buffer[k] ^ ((len_C >> 8*k) & 0xff); // byte no 2 of len_A
}
}
但是编译器似乎仍然指向一个未知的地址并给出了错误的结果。
还有其他选择吗?
答案 0 :(得分:3)
试试这个:
memcpy(buffer, &len_A, sizeof(len_A));
memcpy(buffer + sizeof(len_A), &len_C, sizeof(len_C));
第一行将sizeof(len_A)(8)个字节复制到&amp; buffer [0]。
第二行将sizeof(len_C)(8)字节复制到&amp; buffer [sizeof(len_A)](8)
请注意,这不会以与OP算法相同的顺序复制字节。我不清楚是否需要这样做。见下面的评论。
答案 1 :(得分:2)
很奇怪您使用xor运算符。如果(因为)目标区域已经为零,它将工作正常,但它似乎有点迂回;你应该使用简单的任务。在符号方面,还有一个^=
运算符可用于简化上次提议的分配:
buffer[k] ^= ((len_C >> 8*k) & 0xFF);
(尽管在此上下文中应省略^
)。
第一个示例中的问题是您需要((uint8_t *) &len_A)[l]
(并且没有xor)。
uint64_t len_A;
uint64_t len_C;
uint8_t buffer[16] = { 0 };
for (k = 7, l = 0; k >= 0 && l <= 7; k--, l++)
buffer[k] = ((uint8_t *)&len_A)[l];
for (k = 15, l = 0; k >= 8 && l <= 7; k--, l++)
buffer[k] = ((uint8_t *)&len_C)[l];
这会将数据字节按照它们在内存中找到的相反顺序复制到缓冲区中。使用memcpy()
的解决方案不会做出这种逆转。
循环控件仍然比必要的复杂。您可以将代码简化为:
for (k = 7; k >= 0; k--)
buffer[k] = ((uint8_t *)&len_A)[7-k];
for (k = 15; k >= 8; k--)
buffer[k] = ((uint8_t *)&len_C)[15-k];
在第二个例子中,你将移动比len_A
更多的位,这将导致麻烦;你需要换((k - 8) * 8)
。 合法地移位零,所以你不需要特殊情况。我调整了两个循环的界限。
for (k = 7; k >= 0; k--)
buffer[k] = (len_A >> (8*k)) & 0xFF;
for (k = 15; k>= 8; k--)
buffer[k] = (len_C >> (8*(k-8))) & 0xFF;
我注意到第三对循环没有进行字节顺序反转,尽管这很容易修复:
for (k = 7; k >= 0; k--)
buffer[k] = (len_A >> (8*(8-k))) & 0xFF;
for (k = 15; k>= 8; k--)
buffer[k] = (len_C >> (8*(15-k))) & 0xFF;
这是一些演示输出和代码。
A = 0x0123456789ABCDEF
C = 0x0F1E2D3C4B5A6978
Loops 1: 01 23 45 67 89 AB CD EF : 0F 1E 2D 3C 4B 5A 69 78 :
Loops 2: 01 23 45 67 89 AB CD EF : 0F 1E 2D 3C 4B 5A 69 78 :
Loops 3: EF CD AB 89 67 45 23 01 : 78 69 5A 4B 3C 2D 1E 0F :
Loops 4: 00 01 23 45 67 89 AB CD : 0F 1E 2D 3C 4B 5A 69 78 :
代码:
#include <stdint.h>
#include <stdio.h>
static void dump_buffer(size_t n, uint8_t const *data)
{
for (size_t i = 0; i < n; i++)
{
printf(" %.2X", data[i]);
if (i % 8 == 7)
printf(" :");
}
putchar('\n');
}
int main(void)
{
uint64_t len_A = 0x0123456789ABCDEF;
uint64_t len_C = 0x0F1E2D3C4B5A6978;
uint8_t buffer[16] = { 0 };
printf("A = 0x%.16llX\nC = 0x%.16llX\n", len_A, len_C);
for (int k = 7, l = 0; k >= 0 && l <= 7; k--, l++)
buffer[k] = ((uint8_t *)&len_A)[l];
for (int k = 15, l = 0; k >= 8 && l <= 7; k--, l++)
buffer[k] = ((uint8_t *)&len_C)[l];
printf("Loops 1: ");
dump_buffer(sizeof(buffer), buffer);
for (int k = 7; k >= 0; k--)
buffer[k] = ((uint8_t *)&len_A)[7-k];
for (int k = 15; k >= 8; k--)
buffer[k] = ((uint8_t *)&len_C)[15-k];
printf("Loops 2: ");
dump_buffer(sizeof(buffer), buffer);
for (int k = 7; k >= 0; k--)
buffer[k] = (len_A >> (8*k)) & 0xFF;
for (int k = 15; k>= 8; k--)
buffer[k] = (len_C >> (8*(k-8))) & 0xFF;
printf("Loops 3: ");
dump_buffer(sizeof(buffer), buffer);
for (int k = 7; k >= 0; k--)
buffer[k] = (len_A >> (8*(8-k))) & 0xFF;
for (int k = 15; k>= 8; k--)
buffer[k] = (len_C >> (8*(15-k))) & 0xFF;
printf("Loops 4: ");
dump_buffer(sizeof(buffer), buffer);
return 0;
}
答案 2 :(得分:0)
您的代码似乎非常复杂。为什么不尝试直接复制内存(假设您的数据已正确对齐,您可以通过aligned_alloc()
确保这一点):
((uint64_t *)buffer)[0] = len_A
((uint64_t *)buffer)[1] = len_C
哪一个是len_C
,哪一个是len_C
取决于机器的字节顺序(如果len_A
是更重要的值,如果你是big-endian,你需要上述解决方案。如果len_C
是更重要的值,如果您是小端,则需要上述解决方案。)否则,请在上面交换len_A
和len_C
。