前一段时间把MD5写出来了:
http://blog.csdn.net/aimeast/archive/2008/11/19/3337153.aspx
今天又把SHA1写了出来。
这个类于前面那个MD5是相似的。正确性的验证也于MD5完全相同。
检测算法正确性的代码
用这段代码检测,只要出现了 OK!........说明我的算法是正确的。
今天又把SHA1写了出来。
这个类于前面那个MD5是相似的。正确性的验证也于MD5完全相同。
- /*********************************************/
- //
- //
- // 未经允许,禁止转载
- // 2008-11-22 23:42:39
- // Email: lixd3389@gmail.com
- // Blog: http://blog.csdn.net/aimeast
- // 原文地址:http://blog.csdn.net/aimeast/archive/2008/11/22/3352612.aspx
- //
- /*********************************************/
- using System;
- using System.IO;
- namespace MY_SHA1
- {
- class My_SHA1
- {
- private static UInt32 h0, h1, h2, h3, h4;
- private const UInt32 K1 = 0x5A827999;
- private const UInt32 K2 = 0x6ED9EBA1;
- private const UInt32 K3 = 0x8F1BBCDC;
- private const UInt32 K4 = 0xCA62C1D6;
- private static UInt32 F1(UInt32 x, UInt32 y, UInt32 z) { return (z ^ (x & (y ^ z))); }
- private static UInt32 F2(UInt32 x, UInt32 y, UInt32 z) { return (x ^ y ^ z); }
- private static UInt32 F3(UInt32 x, UInt32 y, UInt32 z) { return ((x & y) | (z & (x | y))); }
- private static UInt32 F4(UInt32 x, UInt32 y, UInt32 z) { return (x ^ y ^ z); }
- private static UInt32 rol(UInt32 x, int n) { return ((x << n) | (x >> (32 - n))); }
- private static UInt32 M(UInt32[] x, int i)
- {
- UInt32 tm = x[i & 0x0f] ^ x[(i - 14) & 0x0f] ^ x[(i - 8) & 0x0f] ^ x[(i - 3) & 0x0f];
- return (x[i & 0x0f] = rol(tm, 1));
- }
- private static void R(UInt32 a, ref UInt32 b, ref UInt32 e, UInt32 f, UInt32 k, UInt32 m)
- {
- e += rol(a, 5) + f + k + m;
- b = rol(b, 30);
- }
- private static void sha1_init()
- {
- h0 = 0x67452301;
- h1 = 0xefcdab89;
- h2 = 0x98badcfe;
- h3 = 0x10325476;
- h4 = 0xc3d2e1f0;
- }
- private static void sha1_transform(byte[] block)
- {
- UInt32 a, b, c, d, e;
- UInt32[] x = new UInt32[16];
- a = h0;
- b = h1;
- c = h2;
- d = h3;
- e = h4;
- for(int i = 0, j = 0;i < 16;i++, j += 4)
- x[i] = BitConverter.ToUInt32(new byte[] { block[j + 3], block[j + 2], block[j + 1], block[j] }, 0);
- R(a, ref b, ref e, F1(b, c, d), K1, x[0]);
- R(e, ref a, ref d, F1(a, b, c), K1, x[1]);
- R(d, ref e, ref c, F1(e, a, b), K1, x[2]);
- R(c, ref d, ref b, F1(d, e, a), K1, x[3]);
- R(b, ref c, ref a, F1(c, d, e), K1, x[4]);
- R(a, ref b, ref e, F1(b, c, d), K1, x[5]);
- R(e, ref a, ref d, F1(a, b, c), K1, x[6]);
- R(d, ref e, ref c, F1(e, a, b), K1, x[7]);
- R(c, ref d, ref b, F1(d, e, a), K1, x[8]);
- R(b, ref c, ref a, F1(c, d, e), K1, x[9]);
- R(a, ref b, ref e, F1(b, c, d), K1, x[10]);
- R(e, ref a, ref d, F1(a, b, c), K1, x[11]);
- R(d, ref e, ref c, F1(e, a, b), K1, x[12]);
- R(c, ref d, ref b, F1(d, e, a), K1, x[13]);
- R(b, ref c, ref a, F1(c, d, e), K1, x[14]);
- R(a, ref b, ref e, F1(b, c, d), K1, x[15]);
- R(e, ref a, ref d, F1(a, b, c), K1, M(x, 16));
- R(d, ref e, ref c, F1(e, a, b), K1, M(x, 17));
- R(c, ref d, ref b, F1(d, e, a), K1, M(x, 18));
- R(b, ref c, ref a, F1(c, d, e), K1, M(x, 19));
- R(a, ref b, ref e, F2(b, c, d), K2, M(x, 20));
- R(e, ref a, ref d, F2(a, b, c), K2, M(x, 21));
- R(d, ref e, ref c, F2(e, a, b), K2, M(x, 22));
- R(c, ref d, ref b, F2(d, e, a), K2, M(x, 23));
- R(b, ref c, ref a, F2(c, d, e), K2, M(x, 24));
- R(a, ref b, ref e, F2(b, c, d), K2, M(x, 25));
- R(e, ref a, ref d, F2(a, b, c), K2, M(x, 26));
- R(d, ref e, ref c, F2(e, a, b), K2, M(x, 27));
- R(c, ref d, ref b, F2(d, e, a), K2, M(x, 28));
- R(b, ref c, ref a, F2(c, d, e), K2, M(x, 29));
- R(a, ref b, ref e, F2(b, c, d), K2, M(x, 30));
- R(e, ref a, ref d, F2(a, b, c), K2, M(x, 31));
- R(d, ref e, ref c, F2(e, a, b), K2, M(x, 32));
- R(c, ref d, ref b, F2(d, e, a), K2, M(x, 33));
- R(b, ref c, ref a, F2(c, d, e), K2, M(x, 34));
- R(a, ref b, ref e, F2(b, c, d), K2, M(x, 35));
- R(e, ref a, ref d, F2(a, b, c), K2, M(x, 36));
- R(d, ref e, ref c, F2(e, a, b), K2, M(x, 37));
- R(c, ref d, ref b, F2(d, e, a), K2, M(x, 38));
- R(b, ref c, ref a, F2(c, d, e), K2, M(x, 39));
- R(a, ref b, ref e, F3(b, c, d), K3, M(x, 40));
- R(e, ref a, ref d, F3(a, b, c), K3, M(x, 41));
- R(d, ref e, ref c, F3(e, a, b), K3, M(x, 42));
- R(c, ref d, ref b, F3(d, e, a), K3, M(x, 43));
- R(b, ref c, ref a, F3(c, d, e), K3, M(x, 44));
- R(a, ref b, ref e, F3(b, c, d), K3, M(x, 45));
- R(e, ref a, ref d, F3(a, b, c), K3, M(x, 46));
- R(d, ref e, ref c, F3(e, a, b), K3, M(x, 47));
- R(c, ref d, ref b, F3(d, e, a), K3, M(x, 48));
- R(b, ref c, ref a, F3(c, d, e), K3, M(x, 49));
- R(a, ref b, ref e, F3(b, c, d), K3, M(x, 50));
- R(e, ref a, ref d, F3(a, b, c), K3, M(x, 51));
- R(d, ref e, ref c, F3(e, a, b), K3, M(x, 52));
- R(c, ref d, ref b, F3(d, e, a), K3, M(x, 53));
- R(b, ref c, ref a, F3(c, d, e), K3, M(x, 54));
- R(a, ref b, ref e, F3(b, c, d), K3, M(x, 55));
- R(e, ref a, ref d, F3(a, b, c), K3, M(x, 56));
- R(d, ref e, ref c, F3(e, a, b), K3, M(x, 57));
- R(c, ref d, ref b, F3(d, e, a), K3, M(x, 58));
- R(b, ref c, ref a, F3(c, d, e), K3, M(x, 59));
- R(a, ref b, ref e, F4(b, c, d), K4, M(x, 60));
- R(e, ref a, ref d, F4(a, b, c), K4, M(x, 61));
- R(d, ref e, ref c, F4(e, a, b), K4, M(x, 62));
- R(c, ref d, ref b, F4(d, e, a), K4, M(x, 63));
- R(b, ref c, ref a, F4(c, d, e), K4, M(x, 64));
- R(a, ref b, ref e, F4(b, c, d), K4, M(x, 65));
- R(e, ref a, ref d, F4(a, b, c), K4, M(x, 66));
- R(d, ref e, ref c, F4(e, a, b), K4, M(x, 67));
- R(c, ref d, ref b, F4(d, e, a), K4, M(x, 68));
- R(b, ref c, ref a, F4(c, d, e), K4, M(x, 69));
- R(a, ref b, ref e, F4(b, c, d), K4, M(x, 70));
- R(e, ref a, ref d, F4(a, b, c), K4, M(x, 71));
- R(d, ref e, ref c, F4(e, a, b), K4, M(x, 72));
- R(c, ref d, ref b, F4(d, e, a), K4, M(x, 73));
- R(b, ref c, ref a, F4(c, d, e), K4, M(x, 74));
- R(a, ref b, ref e, F4(b, c, d), K4, M(x, 75));
- R(e, ref a, ref d, F4(a, b, c), K4, M(x, 76));
- R(d, ref e, ref c, F4(e, a, b), K4, M(x, 77));
- R(c, ref d, ref b, F4(d, e, a), K4, M(x, 78));
- R(b, ref c, ref a, F4(c, d, e), K4, M(x, 79));
- h0 += a;
- h1 += b;
- h2 += c;
- h3 += d;
- h4 += e;
- }
- /// <summary>
- /// 得到stream的SHA1
- /// </summary>
- /// <param name="stream">要处理的流</param>
- /// <param name="index">开始处理的位置</param>
- /// <param name="count">要处理的长度</param>
- /// <returns></returns>
- public static string Compute(Stream stream, long index, long count)
- {
- if(stream == null)
- throw new ArgumentNullException();
- byte[] block = new byte[64];
- UInt64 size = 0;
- int b;
- sha1_init();
- while(index-- > 0 && stream.ReadByte() >= 0)
- ;
- if(index >= 0)
- throw new ArgumentException("", "index");
- while((b = stream.ReadByte()) != -1 && count-- > 0)
- {
- block[size++ % 64] = (byte)b;
- if(size % 64 == 0)
- sha1_transform(block);
- }
- if(count > 0)
- throw new ArgumentException("", "count");
- UInt64 bp = size % 64;//blockPoint
- block[bp++] = 0x80;
- if(bp > 56)
- {
- while(bp < 64)
- block[bp++] = 0;
- sha1_transform(block);
- for(int i = 0;i < 56;i++)
- block[i] = 0;
- }
- else
- while(bp < 56)
- block[bp++] = 0;
- size *= 8;
- block[56] = (byte)(size >> 56);
- block[57] = (byte)((size >> 48) & 0xFF);
- block[58] = (byte)((size >> 40) & 0xFF);
- block[59] = (byte)((size >> 32) & 0xFF);
- block[60] = (byte)((size >> 24) & 0xFF);
- block[61] = (byte)((size >> 16) & 0xFF);
- block[62] = (byte)((size >> 8) & 0xFF);
- block[63] = (byte)(size & 0xFF);
- sha1_transform(block);
- //注意,这里的结果要进行翻转
- return Rev(string.Format("{0}-{1}-{2}-{3}-{4}",
- BitConverter.ToString(BitConverter.GetBytes(h4)),
- BitConverter.ToString(BitConverter.GetBytes(h3)),
- BitConverter.ToString(BitConverter.GetBytes(h2)),
- BitConverter.ToString(BitConverter.GetBytes(h1)),
- BitConverter.ToString(BitConverter.GetBytes(h0))).Replace("-", ""));
- }
- private static string Rev(string str)
- {
- string s = string.Empty;
- for(int i = 0;i < 40;i += 2)
- s = str.Substring(i, 2) + s;
- return s;
- }
- }
- }
检测算法正确性的代码
用这段代码检测,只要出现了 OK!........说明我的算法是正确的。
- using System;
- using System.IO;
- using System.Security.Cryptography;
- using MY_SHA1;
- namespace _SHA1
- {
- class Program
- {
- static void Main(string[] args)
- {
- Random rnd = new Random();
- SHA1 sha = SHA1.Create();
- bool f = true;
- for(int i = 0;i < 10000;i++)
- {
- byte[] buf = new byte[i];
- for(int j = 0;j < i;j++)
- buf[j] = (byte)rnd.Next(200);
- MemoryStream ms = new MemoryStream(buf);
- string s1 = My_SHA1.Compute(ms, 0, i);
- ms.Seek(0, SeekOrigin.Begin);
- string s2 = BitConverter.ToString(sha.ComputeHash(ms)).Replace("-", "");
- if(s1 != s2)
- {
- Console.WriteLine("{0}/n {1}/n {2}", i, s1, s2);
- f = false;
- }
- }
- if(f)
- Console.WriteLine("OK!........");
- }
- }
- }