连接两个64位整数并将其存储到[16]的uint8_t数组中

时间:2013-11-29 17:04:31

标签: c concatenation

我想将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
    }
}

但是编译器似乎仍然指向一个未知的地址并给出了错误的结果。

还有其他选择吗?

3 个答案:

答案 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_Alen_C