Archive | November, 2008

Find the factorial of a number, using Recursion

29 Nov

Let’s say someone asked you to write a method that can find the factorial of a number. I’ll show you how. And then I’ll show you how to do it recursively. Remember recursion?

But first, see the definition of Factorial from wikipedia, for those of you who didn’t do math in school.

In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example,

  5! = 1 x 2 x 3 x 4 x 5 = 120

and
6 ! = 1  \times  2  \times  3  \times  4  \times  5  \times  6 = 720 \

Standard Way

So here is the method. It takes a number and returns its factorial. This is a standard way of doing it, or you can refactor the code and make it more concise :-)

Public Function Factorials(Byval n As Integer) As Integer

	if n<1 Then return 1
	Dim res As integer = 1
		For i As Integer = 1 to n
			res*= i
		Next i
	Return res
End Function

Using Recurcion to find the factorial.
So imagine that you have to use recurcion to get the same results. Not difficult at all. You just change the code a little bit and have the method call itself. See the code below.

Public Function Factorials(Byval n As Integer) As Integer

	If n<1 Then
	 Return 1
	Else
	  Return (n * Factorials(n-1))
	End If
End Function

So that is it. Both methods work fine and return the same results. Another little bit on recursion.
Till next time, yours truly.

Digitally Signing Files and Checking Signatures

21 Nov

In a nutshell, 

digital signature is a value that can be appended to electronic data to prove that it was created by someone who possesses a specific private key. Public-key algorithms can also be used to form digital signatures. Digital signatures authenticate the identity of a sender and help protect the integrity of data.

That’s all they do, protect data integrity. When you sign a file, you or someone else can later verify the signature with your public key and check if the data was tampered with or modified in any way.

The digital signature does not protect the secrecy of the data in any way. The data is visible to anyone with access to the file. To protect the secrecy of the data, you need to encrypt the file.

The setting could be like this, you sign a file, send the public key and signature to your receiver separately, when they receive the file, they verify the signature. If its a bank cheque, and the signature is wrong, then you know someone did something with the cheque.

That being said, today I wrote two methods for signing and verifying the digital signature of a file. Let me explain a little bit on how it works. When you sign data, a public key and a signature are created. You must store these somewhere (prefarably as a file) and use them later to verify the signature of the data you signed.

I compiled the two methods to a small windows application that you can use to  sign and verify signatures. 

form_run

The .NET Framework makes digital signing of files so easy by providing two classes for generating and verifying digital signatures: DSACryptoServiceProvider and RSACryptoServiceProvider, both contained in the System.Security.Cryptography namespace. They use different algorithms but provide the same functionality.

To generate a digital signature for a file, we need to perform the following steps:
1. Create the digital signature algorithm object.(In this case we’ll use DSACryptoServiceProvider)
2. Store the data to be signed in a byte array.
3. Call the SignData method and store the signature.
4. Export the public key.

In real settings you are required to store the Signature and Public key separately, but for brevity, in this sample I will store them in the same file, and perform some string manipulation in reading them separately from the file.

Here is the source code for the first method that signs the data. It takes two arguments, a path for the data to be signed, and the path for exporting the digital signature. (If you don’t provide this, the file will be saved in the application’s primary directory (where you run it from).

Public Sub SignFile(ByVal FilePath As String, ByVal KeyPath As String)

        ' Signing Step 1: Create the digital signature algorithm object
        Dim signer As DSACryptoServiceProvider = New DSACryptoServiceProvider

        ' Signing Step 2: Store the data to be signed in a byte array.
        Dim file As FileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read)
        Dim reader As BinaryReader = New BinaryReader(file)
        Dim data As Byte() = reader.ReadBytes(CType(file.Length, Integer))

        ' Signing Step 3: Call the SignData method and create the signature
        Dim signature As Byte() = signer.SignData(data)

        ' Signing Step 4: Export the public key
        ' Save the public key and the Signature in a file. 

        Using sr As New StreamWriter(KeyPath)
            sr.Write(signer.ToXmlString(False))
            sr.WriteLine()
            sr.Write("Signature:" & System.Convert.ToBase64String(signature))
        End Using
        reader.Close()
        file.Close()
    End Sub

I trust that the code is self explanatory.

To verify the digital signature, we need to perform the following steps:
1. Create the digital signature algorithm object.(We use the same DSACryptoServiceProvider)
2. Import the signature and public key.
3. Store the data to be verified in a byte array.
4. Call the VerifyData method.

Below is the sourcecode for the signature verification method.
This one too takes a path for the file to be verified, and a path for the location of the digital signature file. It then verifies the signature, returning true if the signature is verified and false if otherwise.

