Artem's blog

Mainly .NET (C#, ASP.NET) and my projects


This user hasn't shared any biographical information

The prize for the Best C# Article of April 2014 (2nd level)

This morning I received a letter from Code Project Solutions with the second place prize for my article. In the letter, I found two stickers, which made me very happy! The pictures are found below:


The letter


The stickers










Before I wrote the article on CodeProject, it was originally written in LaTeX, because I wanted to submit it to several conferences. However, after a minute of thought, I quickly realized that if you want to share your ideas more efficiently, you should take the advantage of modern technologies (HTML, etc.) and modern media. I am a fan of LaTeX, but in this case, HTML was my choice because of the simple navigation (and some other things) that it allowed.

It came as a surprise that it received positive feedback (with suggestions for improvement) and the page view was high. My first article on CodeProject about Different Aspects of Website Protection received some views and votes too, but in comparison to Licensing Systems in .NET it was nothing.

It is difficult to say why it received more attention than my previous article, but in any way – positive feedback is very encouraging, and specially when other people take an advantage of it! I will definitely continue my hobby of writing articles and hopefully in some months from now a larger work.

I am very thankful to all people for their support! 🙂

Factorial notation in Mathos Parser (1)

In this article series, I would like to look at how Mathos Parser (a very simple expression parser) can be used to perform things that were not originally intended. Today, I am going to show what has to be done to make Mathos Parser able to interpret factorial notation, such as “4!

Already in the parser, we can solve this in at least two different ways:

  • creating a localFunction fact() that will take one parameter and return the factorial of that number
  • using FactorialPower(falling power) instead, that is 4!4 would be 24 and 4!1=4.

Both methods do not require you to change anything in the input string, but they might not be as close to the mathematical notation as we want it to be. Therefore, as a part of this article, I am going to illustrate the changes in the input string that have to be made, to make it understand 4!.

  1. Include Reg Ex name space as following:
    using System.Text.RegularExpressions;
  2. Add these two methods somewhere in the class:
    static decimal factorial(decimal x)
        if(x==1 || x== 0)
            return 1;
            return x * factorial(x - 1);
    static string FactorialString(Match m)
        return m.Value + "0";
  3. Define the Mathos Parser and add a definition of the factorial operator including the way it should be executed. Note, at this stage, for this to work, the factorial number has to be in the form of 4!0 or 4!1 ((both result in 24).
    Mathos.Parser.MathParser parser = new Mathos.Parser.MathParser();
    parser.OperatorList = new List<string>() {"!" ,"%","^", "/", "*",  "-", "+"}; // removed ":" for division
    parser.OperatorAction.Add("!", (x, y) => factorial(x));
  4. Before the input string can be parsed, perform the following action (assuming you have defined a variable input with a value):
    input = Regex.Replace(input, @"[0-9]+\!", new MatchEvaluator(FactorialString));
  5. Parser the string and store the result:
    decimal result = parser.Parse(input);

This is how we can make Mathos Parser able to understand mathematical notation of factorial. In the next article of this series, we are going to look at how Mathos Parser can be used to construct a new programming language.

A possible change for machine code

In the recent issue, it was reported that machine codes are repeated approximately once per 50 different machines in SKGL The reasons under investigation are:

  • small hash value allows even more collisions.
  • the machine information that is being hashed does not collect all hardware that can be changed.

The first reason is currently in focus, and I have tried to develop a piece of code that now increases the length of the machine code. It would be great if those of you who are able to test this on several machines could do so, and comment(either directly below this thread or here) how frequent the collisions are on different machines! Thank you in advance! 🙂

EDIT 2: This can be done by anyone using Windows:

  1. Download the software below (no installation required): (or download the exe file directly here) NOTE: In Google Chrome, it might tell that the file is dangerous because it is not commonly downloaded. Please right click and press keep.

Machinecode experiment

EDIT: You can also write the machine code you get on your own computer and post it below this thread. (hardware info using dxdiag would be awesome, but the machine code is more important at this point)

public class AnalysisOfMachineCode
    public void test()

    public static int getMachineCode()
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_Processor");
        string collectedInfo = "";
        // here we will put the informa
        foreach (ManagementObject share in searcher.Get())
            // first of all, the processorid
            collectedInfo += share.GetPropertyValue("ProcessorId");

        searcher.Query = new ObjectQuery("select * from Win32_BIOS");
        foreach (ManagementObject share in searcher.Get())
            //then, the serial number of BIOS
            collectedInfo += share.GetPropertyValue("SerialNumber");

        searcher.Query = new ObjectQuery("select * from Win32_BaseBoard");
        foreach (ManagementObject share in searcher.Get())
            //finally, the serial number of motherboard
            collectedInfo += share.GetPropertyValue("SerialNumber");

        // patch luca bernardini
        if (string.IsNullOrEmpty(collectedInfo) | collectedInfo == "00" | collectedInfo.Length <= 3)
            collectedInfo += getHddSerialNumber();

        return getEightByteHash(collectedInfo, 1000000);

    public static string getHddSerialNumber()

        // --- Win32 Disk 
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("\\root\\cimv2", "select * from Win32_DiskPartition WHERE BootPartition=True");

        uint diskIndex = 999;
        foreach (ManagementObject partition in searcher.Get())
            diskIndex = Convert.ToUInt32(partition.GetPropertyValue("Index"));
            break; // TODO: might not be correct. Was : Exit For

        // I haven't found the bootable partition. Fail.
        if (diskIndex == 999)
            return string.Empty;

        // --- Win32 Disk Drive
        searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive where Index = " + diskIndex.ToString());

        string deviceName = "";
        foreach (ManagementObject wmi_HD in searcher.Get())
            deviceName = wmi_HD.GetPropertyValue("Name").ToString();
            break; // TODO: might not be correct. Was : Exit For

        // I haven't found the disk drive. Fail
        if (string.IsNullOrEmpty(deviceName.Trim()))
            return string.Empty;

        // -- Some problems in query parsing with backslash. Using like operator
        if (deviceName.StartsWith("\\\\.\\"))
            deviceName = deviceName.Replace("\\\\.\\", "%");

        // --- Physical Media
        searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia WHERE Tag like '" + deviceName + "'");
        string serial = string.Empty;
        foreach (ManagementObject wmi_HD in searcher.Get())
            serial = wmi_HD.GetPropertyValue("SerialNumber").ToString();
            break; // TODO: might not be correct. Was : Exit For

        return serial;


    public static int getEightByteHash(string s, int MUST_BE_LESS_THAN = 1000000000)
        //This function generates a eight byte hash

        //The length of the result might be changed to any length
        //just set the amount of zeroes in MUST_BE_LESS_THAN
        //to any length you want
        uint hash = 0;

        foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s))
            hash += b;
            hash += (hash << 10);
            hash ^= (hash >> 6);

        hash += (hash << 3);
        hash ^= (hash >> 11);
        hash += (hash << 15);

        int result = (int)(hash % MUST_BE_LESS_THAN);
        int check = MUST_BE_LESS_THAN / result;

        if (check > 1)
            result *= check;

        return result;


