简体   繁体   English

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

[英]Concatenate two 64bit integer and store it into a uint8_t array of [16]

I want to concatenate a 64bit integer len_A with a 64bit integer len_C and store it into a uint8_t buffer[16]. 我想将64位整数len_A与64位整数len_C连接起来,并将其存储到uint8_t缓冲区中[16]。 But I couldnt do it even it I have assign len_A as (uint8_t *) len_A and len_C (uint8_t *) len_C. 但是,即使我将len_A分配为(uint8_t *)len_A和len_C(uint8_t *)len_C,我也无法做到。

The warning message was: cast to pointer from integer of different size 警告消息是:从不同大小的整数强制转换为指针

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];
}

I've also done it in another way: 我也用另一种方式做到了:

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
    }
}

But still the compiler seems to point to an unknown address and giving the wrong results. 但是编译器似乎仍然指向一个未知的地址并给出错误的结果。

Are there any other options? 还有其他选择吗?

Try this: 尝试这个:

memcpy(buffer, &len_A, sizeof(len_A));
memcpy(buffer + sizeof(len_A), &len_C, sizeof(len_C));

The first line copies sizeof(len_A) ( 8 ) bytes to &buffer[0]. 第一行将sizeof(len_A)(8)字节复制到&buffer [0]。

The second line copies sizeof(len_C) ( 8 ) bytes to &buffer[sizeof(len_A)] ( 8 ) 第二行将sizeof(len_C)(8)字节复制到&buffer [sizeof(len_A)](8)


Note that this does not copy the bytes in the same order as the OP's algorithm. 请注意,这不会以与OP算法相同的顺序复制字节。 It was not clear to me if that was required. 我不清楚是否需要这样做。 See comments below. 请参阅下面的评论。

It is curious that you use the xor operator. 奇怪的是,您使用了xor运算符。 It will work OK if (because) the target area is already zero, but it seems a little circuitous; 如果(因为)目标区域已经为零,则可以正常工作,但看起来有点circuit回; you should be using plain assignment. 您应该使用普通分配。 Notationally, there is also a ^= operator that could be used to simplify the last proposed assignment to: 从概念上讲,还有一个^=运算符可用于将最后提议的赋值简化为:

buffer[k] ^= ((len_C >> 8*k) & 0xFF);

(though the ^ should be omitted in this context). (尽管在此上下文中应省略^ )。

Your problem in the first example is that you needed ((uint8_t *) &len_A)[l] (and no xor). 第一个示例中的问题是您需要((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];

This copies the data bytes into the buffer in the reverse order that they're found in memory. 这会按照在内存中找到的相反顺序将数据字节复制到缓冲区中。 Solutions using memcpy() won't do that reversal. 使用memcpy()解决方案不会进行这种逆转。

The loop controls are still more complex than necessary. 循环控制仍然比必要的复杂。 You could simplify the code to: 您可以将代码简化为:

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];

In the second example, you'll be shifting by more bits than there are in the len_A which will lead to trouble; 在第二个示例中,您将移位的位数超过len_A中的len_A ,这将导致麻烦; you need to shift by ((k - 8) * 8) . 您需要移动((k - 8) * 8) It is legal to shift by zero, so you don't need to special case that. 零移位合法的,因此您无需特殊情况。 I've adjusted the bounds on both loops. 我已经调整了两个循环的边界。

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;

I note that this third pair of loops do not do the byte-order reversal, though that's easily fixed: 我注意到这第三对循环不执行字节顺序反转,尽管很容易解决:

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;

Here's some demonstration output and code. 这是一些演示输出和代码。

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 :

Code: 码:

#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;
}

Your code seems very complex. 您的代码似乎很复杂。 Why not try to copy the memory directly (assuming that your data is aligned appropriately, which you can ensure eg via aligned_alloc() ): 为什么不尝试直接复制内存(假设您的数据已正确对齐,则可以例如通过aligned_alloc()来确保):

((uint64_t *)buffer)[0] = len_A
((uint64_t *)buffer)[1] = len_C

Which one is len_C and which one is len_C depends on the machine's endianness (if len_A is the more significant value, you want the above solution iff you are big-endian. If len_C is the more significant value, you want the above solution iff you are little-endian.) Otherwise, swap len_A and len_C in the above. 哪一个是len_C而哪个是len_C取决于计算机的字节序(如果len_A是更高有效的值,则您需要上面的解决方案(如果您是big-endian)。如果len_C是更高有效的值,则您需要上面的解决方案(如果您是big-endian)都是低位优先。)否则,在上面交换len_Alen_C

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

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