Artem's blog

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

Archives for Technology

What’s new in SKGL Extension for .NET (v. 2)

The extension API for SKGL used to communicate with the Web API of Serial Key Manager has now been upgraded to support Web API 2.0. Below, I’ve listed some changes:

  • The project was moved to GitHub: You can find it here.
  • Some methods were removed/renamed: From now on, there is only one method for a specific action (eg. Activate). There is, for instance, only one method to perform activation, and that method will return a KeyInformation object rather than just stating whether the key is valid or invalid.
  • Support for error handling: When something is missing, you will receive an error. All errors are well documented here. In debug mode, these errors will be displayed in the output.
  • New hash methods and improved algorithm for data collection: The API uses an improved version of information collection (see all contributors) that is later hashed by a hashing algorithm. There are two algorithms at the movement: one that will calculate an eight digit long hash and a second one that will use SHA1. It’s always possible to pick any other hashing algorithm.

I can imagine that some of the changes may or may not trigger different kinds of emotions, partly because some code has to be modified. However, this upgrade is necessary as it will allow much more functionality to be added in the future. It’s also easier to use and thus make it work on other platforms.

Therefore, I will be available to answer some questions on how to migrate to the new library. I can’t guarantee a fast response time, but I will do my best. To save my time, please look through this page first, before contacting me. BUT first, please consider submitting your question on https://github.com/artemlos/SKGL-Extension-for-dot-NET/issues/new. If you rather prefer CodePlex, please use https://skgl.codeplex.com/discussions/topics/5452/help-support.

Links:

Keeping Track of Code Quality with NDepend

In the recent lecture at the Computer Science programme, we’ve discussed the way projects should be designed. There are three very important criteria: Coupling, Cohesion and Responsibility driven design. We might question the use of encapsulation, avoidance of code duplication and writing very specialized classes. Some might argue that once we’ve solved a particular task in a limited amount of time, it’s possible to move on and solve other tasks. However, based on my experience from Mathos Project mainly, I can conclude that if the code would be written that way, the project would have collapsed. The reason is, in particular in open source projects, is that it’s not as strictly decided which team writes and maintains a particular module. One developer might contribute with a specific functionality, and another with a different functionality in the same module. Then, we might get a different set of people trying to understand what they’ve done to build on top of it. Even the authors of the code might not be able to understand or “dare to modify” their own code. This phenomena can be referred to as legacy code. In conclusion, we don’t want that to happen!

For some weeks ago, I received a copy of NDepend (Developer edition and Build machine edition) from Patrick Smacchia, the Lead Developer of NDepend. This made me very happy and I started to test it on my current projects. In this article, I am going to explore some of the functionality available in NDepend. Please note that I am just describing features that came first in to my sight. NDepend is a very advanced system and contains a lot more functionality than I’ve mentioned here. Many specialized books have referred to the system and it’s also recommended by for instance Jeffrey Richter (I’ve referred to one of his works in this article) and Scott Hanselman. (For a more complete tutorial, please see this Pluralsight course)

First impression

Once I installed NDepend and test-launched it, I was able to generate a comprehensive report without reading any documentation. It’s a friendly GUI that suggests you what you can do at any point during the code analysis.

Even if it might appear as if it’s so much new information that has to be interpreted, there is a Get Started feature built-in to the report (top, right corner). It suggests that we should look out for unwanted dependencies, look for complex methods, etc. Personally, the first thing that fell into my sight is the percentage of comments in the project. Recently, Mathos Project promoted the idea to write xml comments to each new method as it is implemented. Since all analysis are saved regularly, I could have generated a report before the first post about the xml comment idea and compared it to the recent report. The percentage would tell me if we are moving the right direction. This is good not only from a developer point of view, but a also from a project manager stand point.

Visualization of projects

It’s always good to quantify big things into something that can easily be interpreted. NDepend provides you with many kinds of graph by default, but it is also possible to specify your own parameters. Let’s look at the simplest Component Dependency graph below:

The Component Dependency graph

Visual Studio Ultimate allows you to generate similar graphs, but in NDepend more information is encoded into the  graph. For instance, the number of dependencies is proportional to the size of a project in the diagram. If you open this diagram in NDepend, you will be able to get more information by hovering a box. An example is show below

nd1

The Component Dependency graph in Visual Studio

This is quite good if you want to spot strongly coupled classes. The thicker arrow, the more depended is a class on another class. Moreover, if a more complex analysis should be performed, we can look at code metrics. I am going to analyse complexity in terms of lines of code, but this can adjusted.

