How to save results if a program closes?

Meknowsnothing

New member
Joined
Nov 29, 2018
Messages
2
Location
Finland
Programming Experience
Beginner
I'm learning C# programming on Linux Mint. I saw an exercise where one ask to find a string that its md5-hash starts like 314159265358. I was able to do the program that runs from command line and stops computing if one presses esc. But how can I modify the code such that it stops computing and saves results to the file whenever program closes, like one types command pkill from command line? I tried to ask the question in https://artofproblemsolving.com/com...sults_in_clinux_mint_when_one_stops_computing but got no answer. My code is at the moment the following:
C#:
using System;
using System.IO;
using System.Text;
//using StringBuilder;

// This is an exercise from [URL]https://www.ohjelmointiputka.net/postit/tehtava.php?tunnus=ssana2[/URL] .
// It tries to find an md5-hash that begins with hexadecimals 314159265...
namespace RandomCS
{
    public class Program
    {
        public static void Main()
        {
            string md5 = "";
            string last = "a";
            string c = "";
            string file = "md5piresults.txt";
            string path = "/home/jaakko/Desktop/Programming/";
            int limit = 1;
            int cp = 0;
            string bestsa;
            string charstring;
            string[] lines = System.IO.File.ReadAllLines(@path+file);
            Console.WriteLine(lines[0]+"\n" +lines[1]);
            const string pi = "314159265358";
            do {
                last = lines[0].Substring(6,lines[0].Length-6);
                Console.WriteLine("We got: "+last);

                bestsa = lines[1].Substring(6,lines[1].Length-6);
                charstring = last;
                cp = CommonPrefix(CreateMD5(bestsa),pi).Length;
                Console.WriteLine("The best we have found = "+bestsa+", md5="+CreateMD5(bestsa)+ ",n="+cp);
                limit = cp+1;
                while (!Console.KeyAvailable) {
                    md5 = CreateMD5(charstring);
                    c = CommonPrefix(md5,pi);
                    if (c.Length >= limit) {
                        Console.WriteLine(charstring+" " +md5+ " " +c.Length);
                        lines[0] = "last: "+charstring;
                        lines[1] = "best: "+charstring;
                        System.IO.File.WriteAllLines(@path +file,lines);
                        Console.WriteLine("We saved to the file " +file + " lines " + lines[0] + " and "+lines[1]);
                        limit = c.Length + 1;
                    }
                    charstring = Increase(charstring);

                    if (charstring == endstring(charstring.Length)) {
                        md5 = CreateMD5(charstring);
                        c = CommonPrefix(md5,pi);
                        if (c.Length >= limit) {
                            Console.WriteLine(charstring+" " +md5+ " "+c.Length);
                            lines[0] = "last: "+charstring;
                            lines[1] = "best: "+charstring;
                            System.IO.File.WriteAllLines(@path +file,lines);
                            limit = c.Length + 1;
                        }
                        charstring = startstring(charstring.Length+1);
                    }
                }
            }
            while (Console.ReadKey(true).Key != ConsoleKey.Escape);
            string best = "";
            lines[0] = "last: "+charstring;
            md5 = CreateMD5(charstring);
            c = CommonPrefix(md5,pi);
            if (c.Length >= limit) {
                    best = charstring;
                    lines[1] = "best: "+best;
            }
            System.IO.File.WriteAllLines(@path +file,lines);
            Console.WriteLine("We exit at the point "+charstring);
            Console.WriteLine(charstring);
            Console.WriteLine(limit);
        }

        // This is from [URL]https://stackoverflow.com/questions/33709165/get-common-prefix-of-two-string[/URL] .
        public static string CommonPrefix(string a, string b)
        {
            if (a == null)
                    throw new ArgumentNullException(nameof(a));

            if (b == null)
                    throw new ArgumentNullException(nameof(b));
  
            var min = Math.Min(a.Length, b.Length);
            var sb = new StringBuilder(min);
            for (int i = 0; i < min && a[i] == b[i]; i++)
                sb.Append(a[i]);

            return sb.ToString();
        }

    
        private static string startstring(int n) {
            string start = "";
            for (int i=0; i<n; ++i) {
                    start += "a";
            }
            return start;
        }


        private static string endstring(int n) {
            string end = "";
            for (int i=0; i<n; ++i) {
                    end += "z";
            }
            return end;
        }


        // This is from [URL]https://stackoverflow.com/questions/11454004/calculate-a-md5-hash-from-a-string[/URL]
        public static string CreateMD5(string input)
        {
            // Use input string to calculate MD5 hash
            using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
            {
                byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
                byte[] hashBytes = md5.ComputeHash(inputBytes);
 
                // Convert the byte array to hexadecimal string
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < hashBytes.Length; i++)
                {
                    sb.Append(hashBytes[i].ToString("X2"));
                }
                return sb.ToString();
            }
        }

        // The idea is from [URL]https://artofproblemsolving.com/community/c163h1699980_how_to_find_the_next_string_in_c[/URL]
        private static string Increase(string thing)
        {
            char[] charArray = thing.ToCharArray();
            bool differentcharacter = false;
            for (int i=0; i<charArray.Length; ++i) {
                    if (charArray[i]!= 'z') {
                            differentcharacter = true;
                    }
            }
            if (differentcharacter == false) {
                return thing;
            }
            bool carry = false;
            for (int i = charArray.Length - 1; i >= 0; i--)
            {
                char c = charArray[i];
                if (carry)
                {
                        if (c != 'z' && c != 'Z')
                        {
                                charArray[i] = ++c;
                                break;
                        }

                        charArray[i] = (char) (c - 25);
                } else
                {
                        if (c != 'z' && c != 'Z')
                        {
                                charArray[i] = (char) (c + 1);
                                break;
                        }

                        charArray[i] = (char) (c - 25);
                        carry = true;
                }
            }
            return new String(charArray);
         }
    }
}
 
If your application receives no notification, which I would imagine is the case with that command, then there's nothing you can do. You have to know that your app is closing to be able to save on closing but if the process is killed without notifying your app then it won't know.
 
Oh well. I read from the Internet that one can trap SIGINT and SIGTERM and somehow force program to save results before closing. I'm not sure if this is true. If not, then I think it the easiest if I put my computer to save results for regular intervals such that I won't lose too much computed results.

So is it possible for example to make a bash script that forces C#-program to save current results and then closes the program?
 
Last edited:
Back
Top Bottom