Two new videos about Serial Key Manager

This week I was able to record two new videos that describe the process of external validation of a license key using Serial Key Manager. Now, my final aim is to record a third, last video about the way the local time can be synced with a server to prevent user from gaining more days than allowed by a license.

Below are the videos:

Time after finals

My last paper was on Tuesday morning – it was the Chemistry options. The exam period is now over, and in fact, the entire IB Diploma is over also (except if there has to be a retake, which I hope will not happen). I have heard some reflections about the test week; one category of students think it went excellent on some papers, some are unsure, and some think that it could have gone much better. I think that it so difficult to make any predictions at this stage, since languages are 55% of work that is done before the finals, while for instance in the sciences, paper 1 might be a bit tricky to predict. Well, qui vivra verra.

It feels that the time restriction during tests is something that could be changed since it does not allow all knowledge to be tested, that is, the exam turns to some sort of competition. This is understandable, and will most certainly occur in our future lives. Maybe IB wants us teach to take quick decisions, since after all,

Delayed decisions inevitably lose their positive quality (Art of War for Managers)

or as Sun Tzu says:

Hence what is valued in war is a quick victory, not prolonged operations (Sun Tzu)

But on the other hand, if more time is given during say Math exams, you are “either able to solve a problem or you are not” (a teacher at Katte). A Russian mathematician (I do not remember his name unfortunately) said that if mathematics competitions would exist during his youth, he would most likely not be a mathematician. This applies to other subjects too; you can be very good at a subject but the test might say otherwise.

