#BrkTheCode from IFS is superb thing. Go here http://www.brkthecode.com/ and get to know about this. Simply they have given a logic and we need to reverse engineer the logic to find the answer. But… I am a well known lazy person and my brain was almost running 99% for last couple of days coz I was stuck in this http://social.msdn.microsoft.com/Forums/en-US/d9634991-0446-4c20-b133-4961355fe0a7/saving-xml-file-after-delete-particular-node-in-windows-phone-81-rt?forum=wpdevelop somehow shorted this out today (nope, its yesterday and I am writing this post on 12:59am IST July 22, 2014) evening. And before my momma call me for the Ifthar (Don’t know about Ifthar? click here) and before I put my machine to Hibernate, I saw about this IFS’s #BrkTheCode. I continue with shutdown /h /f thats a pretty nice command I love in Windows.

After Ifthar and Maghrib prayers (Don’t know about Maghrib prayers? click here) I came and switched on the machine, but I forgot to bring some white sheets and pen to analyze the logic used in the #BrkTheCode website. So as a lazy person, I opted to go with the traditional cipher breaking way, the brute-force attack.

In the puzzle’s website they claim cyphertext 334160560256 is equal to ‘abacus’, so what I though was,

  1. Build words with strings starting from ‘a’,’b’,’c’,….’aa’,’ab’… and go to infinity.
  2. Get the Encrypt() value for each word that I am building.
  3. Compare the Encrypt() value with 1630866511392489104.
  4. If it suits, break the function (to avoid unnecessary running of the program) and print the output to the console.
  5. Else, goto step 1.

So I made a small program like below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IFS_Application
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var val in generate())
            {
                if (Encrypt(val) == 334160560256)
                {
                    Console.WriteLine(val);
                    break;
                }
            }
            Console.ReadLine();
        }

        static Int64 Encrypt(string p)
        {
            Int64 c = 31;
            for (int i = 0; i < p.Length; i++)
                c = c * 47 + (byte)p[i] % 97;
            return c;
        }


        //method to build chars.
        static string toBase26(long i)
        {
            if (i == 0) return ""; i--;
            return toBase26(i / 26) + (char)('a' + i % 26);
        }


        //method to build yield words from chars
        static IEnumerable<string> generate()
        {
            long n = 0;
            while (true) yield return toBase26(++n);
        }
    }
}

So when I tested it with (now the code is in test mode) it shows ‘abacus’ as output, after 10 seconds. But when I run the program with the line if (Encrypt(val) == 1630866511392489104) in my PC, it took about 2 hours but yet to show me the result. So I have created a remote Windows 8, Visual Studio 2013 VM in Azure, run the program and closed the VM client. Its still running in somewhere (I think the server location I have chosen is North America or something). I have to wait untill tomorrow or two or three days to get the result.

But just now, I took some papers and pen and got the logic, make it reverse engineered in C# and submitted to the challenge website with the code and my CV. Lets see if IFS selects me or not.

(Update 1 [9:57 pm IST July 22, 2014])

Its been 24 hours nearly since I setup the VM on Azure, and run the program but its yet to show me the result. It shows the word “abacus” within 10 seconds but the current word is a 10 letter word, so It will take tim for sure lets see.

Witness below

Untitled1

(Update 2 [12:52 am IST July 23, 2014])

Its the time to stop the program in execution and shutdown the VM

Yep, its quite sad but all because of the below picture, I wanna going to stop the program in execution in the VM and shut the VM down.

time to be taken

Simply it will take about (roughly) 3+ years to show the solution. Here is the efforts I have done to calculate the years.

I am running all the codes on a PC with below specs and a VM with almost same specs.

my pc

With the help of StopWatch class in C# I have calculated the time to reach “z”, “zz”, “zzz”, “zzzz” and “zzzzzz”. I made this program to do it.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IFS_Application
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();
            int x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("z"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("zz"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("zzz"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("zzzz"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("zzzzz"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("zzzzzz"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            x = 0;
            foreach (var val in generate())
            {
                x++;
                if (Encrypt(val) == Encrypt("zzzzzzz"))
                {
                    Console.WriteLine(string.Format("string : {0} and went through {1} simple foreach loops", val, x));
                    Console.WriteLine(sw.ElapsedMilliseconds);
                    sw.Restart();
                    break;
                }
            }

            //x = 0;
            //Parallel.ForEach(generate(), val =>
            //{
            //    x++;
            //    if (Encrypt(val) == 334160560256)
            //    {
            //        Console.WriteLine(string.Format("Answer : {0} and went through {1} parallel foreach loops", val, x));
            //        Console.WriteLine(sw.ElapsedMilliseconds);
            //        sw.Restart();
            //    }
            //});

            x = 0;
            for (; x < 1000000; x++)
            {
                x++;
            }
            Console.WriteLine("just incremental for loop went through " + x + " loops");
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
        }

        static Int64 Encrypt(string p)
        {
            Int64 c = 31;
            for (int i = 0; i < p.Length; i++)
                c = c * 47 + (byte)p[i] % 97;
            return c;
        }


        //method to build chars.
        static string toBase26(long i)
        {
            if (i == 0) return ""; i--;
            return toBase26(i / 26) + (char)('a' + i % 26);
        }


        //method to build yield words from chars
        static IEnumerable<string> generate()
        {
            long n = 0;
            while (true) yield return toBase26(++n);
        }
    }
}

Never mind about the commented Parallel.ForEach() thing. and the output was

for eaches

That means, this equation

eqn

here x is equal to the number of chars we are going to find. So I am randomly taking number 10, so I am considering the total number of chars in the answer of the puzzle is 10 (this is just consideration right..!! you might consider 8.. or 9 or even 15..!) And produce a graph for the time I have calculated and the loops per set of chars. It was simply like

no. of loops time taken (in milli seconds)
26 0
702 1
18278 16
12356630 12512
321272406 368821

Now I plotted this data into a graph in Excel, Scatter graph actually so I can easily find the equation of the graph from Excel.

graph_

Yes Microsoft Excel is a handy tool in this matter. And it show the equation is

y = 0.0011x – 410.77

with R2 = 1. R2, A number from 0 to 1 that reveals how closely the estimated values for the trendline correspond to your actual data. A trendline is most reliable when its R-squared value is at or near 1. Also known as the coefficient of determination.

So I have calculated the time that will be taken approximately for the 10 char word (all “z”s in the 10 char) and it was around 161495157016.69 (0.0011 * 146813779479510 – 410.77) and when I converted that 161495157016.69 milliseconds to years, Google says, it is…

time to be taken

5+ years.. so just image the time to be taken for a 15 char string.. OMG!!!..

btw/ I have just shutdown the VM while updating this post. 🙂

Advertisements