-1

抱歉,我不能为此使用单独的类,我尝试构建以下代码并在循环中从外部调用时获得相同的输出。

unsigned int crypt_rand()
{
    HCRYPTPROV hProvider = 0;
    const DWORD dwLength = sizeof(unsigned int);
    unsigned int pbBuffer[dwLength] = {};

    if (!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
        return 1;
    if (!::CryptGenRandom(hProvider, sizeof(unsigned int), reinterpret_cast<PBYTE>(&pbBuffer)))
    {
        ::CryptReleaseContext(hProvider, 0);
        return 1;
    }
    if (!::CryptReleaseContext(hProvider, 0))
        return 1;
    return (unsigned int)pbBuffer;

}                                      

如果我每次都从循环中调用这个函数,得到相同的输出。在这个方法中,我能提供什么像时间一样的输入吗?你能帮我吗?

for (DWORD i = 0; i < 5; ++i)
    {
        rand_no = crypt_rand();
        std::cout << "windows::"<<i<<"::"<<rand_no<< std::endl;
    }

输出是

windows::0::4519964
windows::1::4519964
windows::2::4519964
windows::3::4519964
windows::4::4519964
4

3 回答 3

4

强制转换(语句中的 thereinterpret_cast和 the return)的使用隐藏了一些重要的编译器错误,这些错误可以让您首先正确地编写此代码。

尽可能避免强制转换,而是修复类型。

CryptGenRandom期望一个

BYTE *pbBuffer

范围。将指针传递给一个数组,BYTE 而不是其他任何东西(您正在传递一个指向数组的指针int)。

在您的退货声明中,您将地址转换为unsigned int. 您需要获取BYTE数组并将其包含的转换为 int(您可以在网上找到示例,或者您可以通过轮班和加法自己制作一个)。您现在所做的可能是一遍又一遍地输出相同的地址(或其中的一部分)。

为了澄清,将您的数组定义为

BYTE pbBuffer[dwLength] = {};

并将您的功能称为

::CryptGenRandom(hProvider, dwLength, pbBuffer)

避免强制转换,尤其是 C 风格的强制转换,并阅读有关数组的信息。在 C++ 中,当传递给函数时,数组衰减为指向数组第一个元素的指针。如果您有一个数组,BYTE它将衰减为 a BYTE*,即您的函数的预期类型。

于 2013-06-04T06:47:39.837 回答
0

你想要一个无符号整数的随机数吗?只需将 BYTE 缓冲区的内容转换为 unsigned int

怎么样:

unsigned int crypt_rand()
{
    HCRYPTPROV hProvider = 0;
    const DWORD dwLength = sizeof(unsigned int);
    BYTE buffer[dwLength];

    if (!::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
        return 1;
    if (!::CryptGenRandom(hProvider, sizeof(buffer), &buffer))
    {
        ::CryptReleaseContext(hProvider, 0);
        return 1;
    }
    if (!::CryptReleaseContext(hProvider, 0))
        return 1;
    return *(unsigned int*)buffer;
}
于 2013-09-09T13:12:31.967 回答
0

问题在return (unsigned int)pbBuffer;这里,您每次都只是获取 pbBUffer 的地址。如果 pbBuffer 是一个数组并且函数 crypt_rand 返回 unsigned int 那么它应该是返回时数组的元素。

您需要在编译期间启用警告。这些可能的错误必须作为警告存在。

于 2013-06-04T06:39:59.307 回答