I think everyone taking the IB should be very proud of everything that they know (and not be unhappy about what they do not know), since after all 3 years have elapsed and even if some did not aim for high grades will still have gained a lot of knowledge. At this stage though, I cannot image where I will apply my Chemistry knowledge, nor literature terms like “extern fokalisering” and “intern fokalisering”, but I start to realize that knowing these details is very important for a dialog with different people. You do not need to be an expert in a field in order to start a conversation. So I suppose that when you happen to sit close to chemists or physicists at some point in life, you will be able to understand at least what topic they are talking about – the rest they will explain to you since they are most likely experts in their area and are very passionate about it.

Anyway, the test week was quite an interesting challenge which was fun to undertake. I must confess though that during the second week, my plan received some changes. Before, I had Plan A and Plan B, but during that week, I added another part to it, namely Plan C. At this moment, I do not want to disclose any of them, but I can tell that Plan A is what I want to execute in the first place. This is very secretive, but everyone must have some secrets. As Jaroslav Hašek said: “Skromnost krášlí muže/../,” which can be translated as “Modesty adorns a man /../“.

Otherwise, it feels great and I have already started to develop the foundation for Snippette.NET (a project together with Melody P. and David P.) and I have also re-assumed my work on Serial Key Manager and will certainly continue developing Mathos Project. My goal is to make use of the time during the summer break (or maybe we should say summer holiday) and be as productive as possible.

In conclusion, these two years have been amazing and it has always been a pleasure to be surrounded by very motivated and clever people every day! As a last thing, if anyone would like to have a website (for example about page or a page for an institution),  an application (for scientific calculations or for business models), or simply get started with computer programming, please contact me!

I wish everyone success in future studies and work. May the force be with you!

Finals 2014

From today until the 20th of May, my mental, physical and psychological focus is put on the final exams. This means that I won’t be able to respond to messages, comments, etc at least until the 20th of May. As you can understand, it might take some time after the 20th of May too, since many things are going to be collected (there are several already on the list).

Preparing for the finals

This is the second last day on the Eastern break.


An article about Licensing systems

This is an article about three different licensing systems, using C#.NET environment.

Title: Three different algorithms for constructing licensing systems, their advantages and disadvantages using C# .NET environment.

Abstract: A key validation algorithm is one of the important parts in the protection of a computer application. Even if an already existing API is to be used, it is important to understand its weaknesses in order to compare it with alternative ones. Therefore, in this article, three different categories will be described with clear definitions that will make it possible to distinguish between them and allow an analysis of currently existing APIs. Every category is accompanied with examples and in some cases suggestions for further development. The categories described in this article are Checksum based key validation, Pattern based key validation, and Information based key validation. It is going to be found that the choice of a key validation system depends on the information that is to be stored in the key. It is also concluded that at this point it would be better to use online key validation instead.


Released a new patch for SKGL (now which fixes the MachineCode error:

Release notes:

fixed bug Now, SKGL although it will be find in the solution. thanks to dprotopopov for bug report.

Summary: there was an issue with machine code calculation because of permission settings.

EDIT: fixed it for Virtual Box environment too.

Fix can be downloaded from:

NuGet users should have also received the update in the package manager.

Edit to the last section in Number Games

In my booklet, Algorithms via C#, a way to make the computer guess the numbers more efficiently is presented (see pp. 12-13). Let’s quickly remind ourselves about the problem: we want to make the computer guess a number, between 0 to 100, with minimal amount of questions. It is concluded that we should start with 50, then 25, then 12, etc., that is, divide 100 by 2^k  and depending on if the number is less than what computer guessed, we should either add or subtract this factor.

Everything is correct, but I would like to emphasize that this value can be computed without division.

⌊100/2^1⌋ = 50 = (110010)2
⌊100/2^2⌋ = 25 = (11001)2
⌊100/2^3⌋= 12 = (1100)2
⌊100/2^4⌋= 6 = (110)2
⌊100/2^5⌋= 3 = (11)2
⌊100/2^6⌋= 1 = (1)2

As you can see, in base 2, you simply remove the least significant bit each time. This might save time if you work in radix 2.

Page 3 of 15:« 1 2 3 4 5 6 »Last »