0

我的程序向服务器发送一个大小为 512KB 的数据请求。为了检查数据完整性,它具有来自元信息文件的给定 SHA1。我将把接收到的数据的 SHA1 与给定的 SHA1 进行比较,但我认为出现问题是因为缓冲区太大。

int main(int argc, char** argv)
{
    char given_SHA1[20]; // assume that it has some value.
    char received_buffer[524288]; // Assume that this holds 512KB data from a socket. does not make sense. it is too big.
    char SHA1_received[20]; 

    SHA1(received_buffer, SHA1_received); // SHA1_received will get SHA1 of 512KB data.
    if(strcmp(SHA1_received, given_SHA1) == 0)
    {
        printf("received data is OK\n");
    }
    else
    {
        printf("error\n");
        exit(0);
    }
}

有没有其他方法可以做这段代码所做的事情,而不是将 512KB 缓冲区声明为局部变量?

4

2 回答 2

0

您的问题可能只是分配缓冲区之一。在这种情况下,您可以简单地这样做:

#include <stdlib.h>

...

char *received_buffer;
received_buffer = (char*) malloc(524288 * sizeof(char));

使用完缓冲区后,记得做

free(received_buffer);

因此,您不必保留不再使用的内存(并且,在多次循环此代码的情况下,您可以避免“内存泄漏”)。

作为替代解决方案,您可以按照http://www.openssl.org/docs/crypto/sha.html中给出的说明处理消息片段(重复调用以处理整个消息 - 即使用较小的块) :

SHA1() 计算 d 处 n 个字节的 SHA-1 消息摘要并将其放在 md 中(其中必须有空间用于 SHA_DIGEST_LENGTH == 20 字节的输出)。如果 md 为 NULL,则摘要放置在静态数组中。

如果消息没有完全存储在内存中,可以使用以下函数:

SHA1_Init() 初始化一个 SHA_CTX 结构。

可以重复调用 SHA1_Update() 并使用要散列的消息块(数据中的 len 个字节)。

SHA1_Final() 将消息摘要放在 md 中,它必须为 SHA_DIGEST_LENGTH == 20 字节的输出留出空间,并擦除 SHA_CTX。

应用程序应该使用更高级别的函数 EVP_DigestInit(3) 等,而不是直接调用散列函数。

于 2013-08-06T12:39:40.557 回答
0

我个人会保持一切原样,除了我要声明 buffer static。这将使它成为一个“全局”变量,因此它不会在堆栈上分配。在这个特定的用例中没有什么区别,只是它不占用太多的堆栈空间。

static char received_buffer[524288];

但是,如果您在同一个函数中运行多个线程,这将不起作用。然后您将需要使用其他一些技术,例如使用malloc- 这应该最好“每个线程一次”完成,然后该线程应该用于处理多组数据,并且缓冲区从主线程传递到“获取数据并计算 SHA1" 函数。

于 2013-08-06T13:01:31.310 回答