哈希计算器

Form1.cs代码:

using System;
using System.ComponentModel;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;

namespace HashDemo
{
    public partial class Form1 : Form
    {
        public enum HashAlgo
        {
            CRC32,
            MD5,
            SHA1,
            SHA256,
            SHA384,
            SHA512,
            RipeMd,
        }

        private HashAlgorithm Hash;
        private bool hashingFinished;
        private FileStream inFile;
        private HashAlgo selectedHash;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            BgWorker.ProgressChanged += BgWorker_ProgressChanged;
            BgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
            FileNameTextBox.DragEnter += FileNameTextBox_DragEnter; //拖放效果
            FileNameTextBox.DragDrop += FileNameTextBox_DragDrop; //捕捉
            DragEnter += FileNameTextBox_DragEnter;
            DragDrop += FileNameTextBox_DragDrop;
            selectedHash = HashAlgo.CRC32;
        }

        private void BrowseButton_Click(object sender, EventArgs e)
        {
            DialogResult myDialogResult;
            myDialogResult = OpenFile.ShowDialog();

            if (myDialogResult == DialogResult.Cancel)
                return; // 如果按下取消,则退出

            FileNameTextBox.Text = OpenFile.FileName;
        }

        private void CalculateButton_Click(object sender, EventArgs e)
        {
            BgWorker.RunWorkerAsync(); //在单独的线程上运行哈希计算
            CalculateButton.Enabled = false;
        }

        private void CrcRadio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.CRC32;
        }

        private void Md5Radio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.MD5;
        }

        private void Sha1Radio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.SHA1;
        }

        private void Sha256Radio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.SHA256;
        }

        private void Sha384Radio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.SHA384;
        }

        private void Sha512Radio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.SHA512;
        }

        private void RipemdRadio_CheckedChanged(object sender, EventArgs e)
        {
            selectedHash = HashAlgo.RipeMd;
        }

        private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressBar.Value = e.ProgressPercentage;
        }

        private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            switch (selectedHash)
            {
                case HashAlgo.MD5:
                    Hash = new MD5CryptoServiceProvider();
                    break;
                case HashAlgo.SHA1:
                    Hash = new SHA1CryptoServiceProvider();
                    break;
                case HashAlgo.SHA256:
                    Hash = new SHA256CryptoServiceProvider();
                    break;
                case HashAlgo.SHA384:
                    Hash = new SHA384CryptoServiceProvider();
                    break;
                case HashAlgo.SHA512:
                    Hash = new SHA512CryptoServiceProvider();
                    break;
                case HashAlgo.RipeMd:
                    Hash = new RIPEMD160Managed();
                    break;
                    //case HashAlgo.Adler32:
                    //    Hash = new Adler32();
                    //    break;
                case HashAlgo.CRC32:
                    Hash = new CRC32();
                    break;
            }

            try
            {
                inFile = new FileStream(FileNameTextBox.Text, FileMode.Open);

                const int bufSize = 4096;
                var buffer = new byte[bufSize];
                int readBytes = 1;
                long filePos;
                long fileLength = inFile.Length;

                while (readBytes > 0)
                {
                    int progress;

                    readBytes = inFile.Read(buffer, 0, bufSize);
                    filePos = inFile.Position;

                    if (readBytes == 4096)
                    {
                        Hash.TransformBlock(buffer, 0, bufSize, null, 0);
                        progress = (int) ((filePos/(float) fileLength)*100);
                    }
                    else
                    {
                        Hash.TransformFinalBlock(buffer, 0, readBytes);
                        progress = 100;
                    }

                    BgWorker.ReportProgress(progress);
                }

                hashingFinished = true;
                inFile.Close();
            }
            catch (IOException)
            {
                MessageBox.Show("无法打开所选文件.", "文件打开错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (CryptographicException)
            {
                MessageBox.Show("处理文件时出错.", "哈希错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ex.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (hashingFinished)
                hashTextBox.Text = BitConverter.ToString(Hash.Hash).Replace("-", "").ToLower();
            CalculateButton.Enabled = true;
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var form = new About();
            form.ShowDialog();
        }

        private void FileNameTextBox_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.All;
        }

        private void FileNameTextBox_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                var myFiles = (string[]) e.Data.GetData(DataFormats.FileDrop);
                FileNameTextBox.Text = myFiles[0];
            }
        }
    }
}