MetricTreemapSnapshot

Code metrics. Generated with the NDepend plug in in Visual Studio.

Each of these small rectangles represents a method, where the area is proportional to the lines of code that method (we can change this to another property). The rectangles selected in blue are top ten methods that either have too many variables, parameters, or lines of code (read more here). If you spot a method that you want to inspect, simply double click on it and you will be redirected directly into your project where the method is located. This is quite good if we want to spot high or low cohesion. There is a tendency that the simpler a method/class is, the more specialized is the class at a particular task.

Abstractions

In addition to the diagrams I’ve already shown above, one that I really liked (partly because of the simplicity) is the Abstractness vs. Instability graphs. I’ve compared one for Mathos Core Library and Mathos Parser.

Mathos Core Library

Mathos Parser

Note, Instability is a good thing since Stable means “painful to modify” according to the definition. It seems like Mathos Parser is in the safe zone and Mathos Core Library is close to it.

Creating custom rules

The report I’ve generated used the standard rules (you can see some of them here). It is possible to use the C# Linq to make your own rules. You can find more about how to construct your own rules here. It is quite straight forward. Here is one of the standard rules that measures method complexity:

warnif count > 0 from m in JustMyCode.Methods where 
  m.ILCyclomaticComplexity > 40 && 
  m.ILNestingDepth > 5
  orderby m.ILCyclomaticComplexity descending,
          m.ILNestingDepth descending
select new { m, m.ILCyclomaticComplexity, m.ILNestingDepth }

An example of this functionality is shown below:
CQLinq_Overview

Conclusion

Based on my experience with NDepend, I strongly recommend this system to developers working on projects, particularly large-scale projects. Even if you are not using .NET, I believe it’s a good idea to get some basic knowledge of it. Some weeks ago, the .NET team at Microsoft announced that the .NET Core is going to be open source, which in my opinion will make the .NET framework even more influential in environments like Linux, Mac etc. On your .NET journey, I am quite convinced that NDepend will help you to make good design decisions easier and thus make your project not only good at performing tasks, but also a pleasure to read for new developers!

Edits:

  • Published 2014.012.05
  • Added a picture of C# Linq overview.

If statement in CIL

The article, Introduction to IL Assembly Languageis a great resource for those of you who would like to understand IL code (kind of like asm but in .net). IL really gives you a different perspective on computer programming, and you must consider more things in comparison to high level languages like C#.

Currently, I am studying conditional statements. Below, an example of a statement that checks whether the two values in the evaluation stack are equal to each other. 

//An example of an if statement.

.assembly extern mscorlib {}

.assembly Test
{
    .ver 1:0:1:0
}
.module test.exe

.method static void main() cil managed
{
	.maxstack 2
	.entrypoint

	ldc.i4 30
	ldc.i4 40

	beq Equal
		ldstr "No, they are not equal"
		call void [mscorlib]System.Console::WriteLine (string)

	br Exit

	Equal:
		ldstr "Yes, they are equal"
		call void [mscorlib]System.Console::WriteLine (string)

	Exit:
		ret
}

By executing this, the result below would be shown:

ev

The new generation of app protection

In order to emphasize the ability to control an application when online key validation is being used, I have created a poster. Serial Key Manager be found here.

skm_system_all_skgl

Keep everything under control

Creating a programming language with Mathos Parser (2)

In this article, I would like to find out whether it is possible to construct a programming language with Mathos Parser. In general, the question is if a simple expression parser has the necessary things to easily convert it into a language.

The answer is yes, but the language will be very limited if additional features are not added. The reason for this is because what most languages have in common is some sort of  user/machine interaction, while an expression parser only allows you to parse mathematical things and is not really designed to interpret how to write to a file or allocate memory.

For example, imagine you want to create something similar to if statements  and you decide to treat an if as a function. You would use following code:

parser.LocalFunctions.Add("if", x =>
{
    if (x[0] == 1)
    {
        return x[1];
    }
    else
    {
        if (x.Length == 3)
        {
            return x[2];
        }
        else
        {
            return 0;
        }
    }
});

So, if whatever we pass into the first parameter is true, the value in the second parameter will be returned. This is quite cool, but it does not allow us to return a series of statements. Instead, we could design a new kind of if statement that would, depending on the result from this if function, execute the right method. Here is how I solved it:

let a = get()               # ask for user input

