如何从/dev/urandom获取自定义字节?

问题描述 投票:0回答:2

我正在开发一个程序,可以发现比特币地址中的部分冲突。 我已经获得了 urandom 的源代码,但不知道从哪里开始。 所以我想从 /dev/urandom 中获取总长度为 32 的随机字节(包括屏蔽 0),因为我的程序需要 256 位,但在转换为十六进制时在开头用零屏蔽。

十六进制输出会是这样的

000000000000000000000000000000000000000000000000000000000000002d4

注意实际十六进制值之前的 0(这就是我所说的掩码),在 python 中,许多库都需要它来获取比特币地址。

我正在努力处理以下代码(不是来自 random.c),现在我认为修改 urandom 本身可能会更有帮助。

   static bool init_rand(void *data, size_t size)
{
    FILE *stream = fopen("/dev/urandom", "r");
    if (stream == NULL)
        return false;
    bool ok = (fread(data, sizeof(uint8_t), size, stream) == size);
    fclose(stream);
    return ok;
}



static bool init_rand(void *data, size_t size)
{
    size_t size0 = size / sizeof(unsigned) + 1;
    assert(size0 * sizeof(unsigned) >= size);
    unsigned data0[size0];
    for (size_t i = 0; i < size0; i++)
    {
        int err = rand_s(data0 + i);
        if (err != 0)
            return false;
    }
    memcpy(data, data0, size);
    return true;
}


static struct seed *make_seed(void)
{
    struct seed *seed = (struct seed *)malloc(sizeof(struct seed));
    assert(seed != NULL);
    seed->counter = 0;
    if (!init_rand(seed, sizeof(struct seed)))
    {
        fprintf(stderr, "error: failed to init random seed\n");
        exit(EXIT_FAILURE);
    }
    if (seed->counter == 0)     // Sanity check...
    {
        fprintf(stderr, "error: random seed initialization failed\n");
        exit(EXIT_FAILURE);
    }
    return seed;
}

欲了解完整代码,请参阅 Pairgen 此处

是否可以修改 Linux 内核驱动程序中的 random.c 以生成已用 0 掩码的字节?

c random byte bitcoin puzzle
2个回答
-1
投票

您将打印表示形式(“十六进制输出”)与实际值混淆了。

0x2d4 和 0x0000000000000000000000000000000000000000000000000000000000000002d4 是完全相同的值。

“0x2d4”和“0x000000000000000000000000000000000000000000000000000000000000002d4”是两个非常不同的字符串。

如果您想格式化字符串 - 使用格式化操作(如

sprintf
)。


查看您的评论,看来您误解了

0
的概念以及“十六进制”的含义。

Hex 代表十六进制,表示以 16 为基数的系统中的值的解释。它用于“表示”值(为了可读性),它不会影响值本身。例如,0xA 是十进制值

10
的以 16 为基数的表示形式。这些是相同的值,只是写法不同。
同样,前导零不会改变值。如果您在调试器中看到 

0x24b

,并且保存它的变量是 32 位,那么实际的内存表示将是

0x0000024b
。您可以使用
printf
格式标志控制值的打印方式。
最后但并非最不重要的一点是,

0

是一个有效值。每个位都可以是

0
1
,并且您可以让随机生成器为您提供绝对有效的随机生成值,对于您要求的所有 256 位,该值都是
0
。虽然可能性极小,但也并非不可能。更有可能的是,256 位中的
some
0,并且完全有可能其中一些是最高位,如果您丢弃这些位,则导致您的 256 位值被误解为小于 256 位高位(如
printf
默认情况下所做的那样)。
当用于加密目的时,您不应该操纵从 

urandom

读取的值,因为这很可能会引入漏洞,并且可能不是您

真正
想要做的。


-1
投票
memset

可以用零屏蔽字节。这对我有帮助,但我必须在

rand256(seed)
函数中完成它
static uint256_t rand256(struct seed *seed)
{
    seed->counter++;
    return sha256(seed, sizeof(struct seed));
}

static uint256_t rand256_and_mask(struct seed *seed)
{
    //Generate 256-bit random number using rand256 function
    uint256_t r = rand256(seed);
    memset(&r, 0, 24); //mask first  bytes leaving 8 intact
    return r;
}

© www.soinside.com 2019 - 2024. All rights reserved.