【问题标题】:Writing and reading a binary file写入和读取二进制文件
【发布时间】:2018-06-24 12:00:09
【问题描述】:

我正在尝试将crypt->public_key->data 写入二进制文件。如果我使用sizeof(unsigned int) 的大小作为fwrite() 中的第二个参数,它可以工作。但是,它在头文件中被声明为unsigned short * 类型。我不确定它为什么会这样。此外,我在编写公钥和阅读它们时也遇到了问题。虽然我在fwrite()fread()中使用的大小完全相同。

编辑:似乎我的 crypt->public_key->data 的大小不正确,正如 usr2564301 所指出的那样。

*我不确定是否需要引用此代码的来源。但我会在此处添加 URL:https://github.com/Varad0612/The-McEliece-Cryptosystem

来自 matrix.h 的代码

typedef struct matrix
{
   int rows;             //number of rows.
   int cols;             //number of columns.
   unsigned short *data;
}*bin_matrix;

这是来自 mceliece.c 的代码

//Initialize the mceliece cryptosystem
mcc mceliece_init(int n0, int p, int w, int t)
{
    FILE *publicKey, *privateKey;
    mcc crypt;  
    crypt = (mcc)safe_malloc(sizeof(struct mceliece));  
    //crypt->code = qc_mdpc_init(n0, p, w, t);
    //crypt->public_key = generator_matrix(crypt->code);

    //printf("%d\n",crypt->public_key->rows);
    //printf("%d\n",crypt->public_key->cols);

    //Write public key into a binary file
    /*publicKey = fopen("PublicKey.bin", "wb");
    privateKey = fopen("PrivateKey.bin", "wb");

    if(privateKey != NULL){
        fwrite(crypt->code->row, n0*p*sizeof(unsigned short), n0 * p, privateKey);
        fclose(privateKey); 
    }
    else{
        printf("Unable to write private key\n");    
    }

    //Write public key into a binary file
    if(publicKey != NULL){
        fwrite(crypt->public_key->data, p*p*n0*sizeof(unsigned short), crypt->public_key->rows*crypt->public_key->cols, publicKey);
        fclose(publicKey);
    }
    else{
        printf("Unable to write public key\n");
    }*/

    //Read private key from a binary file
    crypt->code = (mdpc)safe_malloc(sizeof(struct qc_mdpc));
    crypt->code->n0 = n0;
    crypt->code->p = p;
    crypt->code->w = w;
    crypt->code->t = t;
    crypt->code->n = n0 * p;
    crypt->code->r = p;
    crypt->code->k = (n0 - 1) * p;
    crypt->code->row = (unsigned short*)calloc(n0 * p, sizeof(unsigned short));
    privateKey = fopen("PrivateKey.bin", "rb");
    if(privateKey != NULL){
        fread(crypt->code->row, p*n0*sizeof(unsigned short), p*n0, privateKey);
        fclose(privateKey); 
    }
    else
        printf("Unable to read private key\n");

    //Read public key from a binary file
    /*crypt->public_key = (bin_matrix)safe_malloc(sizeof(struct matrix));
    crypt->public_key->data = (unsigned short*)safe_malloc(p*p*n0*sizeof(unsigned short));
    crypt->public_key->rows = p;
    crypt->public_key->cols = n0*p; 
    publicKey = fopen("PublicKey.bin", "rb");
    if(publicKey != NULL){
        fread(crypt->public_key->data, p*p*n0*sizeof(unsigned short), crypt->public_key->rows*crypt->public_key->cols, publicKey);
        fclose(publicKey);  
    }
    else{
        printf("Unable to read public key\n");
    }*/

    printf("Successful\n");
    //printf("mceliece generated...\n");
    return crypt;
}

【问题讨论】:

  • sizeof(unsigned int) 是一个常量大小,由您的编译器提供。但是,您不知道->data 处的数据量是否有那么大——您无法从指针推导出分配的大小。据推测,您需要根据该结构中的其他元素计算其实际大小。
  • @SteveSummit:乘以之前的sizeof(unsigned int)。这不可能是正确的——它可能应该是sizeof(unsiged short)。请注意,OP对于什么不起作用是模糊的。写入的数据太少?太多了?
  • @Lance 乘以sizeof(unsigned short) 应该是正确的,因为这是基础数据的大小。乘以sizeof(unsigned int) 应该是完全错误的,并且不应该工作。当您使用unsigned short 时,您能否更清楚地了解它是如何失败的? crypt->public_key->rows->cols 是否在您调用 fwrite 的位置正确设置? (大概设置它们的代码在generator_matrix() 中。)
  • @SteveSummit 我收到一条解码失败消息,它位于 qc_mdpc.c 的 decode() 中。我认为'crypt->public_key->rows'和'->cols'是正确的,因为我没有修改原始代码中这部分的任何内容。

标签: c post-quantum-cryptography


【解决方案1】:

我们的阅读陈述存在混淆:

fread(crypt->code->row, p*n0*sizeof(unsigned short), p*n0, privateKey);

这将尝试读取p*n0 元素,每个元素的大小为p*n0*sizeof(unsigned short) 字节。如果文件不大于分配的大小,你会很幸运,因为fread 不会尝试写入超出分配块的末尾。

你应该写:

size_t nread = fread(crypt->code->row, sizeof(unsigned short), p * n0, privateKey);
if (nread == p * n0) {
    /* private key was read successfully */
} else {
    /* file is too short, only nread words were read */
}

【讨论】:

  • fread 不保证读取请求的数据,即使文件中有那么多数据。
  • @zwol: 实际上是这样:C11 7.21.8.1p3 `fread` 函数返回成功读取的元素数,如果读取错误或可能小于nmemb遇到文件结尾。如果sizenmemb 为零,则fread 将返回零,并且数组的内容和流的状态保持不变。 您必须参考可能返回的unix read 系统调用即使文件有可用数据,也有多种原因导致计数不足。
  • 您的解释是合理的,但我不知道fread任何 实现如果read 返回一个短计数会在内部循环,因此作为一个实际问题fread 的用户必须准备好处理短读。
  • @zwol:真的吗?我刚刚查找了 glibc 并在内部函数_IO_default_xsgetn 中找到了正确的循环。 glibc 是一项需要解开的工作。 newlibc 在内部函数_fread_r 中也有循环。从 BSD 派生的 Apple libc 在__fread__fread0 中也有正确的循环。您必须指的是古代或异国情调的实现。如果fread 停在某个随机位置,则无法正确重新启动它。有意义的是,它只会因为文件结束或读取错误而失败,就像getc
  • @Lance:你们在同一台计算机上编码和解码吗?您只发布了一段代码,我无法告诉您应用程序的其余部分有什么不正确的地方。
猜你喜欢
  • 2014-01-07
  • 2015-06-16
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多