Public Function VerifySignature(ByVal FilePath As String, ByVal KeyPath As String) As Boolean

        ' Verifying Step 1: Create the digital signature algorithm object
        Dim verifier As DSACryptoServiceProvider = New DSACryptoServiceProvider

        ' Verifying Step 2: Import the signature and public key.
        Dim publicKey As String = Nothing
        Dim signSource As String = Nothing

        Using sr As New StreamReader(KeyPath)
            For Each line As String In sr.ReadLine
                If Not line.StartsWith("Signature:") Then
                    publicKey += line
                Else
                    Exit For
                End If
            Next line
            signSource = sr.ReadToEnd
        End Using
        Dim res As String = signSource.Remove(0, 10)

        Dim signature As Byte() = System.Convert.FromBase64String(res)

        verifier.FromXmlString(publicKey)

        ' Verifying Step 3: Store the data to be verified in a byte array
        Dim file As FileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read)
        Dim reader As BinaryReader = New BinaryReader(file)
        Dim data As Byte() = reader.ReadBytes(CType(file.Length, Integer))

        ' Verifying Step 4: Call the VerifyData method
        If verifier.VerifyData(data, signature) Then
            Return True
        Else
            Return False
        End If
        reader.Close()
        file.Close()
    End Function
End Class

One important thing, do not forget to include the following libraries in your project.

  • System.Security.Cryptography
  • System.IO
  • System.Text.Encoding
  • System.Xml
  • System.Text

Those are the two  main important methods that I used in the small windows application. You can download the full sourcecode for the windows form as a text file here.

And please reserve your comments on the UI design, I know it isn’t that sleek.

verification

A few notes: The issue of digital signatures is broad and can not be covered in the scope of this post. I also understand that I did not explain all the bits and bytes of the code, but I hope it is understandanle. In case you need any further explanation, please feel free to contact me via: n i c l i v e @ g m a i l dot com, or through here.

Till next time, yours truly.

Windows Forms 2.0-Draw Beautiful Gradient Backdrops

17 Nov

Tired with the usual gray in windows forms? Yeah, me too! With .Net you can easily create visually beautiful color gradients on your windows forms, and with very minimum code.

Here’s a piece of code that does just that for you. This method takes the top color, bottom color and the object that called the method, it then creates a brush and an area to paint and then draws a gradient on your object which could be a form, a panel etc with a mix of the colors you selected.

Public Sub DrawGradient(ByVal UpperColor As Color, ByVal LowerColor As Color, _
                        ByVal Caller As Object)

        Dim cur As Control = CType(Caller, Control)

        Dim objBrush As New Drawing2D.LinearGradientBrush _
          (cur.DisplayRectangle, UpperColor, LowerColor, Drawing2D.LinearGradientMode.Vertical)
        Dim objGraphics As Graphics = cur.CreateGraphics()
        objGraphics.FillRectangle(objBrush, cur.DisplayRectangle)
        objBrush.Dispose()
        objGraphics.Dispose()
    End Sub

The gradient will be vertical, i.e top to bottom, but you can change the LinearGradientMode option to horizontal or diagonal depending on your choice of style.

To call this method, you use the Paint event of a form or a control. As you can see on the code above, I used the DisplayRectangle method of a control to make the code more generic, otherwise, you could use a form, or another control depending on your needs.

I used this code Dim cur As Control = CType(Caller, Control). This way you can call it from a form, a panel control, a button etc. without changing the code.
But if you are going to call it from just forms, then you could change it to this
Dim cur As Form = CType(Caller, Form).

Implementation:

Its easy. Call the method from the object’s Paint event, providing the colors you want to use. I created a simple form called GradientsSample. Here is my implementation on the form’s Paint event.

Private Sub GradientsSample_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        DrawGradient(Color.CornflowerBlue, Color.White, sender)
    End Sub

I used the XP style mix of CornflowerBlue and White. See how the form looks like.

xp-style-gradient

See, just beautiful.

I then added a panel to the left side of the form, say you want to use it as your navigation menu. This is how the forms looks like now.

xpstyle_panel

So you see the panel on the left now looks gray and ugly. The form paint event only paints the form and not the controls on the form. Which means we have to use our method to paint the panel control. I added this code to the panel’s Paint event.

Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
        DrawGradient(Color.DarkSeaGreen, Color.White, sender)
    End Sub

For the panel I used the DarkSeaGreen and White colors. The output is just beautiful, as you can see below.
panel_gradient

It is really easy to create gradients and make your forms and controls beautiful, instead of using the usual gray that is common and boring.
Till next time, yours truly.

Multicolumn Comboboxes and Lists in .Net

8 Nov

Before I moved to the .Net world, I used to write a lot of Ms Access and VB6 applications. In Access it is really easy to set up a combo box, with multiple dropdown columns. All you need to do is add a combobox to the form, a wizard will pop up, you follow the wizard, select your key column and display column, you can also choose to display both, and you are set. Your form will easily display something like this.

access_combo

Now, in visual studio 2005, it is not as easy as that. I actually was surprised to find out how much of a pain it was to create a multicolumn combobox. In visual studio when you add a combo box (that you want to bind to a datasource) it gives you the options to choose the data source, display member, value member and selected member. The music starts to play when you need two columns as the display member, like above, say productID and Description. But when a user selects something, you only need to get the productID selected and stored.

Multicolumn Lists

There are two ways you can accomplish this. The first one is to create your own custom control, that inherits from combobox, and add functionality for the datasource, display, value and selected members. The other one is to create a simple generic class, and add the same functionality. In this post I’ll show you how to create this second one.

