Introduction
Creating the serial number for a developed application is the common concern of all developers. One of the most popular ways for creating the unique serial number for an application is creating a serial number based on hardware resources code. As you know all of the hardware resources have their own unique serial number (Such as NIC, HDD and …)
In this article, I will try to create a 3-part serial number based on HDD hardware code. The application includes 3 parts, 1. Getting the request code 2. Generating the serial number based on HDD hardware code and 3. Confirming the serial number and request code with HDD hardware code.
Using the code
As I described, the code includes the 3 part;
1. Generating the Request Code.
Request Code has been created based on HDD hardware code. There is a very simple method which returns the HDD hardware code. This method uses the ManagementObjectSearcher class the included in System.Management namespace.
private string GetHDDSerialNumber()
{
string outs = "";
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
string a = queryObj["PNPDeviceID"].ToString();
if (a.Substring(0, 3) != "USB")
outs = (queryObj["PNPDeviceID"]).ToString();
}
string s = "";
foreach (char t in outs)
{
int i;
if (int.TryParse(t.ToString(), out i))
s += t.ToString();
}
return s;
}
ManagementObjectSearcher is one of the more commonly used entry points to retrieving management information. For example, it can be used to enumerate all disk drives, network adapters, processes and many more management objects on a system, or to query for all network connections that are up, services that are paused, and so on.
So, When the user clicks on the GetRequestCode button, the button’s event handler get the HDD code from GetHDDSerialNumber method and convert it to Base64 string.
2. Getting Serial Number
In common scenarios, a client or user after installation creates a Request Code and sends the code to application owner (via the web or email or …). Application owner will send back a serial number that had been created based on request code.
The second part of this sample is the generation a unique serial number based on request code. All serial number needs two main factor, 1. A seed (here our seed is the HDD hardware code) 2. The algorithm that the serial number will be created based on that.
Ok, when you click on Generate Serial Number button, the handler reads the request from the textbox and convert it to double.
byte[] requestCodeByte = Convert.FromBase64String(txtRequestCode.Text);
string requestCode = string.Empty;
foreach (byte b in requestCodeByte)
{
requestCode += b.ToString();
}
long requestCodeDouble = Convert.ToInt64(requestCode);
In this sample, I use the 3 simple mathematical function to create a 3-parts serial number. You can user your own algorithm to create your own serial number.
long p1 = requestCodeDouble * requestCodeDouble - 2 * requestCodeDouble;
long p2 = (requestCodeDouble - 2) * (requestCodeDouble - 1);
long p3 = (requestCodeDouble + 2 * requestCodeDouble);
In the latest part of this method I use the string.format to create a string of serial numbers.
txtSerialNumber.Text = string.Format("{0}-{1}-{2}", p1, p2, p3);
3. Confirming The Serial Number
The final important part of the application is confirming the serial number. This function is checking 2 conditions. First checking the request code and HHD code are equals. Second checking the all serial number parts are correct.
It the first part of the handler the request code of the current computer has been retrieved.
string thisComputerHddSerialNumber = GetHDDSerialNumber();
byte[] thisComputerRequestCode = new byte[thisComputerHddSerialNumber.Length];
int counter = 0;
foreach (char c in thisComputerHddSerialNumber.ToArray())
{
thisComputerRequestCode[counter] = Convert.ToByte(c.ToString());
counter++;
}
string thisComputerRequestCodeString = Convert.ToBase64String(thisComputerRequestCode);
long p1 = userRequestCodeDouble * userRequestCodeDouble - 2 * userRequestCodeDouble;
long p2 = (userRequestCodeDouble - 2) * (userRequestCodeDouble - 1);
long p3 = (userRequestCodeDouble + 2 * userRequestCodeDouble);
On the second part of the handler method, user’s request code has been converted to a double variable. Please notice that in this sample we run three difference part of this application on the same computer. But in the real using of a serial number application, the application has 3 difference parts that run on 2 or 3 difference computer. So, this is why we need to retrieve the current computer request code again. Actually, we have compared the user serial number and request code with the correct serial number and request code based on system hardware.
byte[] userNumberByte = Convert.FromBase64String(txtRequestCode.Text);
string userRequestCode = "";
foreach (byte b in userNumberByte)
{
userRequestCode += b.ToString();
}
long userRequestCodeDouble = Convert.ToInt64(userRequestCode);
string[] parts = txtSerialNumber.Text.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
long p1c = Convert.ToInt64(parts[0]);
long p2c = Convert.ToInt64(parts[1]);
long p3c = Convert.ToInt64(parts[2]);
Now you have all you need;
a. User serial number parts
b. User request code
c. Current system serial number
d. Current system request code
Here you just need to compare these variables.
if (p1c == p1 && p2c == p2 && p3c == p3 && userRequestCode == txtRequestCode.Text)
{
lblResult.Text = "Correct";
}
else
{
lblResult.Text = "Wrong";
}
Points of Interest
I this project I learned about "ManagementObjectSearcher" object. It's very useful when you need to work with hardware code.