如何在C中顺序生成字节?

ny6fqffe  于 2023-06-21  发布在  其他
关注(0)|答案(2)|浏览(105)

给出下面的示例代码,它生成32个字节,并用零屏蔽第一个字节。

static uint256_t rand256(struct seed *seed)
{
    seed->counter++;
    return sha256(seed, sizeof(struct seed));
}

static uint256_t rand256_and_mask(struct seed *seed)
{
    uint256_t r = rand256(seed);
    memset(&r, 0, 27);
    //r.i8[23] = 0xE;
    return r;
}

我想按顺序获得字节(如\x09,\x0A ... 99的顺序),其差值为+1,就像如果第一次调用时最后一个字节是"\x09",那么第二次调用时它将是"\x0A"
注意:我正在处理的数字非常大,我的程序接受"uint256_t"类型,声明如下:

union uint256_s
{

    uint8_t i8[32];
    uint16_t i16[16];
    uint32_t i32[8];
    uint64_t i64[4];
};
typedef union uint256_s uint256_t;

假设uint256_t r = rand 256(seed);在第一次执行我的程序时产生这个:

E8411A8777E440FD1FA6CBF5F5149D14B45844B32F7B720CE653686229F9B758

那么在rand256_and_mask()中的memset之后,返回的r的值将是:

0000000000000000000000000000000000000000000000000000000029F9B758

在这里,我需要保留r的值,然后在下一次调用时将其递增1(如果需要,请跳过rand 256()调用),因此r的值将是:

0000000000000000000000000000000000000000000000000000000029F9B759

从技术上讲,我需要该程序来跟踪r,因为它代表了范围中的一个位置。我不太懂C语言,所以我希望我能澄清一些事情。
C开发者请帮忙

dzhpxtsq

dzhpxtsq1#

您可以使用memset将其所有字节设置为0。要在C中按顺序生成字节,可以按如下方式修改提供的代码:

static int currentNumber = 9; // store current

static uint256_t getNextNumber()
{
    currentNumber++;
    if (currentNumber > 99)
        currentNumber = 10;

    uint256_t result;
    memset(&result, 0, sizeof(uint256_t));

    for (int i = 31; i >= 0; i--)
    {
        result.i8[i] = currentNumber & 0xFF;
        currentNumber >>= 8;
    }

    return result;
}

每次调用getNextNumber函数时,它都会根据currentNumber生成下一个顺序字节模式。

bttbmeg0

bttbmeg02#

您可以使用此函数以big-endian字节顺序递增uint8_t数组:

#include <stdint.h>
#include <stddef.h>
void incu8v(uint8_t *v, size_t len)
{
    while (len-- > 0)
    {
        if (++v[len] != 0)
        {
            /* No carry. */
            break;
        }
    }
}

此函数将就地递增uint256_t中的一个(传递一个指向uint256_t的指针):

void inc256p(uint256_t *v)
{
    incu8v(v->i8, sizeof(v->i8));
}

此函数将uint256_t递增值并返回递增后的值:

uint256_t inc256(uint256_t v)
{
    inc256p(&v);
    return v;
}

更改i16i32i64成员值的方式将取决于计算机的本机字节顺序。
inc256()inc256p()不会屏蔽结果,但incu8v()可用于递增字节的子序列,例如

incu8v(r.i8 + 27, 5);

请注意,以intuint开始并以_t结尾的标识符是C标准保留的,因此类型名称uint256_t应重命名为不保留的名称。

相关问题