Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / C#

Simple Application For Creating Serial Number Based On Hardware Code

Rate me:
Please Sign up or sign in to vote.
4.92/5 (11 votes)
3 Aug 2016CPOL3 min read 29K   1.3K   38   7
This is a simple application for creating the serial number based on HDD hardware code. It has 3 necessary part of serial number application(Request Code, Getting Serial Number and Confirming that)

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Sweden Sweden
Mehdi Mohseni is a Software senior developer (Consultant) in Sigma ITC (www.sigmait.se), Mehdi has a deep experience in N-Tier software applications as well as MVC design pattern. Mehdi has led more than 100 Asp.Net C# or VB.Net Automation applications. Mehdi is working in Toyota Material Handling Logistic Solution as Senior .Net Developer now.

Comments and Discussions

 
QuestionPNPDeviceID as a serial number? Pin
dandy728-Aug-16 9:29
dandy728-Aug-16 9:29 
Yikes.

If you're going to tell your readers to use Win32_DiskDrive's PNPDeviceID field as a "serial number", then you owe it to them to explain some of its potential shortcomings in real-world use. What happens when a disk is cloned? What happens when a disk gets a different PnP ID, as might be the case when you reconnect it through a different SATA connector (or controller)? What about virtual disks? Etc etc. Without explaining some of the caveats, some of your readers may take it on good faith that you've already done all the hard work and this will "just work" no matter what the circumstances are. This ID is rather unreliable, so you're building a brittle system on top of it because you need it to be static/unique (which it isn't).

I'm also not quite following the logic in your GetHDDSerialNumber(). Apparently, you don't care about USB drives and skip over them altogether, potentially leaving your 'outs' variable to its initialization value (an empty string). OTOH, if you have multiple drives, you'll iterate over all of them, but by the time you exit the loop, you're only going to have the value from the last drive in 'outs', effectively ignoring all the other drives. SATA drives are removable--if I remove the last drive that happened to be picked up when the function was called the first time around, then for subsequent times you'll get a different ID, so you'll get a mismatch.

GeneralRe: PNPDeviceID as a serial number? Pin
dandy723-Jun-19 10:52
dandy723-Jun-19 10:52 
Questionwrong result test on my pc Pin
YDLU4-Aug-16 12:05
YDLU4-Aug-16 12:05 
AnswerRe: wrong result test on my pc Pin
M.M.Mohseni4-Aug-16 22:27
M.M.Mohseni4-Aug-16 22:27 
GeneralRe: wrong result test on my pc Pin
Pidi5-Aug-16 3:18
Pidi5-Aug-16 3:18 
GeneralRe: wrong result test on my pc Pin
M.M.Mohseni6-Aug-16 8:48
M.M.Mohseni6-Aug-16 8:48 
AnswerRe: wrong result test on my pc Pin
jaf25-Aug-16 13:56
jaf25-Aug-16 13:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.