コード例 #1
0
ファイル: Day05.cs プロジェクト: burnedram/aoc2016
        private static string Part2(long worksize, int nZeros, int passwordLength)
        {
            Dictionary <int, Tuple <long, string> > hashes = new Dictionary <int, Tuple <long, string> >();
            int    hashesFound  = 0;
            long   largestIndex = 0;
            string zeros        = new string('0', nZeros);
            bool   done         = false;

            Thread hacking = new Thread(() => HackingPart2(ref done, passwordLength, hashes));

            hacking.Start();

            Parallel.ForEach(MD5Ext.YieldWhile(() => hashesFound < passwordLength, i => Tuple.Create(i * worksize, (i + 1) * worksize)), bound =>
            {
                MD5 md5         = MD5.Create();
                long lowerbound = bound.Item1, upperbound = bound.Item2;
                for (long index = lowerbound; index < upperbound && (hashesFound < passwordLength || index < Interlocked.Read(ref largestIndex)); index++)
                {
                    string hash = md5.ComputeHash(Encoding.ASCII.GetBytes(DoorID + index)).MD5String();
                    if (hash.StartsWith(zeros))
                    {
                        int key = Convert.ToInt32(hash.Substring(5, 1), 16);
                        if (key < passwordLength)
                        {
                            lock (hashes)
                            {
                                bool contains = hashes.ContainsKey(key);
                                if (!contains || hashes[key].Item1 > index - 1)
                                {
                                    hashes[key] = Tuple.Create(index - 1, hash);
                                    Monitor.Pulse(hashes);
                                    if (index - 1 > Interlocked.Read(ref largestIndex))
                                    {
                                        Interlocked.Exchange(ref largestIndex, index - 1);
                                    }
                                    if (!contains)
                                    {
                                        Interlocked.Increment(ref hashesFound);
                                    }
                                }
                            }
                        }
                    }
                }
            });
            lock (hashes)
            {
                done = true;
                Monitor.Pulse(hashes);
            }
            hacking.Join();
            return(new string(hashes.Take(passwordLength).OrderBy(hash => hash.Key).Select(hash => hash.Value.Item2[6]).ToArray()));
        }
コード例 #2
0
ファイル: Day05.cs プロジェクト: burnedram/aoc2016
        // Calculate part 1 in parallel
        private static string Part1(long worksize, int nZeros, int passwordLength)
        {
            SortedList <long, string> hashes = new SortedList <long, string>();
            int    hashesFound  = 0;
            long   largestIndex = 0;
            string zeros        = new string('0', nZeros);
            bool   done         = false;

            Thread hacking = new Thread(() => HackingPart1(ref done, passwordLength, hashes));

            hacking.Start();

            Parallel.ForEach(MD5Ext.YieldWhile(() => hashesFound < passwordLength, i => Tuple.Create(i * worksize, (i + 1) * worksize)), bound =>
            {
                MD5 md5         = MD5.Create();
                long lowerbound = bound.Item1, upperbound = bound.Item2;
                for (long index = lowerbound; index < upperbound && (hashesFound < passwordLength || index < Interlocked.Read(ref largestIndex)); index++)
                {
                    string hash = md5.ComputeHash(Encoding.ASCII.GetBytes(DoorID + index)).MD5String();
                    if (hash.StartsWith(zeros))
                    {
                        lock (hashes)
                        {
                            hashes.Add(index - 1, hash);
                            Monitor.Pulse(hashes);
                            if (index - 1 > largestIndex)
                            {
                                largestIndex = index - 1;
                            }
                            Interlocked.Increment(ref hashesFound);
                        }
                    }
                }
            });
            lock (hashes)
            {
                done = true;
                Monitor.Pulse(hashes);
            }
            hacking.Join();
            return(new string(hashes.Take(passwordLength).Select(hash => hash.Value[5]).ToArray()));
        }