CRC32.cs代码:

using System;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace HashDemo
{
    /// <summary>实现32位循环冗余校验(CRC)哈希算法。</summary>
    /// <remarks>此类不适用于安全目的。 对于安全应用,使用MD5,SHA1,SHA256,SHA384,或SHA512在System.Security.Cryptography命名空间。</remarks>
    public class CRC32 : HashAlgorithm
    {
        #region 构造函数

        static CRC32()
        {
            _crc32TablesCache = Hashtable.Synchronized(new Hashtable());
            _defaultCRC = new CRC32();
        }

        /// <summary>创建一个CRC32对象使用<see cref="DefaultPolynomial" />.</summary>
        public CRC32()
            : this(DefaultPolynomial)
        {
        }

        /// <summary>使用指定的多项式创建CRC32对象</summary>
        /// <remarks>多项式应以位反射形式提供<see cref="DefaultPolynomial" />.</remarks>
        [CLSCompliant(false)]
        public CRC32(uint polynomial)
        {
            HashSizeValue = 32;
            _crc32Table = (uint[]) _crc32TablesCache[polynomial];
            if (_crc32Table == null)
            {
                _crc32Table = _buildCRC32Table(polynomial);
                _crc32TablesCache.Add(polynomial, _crc32Table);
            }
            Initialize();
        }

        //静态构造函数

        #endregion

        #region 属性

        /// <summary>获取默认多项式(在WinZip,以太网等中使用)</summary>
        /// <remarks>默认多项式是WinZip,以太网等使用的标准多项式0x04C11DB7的位反映版本。</remarks>
        [CLSCompliant(false)] public static readonly uint DefaultPolynomial = 0xEDB88320; //0x04C11DB7的逐位反射;

        #endregion

        #region 方法

        /// <summary>初始化HashAlgorithm的实现</summary>
        public override void Initialize()
        {
            _crc = _allOnes;
        }

        /// <summary>将写入对象的数据路由到用于计算哈希的哈希算法中.</summary>
        protected override void HashCore(byte[] buffer, int offset, int count)
        {
            for (int i = offset; i < count; i++)
            {
                ulong ptr = (_crc & 0xFF) ^ buffer[i];
                _crc >>= 8;
                _crc ^= _crc32Table[ptr];
            }
        }

        /// <summary>在加密流对象处理最后一个数据之后,完成哈希计算.</summary>
        protected override byte[] HashFinal()
        {
            var finalHash = new byte[4];
            ulong finalCRC = _crc ^ _allOnes;

            finalHash[0] = (byte) ((finalCRC >> 0) & 0xFF);
            finalHash[1] = (byte) ((finalCRC >> 8) & 0xFF);
            finalHash[2] = (byte) ((finalCRC >> 16) & 0xFF);
            finalHash[3] = (byte) ((finalCRC >> 24) & 0xFF);

            Array.Reverse(finalHash);

            return finalHash;
        }

        /// <summary>使用该方法计算给定ASCII字符串的CRC32值<see cref="DefaultPolynomial" />.</summary>
        public static int Compute(string asciiString)
        {
            _defaultCRC.Initialize();
            return ToInt32(_defaultCRC.ComputeHash(asciiString));
        }

        /// <summary>计算给定输入流的CRC32值 <see cref="DefaultPolynomial" />.</summary>
        public static int Compute(Stream inputStream)
        {
            _defaultCRC.Initialize();
            return ToInt32(_defaultCRC.ComputeHash(inputStream));
        }

        /// <summary>使用该输入数据计算CRC32值 <see cref="DefaultPolynomial" />.</summary>
        public static int Compute(byte[] buffer)
        {
            _defaultCRC.Initialize();
            return ToInt32(_defaultCRC.ComputeHash(buffer));
        }

        /// <summary>使用该计算输入数据的哈希值 <see cref="DefaultPolynomial" />.</summary>
        public static int Compute(byte[] buffer, int offset, int count)
        {
            _defaultCRC.Initialize();
            return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count));
        }

        /// <summary>计算给定ASCII字符串的哈希值。</summary>
        /// <remarks>计算保留了调用之间的内部状态,因此可以用于流数据的计算。</remarks>
        public byte[] ComputeHash(string asciiString)
        {
            byte[] rawBytes = Encoding.ASCII.GetBytes(asciiString);
            return ComputeHash(rawBytes);
        }

        /// <summary>计算给定输入流的哈希值。</summary>
        /// <remarks>计算保留了调用之间的内部状态,因此可以用于流数据的计算。</remarks>
        public new byte[] ComputeHash(Stream inputStream)
        {
            var buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.Read(buffer, 0, 4096)) > 0)
            {
                HashCore(buffer, 0, bytesRead);
            }
            return HashFinal();
        }

        /// <summary>计算输入数据的哈希值。</summary>
        /// <remarks>计算保留了调用之间的内部状态,因此可以用于流数据的计算。</remarks>
        public new byte[] ComputeHash(byte[] buffer)
        {
            return ComputeHash(buffer, 0, buffer.Length);
        }

        /// <summary>计算输入数据的哈希值。</summary>
        /// <remarks>计算保留了调用之间的内部状态,因此可以用于流数据的计算。</remarks>
        public new byte[] ComputeHash(byte[] buffer, int offset, int count)
        {
            HashCore(buffer, offset, count);
            return HashFinal();
        }

        #endregion

        #region 私有部分

        private static uint _allOnes = 0xffffffff;
        private static readonly CRC32 _defaultCRC;
        private static readonly Hashtable _crc32TablesCache;
        private readonly uint[] _crc32Table;
        private uint _crc;

        //构建一个给定一个多项式的crc32表
        private static uint[] _buildCRC32Table(uint polynomial)
        {
            uint crc;
            var table = new uint[256];

            // 256个值代表ASCII字符代码
            for (int i = 0; i < 256; i++)
            {
                crc = (uint) i;
                for (int j = 8; j > 0; j--)
                {
                    if ((crc & 1) == 1)
                        crc = (crc >> 1) ^ polynomial;
                    else
                        crc >>= 1;
                }
                table[i] = crc;
            }

            return table;
        }

        private static int ToInt32(byte[] buffer)
        {
            return BitConverter.ToInt32(buffer, 0);
        }

        #endregion
    }
}

