C ++ Tweetnacl将没有读取整个文件的文件哈希到内存中

时间:2016-10-12 11:26:09

标签: c++ c hash

我正在使用tweetnacl生成sha512字符串和文件的哈希值。对于字符串,它工作得很好,但我不知道如何使用文件。

函数的签名是

public static DataTable ReadAsDataTable(string fileName)
{

    DataTable dataTable = new DataTable();
    using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(fileName, false))
    {
        WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
        IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
        Worksheet workSheet = worksheetPart.Worksheet;
        SheetData sheetData = workSheet.GetFirstChild<SheetData>();
        IEnumerable<Row> rows = sheetData.Descendants<Row>();

        foreach (Cell cell in rows.ElementAt(0))
        {
            dataTable.Columns.Add(GetCellValue(spreadSheetDocument, cell));
        }

        foreach (Row row in rows)
        {
            DataRow dataRow = dataTable.NewRow();
            for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
            {
                dataRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
            }

            dataTable.Rows.Add(dataRow);
        }

    }
    dataTable.Rows.RemoveAt(0);

    return dataTable;
}

其中u8的类型为unsigned char,u64的长度为unsigend。 对于字符串,a可以像那样使用它

extern "C" int crypto_hash(u8 *out, const u8 *m, u64 n);

这适用于字符串和小文件,但如果我想为大文件创建哈希,则它不可行并且用于大量内存。我搜索一个逐字节读取文件的解决方案,并将其作为unsigend char指针传递给该函数。有谁知道如何实现这一目标?

P.S抱歉英语不好。 p.s.s我使用tweetnacl因为体积小而且我只需要散列函数。

2 个答案:

答案 0 :(得分:3)

可能最简单的方法是使用memory-mapped file。这使您可以打开文件并将其映射到虚拟内存中,然后您可以将磁盘上的文件视为内存,操作系统将根据需要加载页面。

因此,在您的情况下,打开您的文件并使用mmap()将其映射到内存中。然后,您可以将指针传递到crypto_hash()函数中,让操作系统完成工作。

请注意,有些警告与虚拟内存的文件大小有关。

对于各种平台:

答案 1 :(得分:2)

我建议您使用不同的实现,您可以逐步提供块。

This one for example。由于许可证是bsd且代码是C而没有依赖关系,因此您只需复制/粘贴所需的3个函数,而无需将整个库(无论多小)添加到项目中。

生命周期如下:

  • sha256_init(&ctx)

  • 重复从文件中读取块并将其反馈到sha256_update(&ctx, buff, buffLen)

  • 当EOF时,使用sha256_final(&ctx, digestHere)

  • 获取摘要