Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Threading;
- using System.IO;
- using System.Collections.Concurrent;
- using System.Runtime.InteropServices;
- using System.Security.Cryptography;
- namespace md5
- {
- static class ArrayExt
- {
- public static T[] SubArray<T>(this T[] data, int index, int length)
- {
- T[] result = new T[length];
- Array.Copy(data, index, result, 0, length);
- return result;
- }
- }
- class FastMD5
- {
- static public void Get2(UInt32[] state, UInt32 key)
- {
- UInt32 a = state[0] = 0x67452301;
- UInt32 b = state[1] = 0xEFCDAB89;
- UInt32 c = state[2] = 0x98BADCFE;
- UInt32 d = state[3] = 0x10325476;
- UInt32 x;
- //Руанд 0
- x = (0xD76AA477 + key); a = ((x << 7) | (x >> (32 - 7))) + b;
- x = ((0x98BADCFE ^ (a & (0x77777777))) + 0xF8FA0C4C); d = ((x << 12) | (x >> (32 - 12))) + a;
- x = ((0xEFCDAB89 ^ (d & (a ^ 0xEFCDAB89))) + 0xBCDB4DD9); c = ((x << 17) | (x >> (32 - 17))) + d;
- x = (0xEFCDAB89 + (a ^ (c & (d ^ a))) + 0xC1BDCEEE); b = ((x << 22) | (x >> (32 - 22))) + c;
- x = (a + (d ^ (b & (c ^ d))) + 0xF57C0FAF); a = ((x << 7) | (x >> (32 - 7))) + b;
- x = (d + (c ^ (a & (b ^ c))) + 0x4787C62A); d = ((x << 12) | (x >> (32 - 12))) + a;
- x = (c + (b ^ (d & (a ^ b))) + 0xA8304613); c = ((x << 17) | (x >> (32 - 17))) + d;
- x = (b + (a ^ (c & (d ^ a))) + 0xFD469501); b = ((x << 22) | (x >> (32 - 22))) + c;
- x = (a + (d ^ (b & (c ^ d))) + 0x698098D8); a = ((x << 7) | (x >> (32 - 7))) + b;
- x = (d + (c ^ (a & (b ^ c))) + 0x8B44F7AF); d = ((x << 12) | (x >> (32 - 12))) + a;
- x = (c + (b ^ (d & (a ^ b))) + 0xFFFF5BB1); c = ((x << 17) | (x >> (32 - 17))) + d;
- x = (b + (a ^ (c & (d ^ a))) + 0x895CD7BE); b = ((x << 22) | (x >> (32 - 22))) + c;
- x = (a + (d ^ (b & (c ^ d))) + 0x6B901122); a = ((x << 7) | (x >> (32 - 7))) + b;
- x = (d + (c ^ (a & (b ^ c))) + 0xFD987193); d = ((x << 12) | (x >> (32 - 12))) + a;
- x = (c + (b ^ (d & (a ^ b))) + 0xA67943AE); c = ((x << 17) | (x >> (32 - 17))) + d;
- x = (b + (a ^ (c & (d ^ a))) + 0x49B40821); b = ((x << 22) | (x >> (32 - 22))) + c;
- //Раунд 1
- x = (a + (c ^ (d & (b ^ c))) + 0xF61E25E2); a = ((x << 5) | (x >> (32 - 5))) + b;
- x = (d + (b ^ (c & (a ^ b))) + 0xC040B340); d = ((x << 9) | (x >> (32 - 9))) + a;
- x = (c + (a ^ (b & (d ^ a))) + 0x265E5A51); c = ((x << 14) | (x >> (32 - 14))) + d;
- x = (b + (d ^ (a & (c ^ d))) + 0xE9B6C7AA + key); b = ((x << 20) | (x >> (32 - 20))) + c;
- x = (a + (c ^ (d & (b ^ c))) + 0xD62F105D); a = ((x << 5) | (x >> (32 - 5))) + b;
- x = (d + (b ^ (c & (a ^ b))) + 0x02441453); d = ((x << 9) | (x >> (32 - 9))) + a;
- x = (c + (a ^ (b & (d ^ a))) + 0xD8A1E681); c = ((x << 14) | (x >> (32 - 14))) + d;
- x = (b + (d ^ (a & (c ^ d))) + 0xE7D3FBC8); b = ((x << 20) | (x >> (32 - 20))) + c;
- x = (a + (c ^ (d & (b ^ c))) + 0x21E1CDE6); a = ((x << 5) | (x >> (32 - 5))) + b;
- x = (d + (b ^ (c & (a ^ b))) + 0xC33707F6); d = ((x << 9) | (x >> (32 - 9))) + a;
- x = (c + (a ^ (b & (d ^ a))) + 0xF4D50D87); c = ((x << 14) | (x >> (32 - 14))) + d;
- x = (b + (d ^ (a & (c ^ d))) + 0x455A14ED); b = ((x << 20) | (x >> (32 - 20))) + c;
- x = (a + (c ^ (d & (b ^ c))) + 0xA9E3E905); a = ((x << 5) | (x >> (32 - 5))) + b;
- x = (d + (b ^ (c & (a ^ b))) + 0xFCEFA3F8); d = ((x << 9) | (x >> (32 - 9))) + a;
- x = (c + (a ^ (b & (d ^ a))) + 0x676F02D9); c = ((x << 14) | (x >> (32 - 14))) + d;
- x = (b + (d ^ (a & (c ^ d))) + 0x8D2A4C8A); b = ((x << 20) | (x >> (32 - 20))) + c;
- //Раунд 2
- a += ((b ^ c ^ d) + 0xFFFA3942); a = ((a << 4) | (a >> (32 - 4))) + b;
- d += ((a ^ b ^ c) + 0x8771F681); d = ((d << 11) | (d >> (32 - 11))) + a;
- c += ((d ^ a ^ b) + 0x6D9D6122); c = ((c << 16) | (c >> (32 - 16))) + d;
- b += ((c ^ d ^ a) + 0xFDE5382C); b = ((b << 23) | (b >> (32 - 23))) + c;
- a += ((b ^ c ^ d) + 0xA4BEEAC4); a = ((a << 4) | (a >> (32 - 4))) + b;
- d += ((a ^ b ^ c) + 0x4BDECFA9); d = ((d << 11) | (d >> (32 - 11))) + a;
- c += ((d ^ a ^ b) + 0xF6BB4B60); c = ((c << 16) | (c >> (32 - 16))) + d;
- b += ((c ^ d ^ a) + 0xBEBFBC70); b = ((b << 23) | (b >> (32 - 23))) + c;
- a += ((b ^ c ^ d) + 0x289B7EC6); a = ((a << 4) | (a >> (32 - 4))) + b;
- d += ((a ^ b ^ c) + 0xEAA127FA + key); d = ((d << 11) | (d >> (32 - 11))) + a;
- c += ((d ^ a ^ b) + 0xD4EF3085); c = ((c << 16) | (c >> (32 - 16))) + d;
- b += ((c ^ d ^ a) + 0x04881D05); b = ((b << 23) | (b >> (32 - 23))) + c;
- a += ((b ^ c ^ d) + 0xD9D4D039); a = ((a << 4) | (a >> (32 - 4))) + b;
- d += ((a ^ b ^ c) + 0xE6DB99E5); d = ((d << 11) | (d >> (32 - 11))) + a;
- c += ((d ^ a ^ b) + 0x1FA27CF8); c = ((c << 16) | (c >> (32 - 16))) + d;
- b += ((c ^ d ^ a) + 0xC4AC5665); b = ((b << 23) | (b >> (32 - 23))) + c;
- //Раунд 3
- x = (a + (c ^ (b | ~d)) + 0xF4292244 + key); a = ((x << 6) | (x >> (32 - 6))) + b;
- x = (d + (b ^ (a | ~c)) + 0x432AFF97); d = ((x << 10) | (x >> (32 - 10))) + a;
- x = (c + (a ^ (d | ~b)) + 0xAB9423C7); c = ((x << 15) | (x >> (32 - 15))) + d;
- x = (b + (d ^ (c | ~a)) + 0xFC93A039); b = ((x << 21) | (x >> (32 - 21))) + c;
- x = (a + (c ^ (b | ~d)) + 0x655B59C3); a = ((x << 6) | (x >> (32 - 6))) + b;
- x = (d + (b ^ (a | ~c)) + 0x8F0CCC92); d = ((x << 10) | (x >> (32 - 10))) + a;
- x = (c + (a ^ (d | ~b)) + 0xFFEFF47D); c = ((x << 15) | (x >> (32 - 15))) + d;
- x = (b + (d ^ (c | ~a)) + 0x85845E51); b = ((x << 21) | (x >> (32 - 21))) + c;
- x = (a + (c ^ (b | ~d)) + 0x6FA87E4F); a = ((x << 6) | (x >> (32 - 6))) + b;
- x = (d + (b ^ (a | ~c)) + 0xFE2CE6E0); d = ((x << 10) | (x >> (32 - 10))) + a;
- x = (c + (a ^ (d | ~b)) + 0xA3014314); c = ((x << 15) | (x >> (32 - 15))) + d;
- x = (b + (d ^ (c | ~a)) + 0x4E0811A1); b = ((x << 21) | (x >> (32 - 21))) + c;
- x = (a + (c ^ (b | ~d)) + 0xF7537E82); a = ((x << 6) | (x >> (32 - 6))) + b;
- x = (d + (b ^ (a | ~c)) + 0xBD3AF235); d = ((x << 10) | (x >> (32 - 10))) + a;
- x = (c + (a ^ (d | ~b)) + 0x2AD7D2BB); c = ((x << 15) | (x >> (32 - 15))) + d;
- x = (b + (d ^ (c | ~a)) + 0xEB86D391); b = ((x << 21) | (x >> (32 - 21))) + c;
- state[0] = state[0] + a;
- state[1] = state[1] + b;
- state[2] = state[2] + c;
- state[3] = state[3] + d;
- //Console.WriteLine("A=" + a.ToString("X8")+" B="+b.ToString("X8")
- // + " C=" + c.ToString("X8") + " D=" + d.ToString("X8") );
- }
- }
- class Program
- {
- static MFile[] SFiles=new MFile[256];
- static MD5 md5Hash = new MD5CryptoServiceProvider();
- static void Main(string[] args)
- {
- Stage1();
- Stage2();
- // byte[] hash = new byte[16] {0x10,0x00,0x6A,0xAE,0x11,0x22,0x33,0x44,
- // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
- // Search(hash);
- }
- static UInt32 Search(byte[] hash)
- {
- const int bufSize=1024*128;
- // Console.WriteLine(offs.ToString("x9"));
- using (var file = File.OpenRead(@"D:\md5test\_result.bin"))
- {
- byte[] buf = new byte[bufSize];
- for(int k=0;k<=0xFF;k++)
- {
- hash[0] = (byte)k;
- long offs = (((long)hash[0] << 24 | (long)hash[1] << 16 | (long)hash[2] << 8 | hash[3]) << 2) - bufSize/2;
- if (offs < 0) offs = 0;
- if (offs >= 0x400000000 - bufSize) offs = 0x400000000 - bufSize;
- file.Position = offs;
- file.Read(buf, 0, bufSize);
- byte[] c1 = md5Hash.ComputeHash(buf.SubArray(bufSize-4, 4));
- Console.Write("\n" + k.ToString("X2") + " 45 6A : "+c1[2].ToString("X2")+" ");
- for (int i = 0; i < 16; i++) Console.Write(c1[i].ToString("X2"));
- }
- }
- return 0;
- }
- public struct KeyInfo
- {
- public Int32 offs;
- public byte cnt;
- public byte wcnt;
- }
- static void Stage2()
- {
- const int Threads = 4; // Количество потоков сортировки
- long length = new System.IO.FileInfo(@"D:\md5test\00.s1").Length;
- TypeCast buf = new TypeCast();
- TypeCast buf1 = new TypeCast();
- TypeCast tmp;
- buf.Byte = new byte[length + 2048 * 1024];
- buf1.Byte = new byte[length + 2048 * 1024];
- KeyInfo[] KI = new KeyInfo[0x1000000];
- TypeCast oBuf = new TypeCast();
- UInt32[] keys = new UInt32[(length + 2048 * 1024) / 2];
- oBuf.Byte = new byte[(length + 2048 * 1024) / 2];
- var outFile = File.Create(@"D:\md5test\_result.bin");
- Task reader = null, writer = null;
- object[] lock_obj = new object[256]; // Объекты для блокировки сортирующих потоков
- for (int i = 0; i < 256; i++) lock_obj[i] = new object();
- using (var file = File.OpenRead(@"D:\md5test\00.s1"))
- { file.Read(buf.Byte, 0, (int)length); }
- for (int f = 0; f <= 255; f++)
- {
- string path = @"D:\md5test\" + f.ToString("x2") + ".s1";
- Console.WriteLine(path);
- length = new System.IO.FileInfo(path).Length;
- if (f != 0)
- {
- //Console.WriteLine("Reader wait"); Console.Out.Flush();
- reader?.Wait();
- tmp = buf; buf = buf1; buf1 = tmp;
- //Console.WriteLine("Readed"); Console.Out.Flush();
- }
- if (f != 0xFF)
- {
- path = @"D:\md5test\" + (f+1).ToString("x2") + ".s1";
- var file1 = File.OpenRead(path);
- reader = file1.ReadAsync(buf1.Byte, 0, (int)new System.IO.FileInfo(path).Length);
- }
- int max = (int)length / 8;
- //Console.WriteLine("Calc counts"); Console.Out.Flush();
- for (int i = 0; i < max; i++)
- {
- uint x=buf.UInt32[i * 2 + 1] = ReverseBytes(buf.UInt32[i * 2 + 1]);
- KI[x>>8].cnt++;
- }
- int sum = 0;
- //Console.WriteLine("Offsets"); Console.Out.Flush();
- for (int i = 0; i < 0x1000000; i++)
- {
- KI[i].offs = sum;
- sum += KI[i].cnt;
- }
- //Console.WriteLine("Wait writer"); Console.Out.Flush();
- writer?.Wait();
- //Console.WriteLine("Sort"); Console.Out.Flush();
- Task[] tasks = new Task[Threads];
- int start_val = 0;
- for (int t = 0; t < Threads; t++)
- tasks[t] = Task.Run(() =>
- {
- int start;
- lock(tasks)
- {
- start = start_val++;
- // Console.WriteLine("Thread " + start.ToString() + " started");
- }
- for (int i = start; i < max; i+=Threads)
- {
- UInt32 ok = buf.UInt32[i * 2 + 1];
- UInt32 k = ok >> 8;
- UInt32 v = buf.UInt32[i * 2];
- int Base = KI[k].offs;
- if (KI[k].cnt == 1) // Может быть только 1 элемент, коллизии потоков невозможны
- {
- oBuf.UInt32[Base] = v; keys[Base] = ok;
- }
- else // Может быть более одного элемента, понадобится сортировка, возможны коллизии
- lock(lock_obj[k & 0xFF])
- {
- int maxj = KI[k].wcnt;
- if (maxj == 0)
- {
- oBuf.UInt32[Base] = v; keys[Base] = ok;
- }
- else
- {
- int j = 0;
- while (
- j < maxj &&
- (keys[Base + j] < ok ||
- (keys[Base + j] == ok && CompareMD5(oBuf.UInt32[Base + j], v) < 0)
- )
- ) j++;
- while (true)
- {
- UInt32 o_ok = keys[Base + j]; UInt32 o_v = oBuf.UInt32[Base + j];
- oBuf.UInt32[Base + j] = v; keys[Base + j] = ok;
- if (j >= maxj) break;
- v = o_v; ok = o_ok;
- j++;
- }
- }
- KI[k].wcnt++;
- }
- }
- });
- Task.WaitAll(tasks);
- //Console.WriteLine("End sort"); Console.Out.Flush();
- writer =outFile.WriteAsync(oBuf.Byte, 0, (int)length/2);
- Array.Clear(KI, 0, KI.Length);
- }
- outFile.Close();
- }
- public static UInt32 ReverseBytes(UInt32 value)
- {
- return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |
- (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;
- }
- static int CompareMD5(UInt32 v1, UInt32 v2)
- {
- TypeCast c1 = new TypeCast();
- TypeCast c2 = new TypeCast();
- c1.Byte = new byte[16];
- c2.Byte = new byte[16];
- FastMD5.Get2(c1.UInt32, v1);
- FastMD5.Get2(c2.UInt32, v2);
- for (int i=0;i<16;i++)
- {
- if (c1.Byte[i] == c2.Byte[i]) continue;
- return (c1.Byte[i] < c2.Byte[i] ? -1 : 1);
- }
- if (v1 != v2) Console.Write("MD5 OF " + v1.ToString() + " and " + v2.ToString() + " IS EQUAL !!!");
- return 0;
- }
- static void Stage1()
- {
- CreateSFiles();
- Console.WriteLine("Stage1 started");
- const int Threads= 5;
- Task[] tasks = new Task[Threads];
- UInt32 start_val = 0;
- for (int i = 0; i < Threads; i++)
- tasks[i] = Task.Factory.StartNew(() =>
- {
- TypeCast hash = new TypeCast();
- hash.Byte = new byte[16];
- UInt32 val,start;
- lock (tasks)
- {
- start = val = start_val++;
- Console.WriteLine("Thread " + val + " started");
- }
- do
- {
- FastMD5.Get2(hash.UInt32, val);
- lock (SFiles[hash.Byte[0]])
- {
- SFiles[hash.Byte[0]].Add(val, (hash.UInt32[0] >> 8) | (hash.UInt32[1] << 24));
- }
- if ((val & 0xFFFFFF) == 0)
- {
- Console.WriteLine(val.ToString("x8"));
- Console.Out.Flush();
- }
- val += Threads;
- } while (val >= Threads /*&& val < 100000000*/);
- Console.WriteLine("Thread "+start.ToString()+" end at "+val.ToString());
- });
- Task.WaitAll(tasks);
- for (int i = 0; i <= 255; i++)
- {
- SFiles[i].Dispose();
- SFiles[i] = null;
- }
- MFile.freeBuffers();
- }
- static void CreateSFiles()
- {
- for(int i=0;i<=255;i++)
- {
- Console.WriteLine("Open " + i.ToString());
- SFiles[i] = new MFile(i);
- }
- }
- }
- [StructLayout(LayoutKind.Explicit, Pack = 2)]
- public class TypeCast
- {
- [FieldOffset(0)]
- public int numberOfBytes;
- [FieldOffset(4)]
- public byte[] Byte;
- [FieldOffset(4)]
- public UInt32[] UInt32;
- }
- public class MFile : IDisposable
- {
- private const int maxBufSize = 262144*2;
- private FileStream file;
- private int num;
- private TypeCast buf;
- private int cur; // Текущая позиция в буфере
- private static ConcurrentBag<TypeCast> freePoll = new ConcurrentBag<TypeCast>();
- private static Task saveTask=null;
- public MFile(int Num)
- {
- num = Num;
- file=File.Create(@"D:\md5test\" + num.ToString("x2") + ".s1");
- cur = 0;
- CreateBuf();
- }
- private void CreateBuf()
- {
- buf = new TypeCast();
- buf.Byte = new byte[maxBufSize*4];
- }
- public void Add(UInt32 val, UInt32 hash)
- {
- buf.UInt32[cur++] = val; buf.UInt32[cur++] = hash;
- if (cur >= maxBufSize-128*256-(hash>>22)) saveTask=saveBuf();
- return;
- }
- public async Task saveBuf(int len=0)
- {
- saveTask?.Wait();
- if (len == 0) len = cur;
- TypeCast oldBuf;
- oldBuf = buf;
- cur = 0;
- if (!freePoll.TryTake(out buf)) CreateBuf();
- await file.WriteAsync(oldBuf.Byte, 0, len * 4);
- freePoll.Add(oldBuf);
- saveTask = null;
- }
- public void Dispose()
- {
- if (cur != 0) saveTask=saveBuf();
- saveTask?.Wait();
- file.Close();
- }
- public static void freeBuffers()
- {
- TypeCast buf;
- while (freePoll.TryTake(out buf)) ;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement