获取使用 SHA1CryptoServiceProvider 计算 SHA1 的进度

发布于 2024-11-17 11:46:21 字数 643 浏览 4 评论 0原文

目前,我正在 C++/CLI 代码中实现一个返回文件 SHA1 值的函数。它是 Visual Studio 中的 Windows 窗体应用程序。

我选择实现 .NetFramework 类 SHA1CryptoServiceProvider 因为它真的很快(相信我)。我测试了几种算法,但没有一个算法像 SHA1CryptoServiceProvider 类那么快。

问题是,在我的应用程序中,有一个进度条显示计算 SHA1 的进度,而 SHA1CryptoServiceProvider 类没有任何返回计算 SHA1 进度的函数。

这是代码:

using namespace System::Security::Cryptography;
using namespace System::IO;

StreamReader^ Reader = gcnew StreamReader("C:\\abc.exe");
SHA1CryptoServiceProvider^ SHA1 = gcnew SHA1CryptoServiceProvider();

String^ Hash = "";

Hash = BitConverter::ToString(SHA1->ComputeHash(Reader->BaseStream));
return Hash;

Currently I am implementing into my C++/CLI code a function that return the SHA1 value of a file. It is a Windows Forms application in Visual Studio.

I chose to implement the .NetFramework class SHA1CryptoServiceProvider because it is really fast (believe me). I have tested several algorithms but none of them were as fast as the SHA1CryptoServiceProvider class.

The problem is that in my application there is a progressBar showing the progress of computing SHA1 and the SHA1CryptoServiceProvider class doesn't have any function that returns progress of computing SHA1.

Here is the code:

using namespace System::Security::Cryptography;
using namespace System::IO;

StreamReader^ Reader = gcnew StreamReader("C:\\abc.exe");
SHA1CryptoServiceProvider^ SHA1 = gcnew SHA1CryptoServiceProvider();

String^ Hash = "";

Hash = BitConverter::ToString(SHA1->ComputeHash(Reader->BaseStream));
return Hash;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过期情话 2024-11-24 11:46:21

最后我做到了。我发布代码,也许有人会发现它有用。我知道代码不干净,我仍在学习。它可以计算大于 2^31 字节的文件的 SHA1。在 22GB 文件上进行了测试。在后台工作人员中工作正常:)

#define SHA1_BUFFER_SIZE  65535
//input buffer
array<unsigned char,1>^ buf = gcnew array<unsigned char,1>(SHA1_BUFFER_SIZE);
pin_ptr<unsigned char> pointer = &buf[0];

//Open file in 64-bit mode
FILE *file = _fopeni64("some_large_file.txt","rb");
SHA1CryptoServiceProvider^ SHA1 = gcnew SHA1CryptoServiceProvider();

//Move pointer to End of File
_fseeki64(file,0,SEEK_END);
//Read pointer position (file size)
unsigned __int64 size = (__int64)_ftelli64(file);

// Move pointer to begining of file
_fseeki64(file,0,SEEK_SET);
__int64 i = 1;    // counter
float wyn = 0;    // help variable for progress Percentage (float)
__int64 conv = 0; // help variable for progress Percentage (int)

//output buffer
array<unsigned char,1>^ outputbuffer = gcnew array<unsigned char,1>(SHA1_BUFFER_SIZE);
while(1)
{
    //Read SHA1_BUFFER_SIZE bytes to buffer
    size_t bufLen = fread( pointer, 1, SHA1_BUFFER_SIZE, file );
    if (bufLen == 0) //End of file
    {
        if (ferror(file)) //Error opening file
            return;
        break;
    }
    //buffer has the last block of bytes of the file
    if ( SHA1_BUFFER_SIZE*i >= size  )
        SHA1->TransformFinalBlock(buf,0,bufLen);
    else
        SHA1->TransformBlock(buf,0,bufLen,outputbuffer,0);

    wyn = SHA1_BUFFER_SIZE*100; /* Getting    */
    wyn /= size;                /* the        */
    wyn *= i;                   /* progress   */
    conv = wyn;                 /* Percentage */
    ComputeSHA1->ReportProgress(conv);
    \\Update our progressBar
    i++;
} //End main loop

String^ sHash = "";
//Get the computed hash and convert to System::String
sHash = BitConverter::ToString(SHA1->Hash);
//Replace the '-' characters in hash to white spaces
sHash = sHash->Replace('-',' ');
//Removing whitespaces from hash
sHash = System::Text::RegularExpressions::Regex::Replace(sHash, "\\s+", System::String::Empty);

//Filling a textBox with the SHA1
ComputeSHA1->ReportProgress(0,sHash);

Finally I have done it. I post the code, maybe someone will find it useful. I know the code is not clean, I am still learning. It can compute SHA1 of files larger that 2^31 bytes. Tested it on a 22GB file. Works fine in backgroundWorker :)

#define SHA1_BUFFER_SIZE  65535
//input buffer
array<unsigned char,1>^ buf = gcnew array<unsigned char,1>(SHA1_BUFFER_SIZE);
pin_ptr<unsigned char> pointer = &buf[0];

//Open file in 64-bit mode
FILE *file = _fopeni64("some_large_file.txt","rb");
SHA1CryptoServiceProvider^ SHA1 = gcnew SHA1CryptoServiceProvider();

//Move pointer to End of File
_fseeki64(file,0,SEEK_END);
//Read pointer position (file size)
unsigned __int64 size = (__int64)_ftelli64(file);

// Move pointer to begining of file
_fseeki64(file,0,SEEK_SET);
__int64 i = 1;    // counter
float wyn = 0;    // help variable for progress Percentage (float)
__int64 conv = 0; // help variable for progress Percentage (int)

//output buffer
array<unsigned char,1>^ outputbuffer = gcnew array<unsigned char,1>(SHA1_BUFFER_SIZE);
while(1)
{
    //Read SHA1_BUFFER_SIZE bytes to buffer
    size_t bufLen = fread( pointer, 1, SHA1_BUFFER_SIZE, file );
    if (bufLen == 0) //End of file
    {
        if (ferror(file)) //Error opening file
            return;
        break;
    }
    //buffer has the last block of bytes of the file
    if ( SHA1_BUFFER_SIZE*i >= size  )
        SHA1->TransformFinalBlock(buf,0,bufLen);
    else
        SHA1->TransformBlock(buf,0,bufLen,outputbuffer,0);

    wyn = SHA1_BUFFER_SIZE*100; /* Getting    */
    wyn /= size;                /* the        */
    wyn *= i;                   /* progress   */
    conv = wyn;                 /* Percentage */
    ComputeSHA1->ReportProgress(conv);
    \\Update our progressBar
    i++;
} //End main loop

String^ sHash = "";
//Get the computed hash and convert to System::String
sHash = BitConverter::ToString(SHA1->Hash);
//Replace the '-' characters in hash to white spaces
sHash = sHash->Replace('-',' ');
//Removing whitespaces from hash
sHash = System::Text::RegularExpressions::Regex::Replace(sHash, "\\s+", System::String::Empty);

//Filling a textBox with the SHA1
ComputeSHA1->ReportProgress(0,sHash);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文