The Logic.

What we need is a connection to the database, a stored procedure or a select statement that returns the display members, something simple like SELECT ProductID, Description FROM Products. All we need is for it to return your display members, and that is all.

So I created this class.


Imports System.Data
Imports System.Data.SqlClient

Public Class MultiColumnList
        Private connString As String
        Private sp As String
        Private source As New Dictionary(Of String, String)

        Public Property Stored_Procedure() As String
            Get
                Return sp
            End Get
            Set(ByVal value As String)
                sp = value
            End Set
        End Property

        Public Property ConnectionString() As String
            Get
                Return connString
            End Get
            Set(ByVal value As String)
                connString = value
            End Set
        End Property

        Public Function GetSelectedValue(ByVal input As String) As String
            If input = Nothing Then
                Return ""
            Else
                Return source(input)
            End If
        End Function

        Public Function DisplayItems() As String()
            'This Function returns a string array as the display member

            'clear the dictionary before adding new values to avoid duplication
            source.Clear()

            'a list for easy move of items to array
            Dim list As New List(Of String)

            Using cn As New SqlConnection(ConnectionString)
                cn.Open()
                Dim cmd As New SqlCommand()
                cmd.Connection = cn
                cmd.CommandType = CommandType.StoredProcedure
                cmd.CommandText = Stored_Procedure
                Dim da As SqlDataReader = cmd.ExecuteReader

                While da.Read
                    'saving the items in the dictionary in the format
                    'source("ProductID - Description","ProductID")
                    'We’ll use the combined display as key to get the stock-no
                   source.Add(String.Format("{0} -{1}", da.GetString(0), _
					da.GetString(1)), da.GetString(0))
                    list.Add(String.Format("{0} -{1}", da.GetString(0), da.GetString(1)))
                End While
                da.Close()
                cn.Close()
            End Using

            'string array that will be returned as source for combo/listbox dropdown display
            Dim res(list.Count - 1) As String

            'move the items from the list to our return string array

            list.CopyTo(res, 0)
            list = Nothing
            Return res
        End Function
    End Class

As you can see in the class, I used a generic string dictionary to store the returned rows, then I added them to a string array, to be used as the items collections for a dropdowm control like a combobox or a listbox.
I also added a simple function that gets the selected item, uses it as a key to read the return value from the dictionary, which is actually what will be stored in your application.

There are also two properties, to set and get the stored procedure and connection string respectively. In this case I decided to use a stored procedure, but you can easily modify the code to use a direct select statement, or you can also decide not to use a database and input your own values with a little twist to the code.

Implementation:

To implement it you can use a combobox or a listbox. In this case I’m going to use a dialog box, that has a list box control ( which I’ll now fill up with my multicolumn list). The setting is that I have a bound textbox on my form, next to it a linklabel or a button that pops up the dialog box.
So first, add a dialog to your project. Right click on your project, choose Add > New Item > Dialog
add_dialog
And then add a list box to your dialog form. On the form load event, instantiate the multicolumn class, set the connectionString property and then the stored_procedure property to the name of your stored procedure. Then handle the ok and cancel buttons click events appropriately. See the complete code listing for the dialog form below.

Imports System.Windows.Forms

Public Class Authorizers
    Dim multi As New MultiColumnList
    Public Selected As String
    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.OK
        Selected = multi.GetSelectedValue(ListBox1.SelectedItem)
        Me.Close()
    End Sub

    Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub Authorizers_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ListBox1.Items.Clear()
        multi.ConnectionString = My.Settings.UsersConnectionString
        multi.Stored_Procedure = "GetAuthorizers"
        ListBox1.Items.AddRange(multi.DisplayItems)
    End Sub
End Class

I create the public variable Selected to store the selected value, which you can later use on your form as required. This helps a lot if you have to use the dialog on multiple forms.

Implementation on main form.

To implement the dialog on my form, I added a textbox and a linklabel. When a user clicks the linklabel, the dialog is shown, they choose an item, and the value is stored in the text box. Simple as that. See the code for the linklabel, or a button, or whatever control of functionality you might choose to use for accessing the dialog.

Private Sub LinkLabel2_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles LinkLabel2.LinkClicked
        If Authorizers.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Me.AuthorizedByTextBox.Text = Authorizers.Selected
        End If
        LinkLabel1.LinkVisited = True
    End Sub

The dialog is show like in this image, see the displayed text is in the format Username-Title, but when a user selects an item, only the username is returned for use.
multicolumn_dialog
and then your value is displayed in the textbox as seen below.
after_selection
I know this is not the easiest way to accomplish this, and this is not the cleanest, concise code to do the job, but I hope it’ll help you or give you an idea of how to go about this.
All in all I think the VS designers should have made it a bit easier to create multicolumn comboboxes, for the newbies or for the lazy ones.

A more advanced and a better idea as I said above is to create a custom combobox that inherits from system.windows.forms.combobox and add all this functionality for display, datasource and selected value. This class here does not inherit from anything, so it makes it free to use and bind to any dropdown list.

Till next time. Yours truly.

Follow

Get every new post delivered to your Inbox.