zoukankan      html  css  js  c++  java
  • C#中计算流指定位置和长度的MD5值

    在Microsoft .NET Framework 2.0中,计算MD5值可以用到System.Security.Cryptography.MD5CryptoServiceProvider类,其计算MD5的方法ComputeHash()有三个重载方法。


    名称 说明

    ComputeHash(Byte[]) 计算指定字节数组的哈希值。 (继承自 HashAlgorithm。)

    ComputeHash(Stream) 计算指定 Stream 对象的哈希值。 (继承自 HashAlgorithm。)

    ComputeHash(Byte[], Int32, Int32) 计算指定字节数组的指定区域的哈希值。 (继承自 HashAlgorithm。)

    如果需要计算文件流中指定区域的哈希值(如大文件传输断点续传)时,这三个方法就不够用了,我们需要一个如下的重载方法:


    名称 说明

    ComputeHash(Stream,Int32,Int32) 计算指定 Stream 对象的指定区域的哈希值。(继承自 HashAlgorithm。)

      

    不过微软并没有提供这个方法来计算流中指定区域的MD5值。通过反编译mscorlib.dll与查看微软公布的Framework部分源代码,发现Windows 2000 Professol与Windows XP及以上操作系统提供了一个 "Cryptdll.dll”,其中有3个关于计算MD5的API函数:

    MD5Init

    The MD5Init function initializes an MD5 message digest context. The context must be initialized for any new MD5 message digest. This function is defined by RSA.

    void MD5Init(
    MD5_CTX* context
    );

    MD5Update

    The MD5Update function updates the MD5 context by using the supplied buffer for the message whose MD5 digest is being generated. This function is called for each buffer of the message being hashed. This function is defined by RSA.

    void MD5Update(
    MD5_CTX context,
    unsigned char* input,
    unsigned int inlen
    );

    MD5Final

    The MD5Final function ends an MD5 message digest previously started by a call to the MD5Init function. Prior to calling MD5Final, use the MD5Update function to update the MD5 message digest context with each buffer in the message being hashed. This function is defined by RSA.

    void MD5Final(
    MD5_CTX context
    );
    有了这些准备,就可以实现计算流中指定区域的MD5值了,下面是MyMD5类的源代码:
     1       public sealed class MyMD5 : HashAlgorithm
     2       {          [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
     3           public struct MD5_CTX
     4           {
     5               /// ULONG[2]              [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U4)]
     6               public uint[] i;
     7               /// ULONG[4]              [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U4)]
     8               public uint[] buf;
     9               /// unsigned char[64]              [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 64)]
    10               public byte[] @in;
    11               /// unsigned char[16]
    12               [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 16)]
    13               public byte[] digest;
    14           }
    15 
    16           [DllImport("cryptdll.dll")]
    17           public static extern void MD5Init(ref MD5_CTX context);
    18           [DllImport("cryptdll.dll")]
    19           public static extern void MD5Update(ref MD5_CTX context, Byte[] input, Int32 inlen);
    20           [DllImport("cryptdll.dll")]
    21           public static extern void MD5Final(ref MD5_CTX context);
    22 
    23           MD5_CTX md5data = new MD5_CTX();
    24           protected override void HashCore(byte[] array, int ibStart, int cbSize)
    25           {
    26               if (ibStart != 0)
    27               {
    28                   byte[] tmparray = new byte[cbSize - ibStart];
    29                   array.CopyTo(tmparray, ibStart);
    30                   array = tmparray;
    31               }
    32               MD5Update(ref md5data, array, cbSize);
    33           }
    34 
    35           protected override byte[] HashFinal()
    36           {
    37               MD5Final(ref md5data);
    38               return md5data.digest;
    39           }
    40 
    41           public MyMD5()
    42           {
    43               Initialize();
    44           }
    45           public override void Initialize()
    46           {
    47               MD5Init(ref md5data);
    48           }
    49 
    50           public byte[] ComputeHash(Stream inputStream, int offset, long count)
    51           {
    52               int num;
    53               long totalHashCount = 0;
    54               inputStream.Seek(offset,SeekOrgin.Begin);//感谢denworld指正
    55               byte[] buffer = new byte[0x1000];
    56               do
    57               {
    58                   int readCount = buffer.Length;
    59                   if (count - totalHashCount < buffer.Length)
    60                   {
    61                       readCount = (int)(count - totalHashCount);
    62                   }
    63                   num = inputStream.Read(buffer, 0, readCount);
    64                   if (num > 0)
    65                   {
    66                       this.HashCore(buffer, 0, num);
    67                       totalHashCount += num;
    68                   }
    69               }
    70               while (num > 0);
    71               this.HashValue = this.HashFinal();
    72               byte[] buffer2 = (byte[])this.HashValue.Clone();
    73               this.Initialize();
    74               return buffer2;
    75           }
    76       }
  • 相关阅读:
    Run Loop简介 分类: ios技术 ios相关 2015-03-11 22:21 73人阅读 评论(0) 收藏
    iOS Socket第三方开源类库 ----AsyncSocket 分类: ios相关 ios技术 2015-03-11 22:14 59人阅读 评论(0) 收藏
    CocoaPods安装和使用教程 分类: ios技术 ios相关 2015-03-11 21:53 48人阅读 评论(0) 收藏
    详解Objective-C的meta-class 分类: ios相关 ios技术 2015-03-07 15:41 51人阅读 评论(0) 收藏
    IOS即时通讯XMPP搭建openfire服务器 分类: ios技术 2015-03-07 11:30 53人阅读 评论(0) 收藏
    IOS之富文本编辑 分类: ios技术 2015-03-06 22:51 89人阅读 评论(0) 收藏
    IOS第三方数据库--FMDB 分类: ios技术 2015-03-01 09:38 57人阅读 评论(0) 收藏
    ASIHTTPRequest异步请求 分类: ios技术 2015-03-01 09:33 48人阅读 评论(0) 收藏
    python+day6 json,pickle 模块
    python_day6 log模块
  • 原文地址:https://www.cnblogs.com/aaaSoft/p/1533210.html
Copyright © 2011-2022 走看看