设计界面如图:

这里写图片描述

运行结果如图:

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设备端与阿里云IoT平台建立MQTT通道的CONNECT报文有三个关键参数:客户端标识符 (ClientId) ,用户名(User Name),密码(Password)。这三个参数由设备三元组(productKey,deviceName,deviceSecret)按照阿里云IoT签名规则生成。 参数 生成方式 描述 username deviceName+"&"+productKey password sign_hmac(deviceSecret,content) sign_hmac为mqttClientId中的signmethod content为 "clientId${id}deviceName${deviceName}productKey${productKey}timestamp${timestamp}" 其中 id:表示客户端ID,64字符内。 timestamp:表示当前时间毫秒值。 clientId id+"|securemode=3,signmethod=hmacsha1,timestamp="+timestamp+"|" id:表示客户端ID,64字符内。 timestamp:表示当前时间毫秒值。 securemode:表示安全模式:可选值有2(TLS加密)和3(非加密) signmethod:表示签名算法类型。支持hmacmd5,hmacsha1和hmacsha256 2. 三元组接入示例 2.1 设备三元组信息 设备三元组 productKey = a14Xib5kdYd deviceName = light1983432 deviceSecret = oLyaKqVxtRvjH284LdhqVgVUx1UPy6zq 建立MQTT连接时参数 clientId = SN1928339 timestamp = 1539421321846 signmethod = hmacsha1 2.2 参数生成结果 mqttClientId = SN1928339|securemode=3,signmethod=hmacsha1,timestamp=1539421321846| mqttUsername = light1983432&a14Xib5kdYd mqttPassword = b2488041f64f425016b467ee1c94959ebd592ad1 生成password的content content=clientIdSN1928339deviceNamelight1983432productKeya14Xib5kdYdtimestamp1539421321846 2.3 建立连接 mqttClientId作为MQTT客户端标识符 (ClientId) mqttUsername作为MQTT用户名(User Name) mqttPassword作为MQTT密码(Password) 在线Password生成算法验证

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值