[C#] Progress Bars with SHA1CryptoServiceProvider help!

Discussion in 'Mixed Languages' started by jlgager, May 11, 2011.

  1. jlgager

    jlgager MDL Developer

    Oct 30, 2009
    365
    3,230
    10
    #1 jlgager, May 11, 2011
    Last edited by a moderator: Apr 20, 2017
    I am trying to report progress of the SHA1CryptoServiceProvider which is getting the SHA1 hash of an input file to the progress bar. I have the SHA1CryptoServiceProvider in one background process and a timer in another. The timer is what is reporting progress as I don't know how to do it with the SHA1CryptoServiceProvider. The problem is that I need to either get the SHA1CryptoServiceProvider to report progress or have according to the file size the program guess how long it will take and increment the progress bar correctly. Both so that the progress bar is at 100 or very close when the hash is completed.
    Here is my code.

    View attachment WindowsFormsApplication1.rar

    Code:
     string strfilepath;
            string hash;
            long s1;
            float s2;
            FileInfo f;
            bool running;
            private void btnBrowse_Click(object sender, EventArgs e)
            {
                openFD.InitialDirectory = "C:/";
                openFD.Title = "Please Select An ISO";
                openFD.FileName = "";
                openFD.Filter = "ISO Files|*.iso";
    
                if (openFD.ShowDialog() != DialogResult.Cancel)
                {
                    txtFilepath.Text = openFD.FileName;
                }
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                try
                {
                    strfilepath = txtFilepath.Text;
                    f = new FileInfo(strfilepath);
                    s1 = f.Length;
                    MessageBox.Show(Convert.ToString(s1));
                    s2 = s1 / 102400000;
                    s2 = s2 / 100;
                    s2 = s2 / 1.4F;
                    MessageBox.Show(Convert.ToString(s2));
                    if (File.Exists(strfilepath))
                    {
                        if (bw.IsBusy != true)
                        {
                            running = true;
                            bw.RunWorkerAsync();
                        }
                        if (bw2.IsBusy != true)
                        {
                            bw2.RunWorkerAsync();
                        }
                        if (running == true)
                        {
                            MessageBox.Show("Running");
                            running = false;
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message, "Error!",
                             System.Windows.Forms.MessageBoxButtons.OK,
                             System.Windows.Forms.MessageBoxIcon.Error,
                             System.Windows.Forms.MessageBoxDefaultButton.Button1);
                }
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                hash = GetSHA1Hash(strfilepath);
            }
    
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
    
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if ((e.Cancelled == true))
                {
                    MessageBox.Show("Canceled!");
                }
    
                else if (!(e.Error == null))
                {
                    MessageBox.Show("Error: " + e.Error.Message);
                }
    
                else
                {
                        bw2.CancelAsync();
                        MessageBox.Show("Hash Made!");
                        txtHash.Text = hash;
                }
            }
    
            public static string GetSHA1Hash(string filename)
            {
                string strHash = "";
    
                StreamReader sr = new StreamReader(filename);
                SHA1CryptoServiceProvider sha1h = new SHA1CryptoServiceProvider();
    
                try
                {
                    strHash = BitConverter.ToString(sha1h.ComputeHash(sr.BaseStream));
                    sr.Close();
                    strHash = strHash.Replace("-", "");
                }
                catch (System.Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message, "Error!",
                             System.Windows.Forms.MessageBoxButtons.OK,
                             System.Windows.Forms.MessageBoxIcon.Error,
                             System.Windows.Forms.MessageBoxDefaultButton.Button1);
                }
    
                return strHash;
            }
    
            private void bw2_DoWork(object sender, DoWorkEventArgs e)
            {
                for (int i = 1; i <= 100; i++)
                {
                    if ((bw2.CancellationPending == true))
                    {
                        e.Cancel = true;
                        break;
                    }
                    else
                    {
                        Thread.Sleep(446);
                        bw2.ReportProgress(i);
                    }
                }
            }
    
            private void bw2_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                progressBar1.Value = e.ProgressPercentage;
                this.Text = e.ProgressPercentage.ToString() + "%";
            }
    
            private void bw2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if ((e.Cancelled == true))
                {
                    MessageBox.Show("Timer Stopped!");
                }
    
                else if (!(e.Error == null))
                {
                    MessageBox.Show("Error: " + e.Error.Message);
                }
    
                else
                {
                    MessageBox.Show("Timer Done!");
                    progressBar1.Value = 100;
                }
            }
     
  2. jlgager

    jlgager MDL Developer

    Oct 30, 2009
    365
    3,230
    10
    #2 jlgager, May 11, 2011
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Code:
    f = new FileInfo(strfilepath);
                    s1 = f.Length;
                    MessageBox.Show(Convert.ToString(s1));
                    s2 = s1 / 102400000;
                    s2 = s2 / 100;
                    s2 = s2 / 1.4F;
                    MessageBox.Show(Convert.ToString(s2));
    This part if the code was my attempt at getting the file size.
    The first line successfully retrieves the file size but I don't know what to do with it after I have retrieved it.
     
  3. BobSheep

    BobSheep MDL Guru

    Apr 19, 2010
    2,330
    1,377
    90
    I don't think it's possible to find out how much work the hash computation has done at any point in time. But I have a suggestion. Have a fixed size file and do a dummy compute hash to get the elapsed time, then work out how much bigger the real file is than the fixed sized file and estimate a time for the real file. Then have a countdown timer to update the progress bars.
     
  4. Stannieman

    Stannieman MDL Guru

    Sep 4, 2009
    2,232
    1,818
    90
    But not every computer can compute the hash at the same time + it depends on cpu and disk load, so it's pretty inaccurate.
    I think the only accurate way is to write the hash algorithm yourself, and then devide the total bytes of the calculated file by 100. Everytime that value is done you add a % to the bar.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. BobSheep

    BobSheep MDL Guru

    Apr 19, 2010
    2,330
    1,377
    90
    You would compute the hash on each computer so the ratio would be correct for each computer not compute the has once on your dev machine.
     
  6. Stannieman

    Stannieman MDL Guru

    Sep 4, 2009
    2,232
    1,818
    90
    But it's still inaccurate, imagine that you start to rar a file with max compression during hashing, or start hashing another file.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. BobSheep

    BobSheep MDL Guru

    Apr 19, 2010
    2,330
    1,377
    90
    Yes it's still inaccurate. Have you ever installed Visual Studoi 2003? The progress bar is 95% complete and yet it still takes about 30 minutes more to finish. Sometimes compromise is the best you can do.
     
  8. nikop

    nikop MDL Novice

    May 25, 2008
    5
    5
    0
    Solution is manually to read into buffer and use TransformBlock (TransformFinalBlock) for each block
     
  9. Alphawaves

    Alphawaves Super Moderator/Developer
    Staff Member

    Aug 11, 2008
    6,222
    22,280
    210
    #9 Alphawaves, Oct 19, 2011
    Last edited by a moderator: Apr 20, 2017
    Heres a method i used to use using TransformBlock to get an MD5 hash:

    Code:
    using System.IO;
    using System.Security.Cryptography;
    
    namespace GetMD5
    {
        public partial class Fmd5 : Form
        {
            private string GHS = "";
            private delegate void SetBoolDelegate(bool b);
            private delegate string ReturnTextDelegate();
            private delegate void SetIntDelegate(int value);
            private delegate void SetTextDelegate(string result);
            private OpenFileDialog Dialog = new OpenFileDialog();
            public Fmd5()
            {
                InitializeComponent();
            }
            private void pbvalue(int value)
            {
                pb.Value = value;
                OUTtxt.Text = "Computing Hash .. " + pb.Value.ToString() + "%";
            }
            private void TxtMD5(string result)
            {
                HASHtxt.Text = result;
            }
            private void GetHash_Click(object sender, EventArgs e)
            {
                Dialog.Title = "Select File";
                if (Dialog.ShowDialog() != DialogResult.OK)
                {
                    GHS = "";
                    return;
                }
                else
                {
                    HASHtxt.ResetText();
                    HASHtxt.Visible = false;
                    GHS = Dialog.FileName;
                    GetHash.Enabled = false;
                    HashWorker.RunWorkerAsync();
                }
            }
    
            public enum MD5HASH
            {
                MD5 = 1
            }
            public void GetHASH(object compute)
            {
                    MD5HASH computeH = (MD5HASH)compute;
                    string HFile = (string)Invoke(new ReturnTextDelegate(GHS.ToString), new object[0]);
                    FileStream stream = File.OpenRead(HFile);
                    long length = stream.Length;
                    byte[] buffer = new byte[0x2000];
                    int readBytes = -1;
                    long num = 0L;
                    int val = 0;
                    int val1 = 0;
                    HashAlgorithm FMD5 = null;
                    FMD5 = MD5.Create();
                    while (readBytes != 0)
                    {
                        readBytes = stream.Read(buffer, 0, buffer.Length);
                        FMD5.TransformBlock(buffer, 0, readBytes, null, 0);
                        num += readBytes;
                        val = (int)((((double)num) / ((double)length)) * 100.0);
                        if (val1 != val)
                        {
                            Invoke(new SetIntDelegate(pbvalue), new object[] { val });
                            val1 = val;
                        }
                    }
                        byte[] buffer2 = null;
                        string str = "";
                        FMD5.TransformFinalBlock(buffer, 0, 0);
                        buffer2 = FMD5.Hash;
                        for (int j = 0; j < buffer2.Length; j++)
                        {
                            str = str + string.Format("{0:X2}", buffer2[j]);
                        }
                            Invoke(new SetTextDelegate(TxtMD5), new object[] { str });
            }
    
            private void HashWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                GetHASH(MD5HASH.MD5);
            }
    
            private void HashWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                GHS = "";
                GetHash.Enabled = true;
                HASHtxt.Visible = true;
                OUTtxt.ResetText();
                OUTtxt.Visible = false;
                pb.Value = 0;
            }
        }
    }