if(a>3,1, 0)                # it only returns a number
1-> write It is true        # these execute something depending on result
0-> write It is false

As you can see, the if statement is still there, but there is now a feature that will interpret the result and make something happen. You can also use \n to separate between different statements and also name a collection of statements, as shown below:

# Using statements as small methods
# The first result will not use statement,
# the second one will.

notTrue : title Not true \n write Your number is smaller than five (or equal to) \n pause

write Type a number between 1-10

let b be get()

if(b>5, 1, 0)
1-> title A New title! \n write Your number is greater than five! \n pause
0-> notTrue

Note that both examples use a function get(). It can also be implemented as a function:

parser.LocalFunctions.Add("get", x =>
{
    return System.Convert.ToDecimal(Console.ReadLine());
}
);

You might have noticed the use of statements (see notTrue statement). Their role is to simulate a method. Everything you enter into a statement will not be executed until you call it, so you can insert undefined variables into a statement when you define it and later assign them with a value. I have also added commands like write, title, pause, clear and end. These are extensions to the language and are interpreted in the method below:

static void command(Mathos.Parser.MathParser parser, string input, Dictionary<string, string> statement, ref decimal lastResult)
{
    try
    {
        input = Regex.Replace(input, "#\\{.*?\\}#", ""); // Delete Comments #{Comment}#
        input = Regex.Replace(input, "#.*$", ""); // Delete Comments #Comment

        input = Regex.Replace(input, @"[0-9]+\!", new MatchEvaluator(FactorialString));

        input = Regex.Replace(input, @"^\s+", "");

        if (input != "")
        {
            if (input.StartsWith("write"))
            {
                Console.WriteLine(input.Substring(6));
            }
            else if (input.StartsWith("title"))
            {
                Console.Title = input.Substring(6);
            }
            else if (input.StartsWith ("clear"))
            {
                Console.Clear();
            }
            else
            {
                if (input.Contains("->"))
                {
                    int index = input.IndexOf("->");

                    if (lastResult == System.Convert.ToDecimal(input.Substring(0, index)))
                    {
                        mCommand(parser, input.Substring(index + 2), statement, ref lastResult);
                    }
                }
                else
                {
                    if (input.Contains(":") && input.Contains(":=") == false)
                    {
                        int index = input.IndexOf(":");

                        statement.Add(input.Substring(0, index).Replace(" ", ""), input.Substring(index + 1, input.Length - index - 1));

                    }
                    else if (input.StartsWith("pause"))
                    {
                        Console.ReadKey();

                    }
                    else if (input.StartsWith("end"))
                    {
                        Environment.Exit(0);
                    }

                    else
                    {
                        foreach (var item in statement)
                        {
                            if (input.Contains(item.Key))
                            {
                                input = "";
                                mCommand(parser, item.Value, statement, ref lastResult);
                            }
                        }
                        lastResult = parser.ProgrammaticallyParse(input, identifyComments: false);
                        Console.WriteLine(lastResult);
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("An error occured. Message: " + e.Message);
    }
}

static void mCommand(Mathos.Parser.MathParser parser, string input, Dictionary<string, string> statement, ref decimal lastResult)
{
    input = input.Replace(@"\n", System.Environment.NewLine);

    System.IO.StringReader sr = new System.IO.StringReader(input);

    string _input = sr.ReadLine();

    while (_input != null)
    {
        command(parser, _input, statement, ref lastResult);
        _input = sr.ReadLine();
    }
    sr.Close();
}

Some programmers will certainly argue that the code above is not that optimized and is quite primitive. Well, it serves its purpose and makes Mathos Parser look more like a language.

In the next article I want to implement a while feature into this awesome programming language.

Conclusion: Just because something can parse expressions does not mean it can parse a series of statement. In order to fix this we can either choose to add some features externally, or, go into the parser itself and make it more adjusted to this particular task. This language does not alter Mathos Parser in any way.

Downloads:

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;
        }
        else
        {
            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 2.0.5.3. 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
{
    [TestMethod]
    public void test()
    {
        Debug.WriteLine(getMachineCode());
    }


    [SecuritySafeCritical]
    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);
    }

    [SecuritySafeCritical]
    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:

Evaluate string expressions

Learn more about how to change a lambda expression on runtime: http://mathosproject.com/updates/convert-a-string-expression-into-a-lambda-expression/

Integral approximation

Constructed an integral approximation application: http://mathosproject.com/updates/integral-approximation-tool/

Page 1 of 2:1 2 »