posted by Joao Manuel Moura Paredes on Wed 21st Apr 2004 20:06 UTC
"Tips for Mono, Page 2/2"
4th Tip: Using hashing classes

If you come to need to hash data, for example, digest a password with MD5 to save it, you will need to use the HashAlgorithm class. It is very simple to use. First you need to create an instance of the class for the hash algorithm you need (it can be one of a few, including MD5, SHA1 and others):

HashAlgorithm digest = HashAlgorithm.Create("MD5");

In the preceeding line we created an instance of HashAlgorithm for MD5 "digestion". If you need to use any other algorithm, just replace the "MD5" for the correct one. I'm not sure if it is imperative to be in uppercase. Then you can digest the data. ComputeHash expects a byte[], so, assume that buffer is a byte[].

byte [] byteHash = digest.ComputeHash(buffer);

The byteHash variable will then hold the result of the hashing. It is also very probable that you want to apply it to a String object. In that case you will need to convert from a String to a Byte[]. There are three aproaches you can use: 1) you use the ASCIIEncoding encoder; 2) you use the UTF encoders; 3) you create your own encoder that converts literaly the string to a byte[] without performing any conversion. The ASCIIEncoding and the UTF encoders are already part of the class library, so you do not have to create them. With the ASCIIEncoding it is very easy. Assuming stringToHash is the string you want to hash, do it like this:

// create a new encoder instance
ASCIIEncoding encoder = new ASCIIEncoding();

// geting the byte[] array needed for the hashing process
encoder.GetBytes(stringToHash, 0, stringToHash.Length, buffer, 0);

You can then use buffer directly with ComputeHash.

But, if you use ASCIIEncoding, you cannot use international characters with it, because that encoder will replace everything above charcode 127 with a question mark. On the other hand, you could do it with UTF encoders like this (example for UTF8):

// create a new encoder instance
UTF8Encoding encoder = new UTF8Encoding();

// geting the byte[] array needed for the hashing process
encoder.GetBytes(stringToHash);

Notice that with UTF8Encoding you didn't have to pass all those parameters you had to when you used ASCIIEncoding. UTF encoders will work but, if you plan on using them, for example, in password challenging in autenticating a connection, you cannot be sure of the encoding used in the other side. It could be anything. In my case it would probably be CP860, ISO-8859-1 or ISO-8859-15. Since the UTF encoders would replace every char above 127 with the UTF-8 code (in the UTF8 encoder case) or every char of the charset with an UTF16 (in the UTF16 encoder case), there would be problems.
So, you're left with creating your own encoder. I created one which I called NullEncoding, because it doesn't encode... just converts directly between a string and a byte[], and vice-versa:

public class NullEncoding
{
  // will give you the bytes from a string
  public static byte[] GetBytes(string s)
  {
    byte [] result = new byte[s.Length];
    for(int i = 0; i < s.Length; ++ i) result[i] = Convert.ToByte(s[i]);
    return result;
  }

  // will give you a string from the bytes
  public static string GetString(byte [] b)
  {
    string result = String.Empty;
    for(int i = 0; i < b.Length; ++ i) result += Convert.ToChar(b[i]);
    return result;
  }
}

It is a little bit different from the other encodings, but it gets the job done. If you payed attention, you will notice the static in the declaration of the methods. This way we do not need to create an instance of the class to encode our stuff. So we can do just like this:

HashAlgorithm digest = HashAlgorithm.Create("MD5");
byte [] byteHash = digest.ComputeHash(NullEncoding.GetBytes(stringToHash));

You may also have noticed the Convert.ToByte and Convert.ToChar. If you're a newbie, check monodoc, as an exercise.

5th Tip: Gtk# - The missing widgets

I started programming Gtk with C#, using Gtk#. When I was using a Gtk.Notebook widget, I wanted to place a container widget (an Hbox, in this case) with an icon and a text label as the label for the sheet tabs. But when I runned my program, which would show the window with the ShowAll() method, I noticed that the widgets in the notebook tab wouldn't get shown. I tryed using just a text label as sheet tab label, and strange enough, the label alone would get shown. As I didn't have any experience with Gtk until then, I cannot tell if this is a problem related with Gtk itself or with the Gtk# classes. Apparently, the notebook, for the wigets in the tab labels, was only calling Show(), and not ShowAll(). This resulted in only the base widget being shown. The Hbox was being shown, but not the widgets inside. So, remember to have your program calling ShowAll explicitly for the container widget inside the notebook tabs, if you want to have everything visible.

6th Tip: Gtk# - One thing you cannot do in C

One thing you cannot do in C is to derive a window class to create your window. This because C... has no classes. But in C# you can. In fact, you are advised to do it.
When creating a window, make a class that inherits from Gtk.Window. Create your own constructors, and make them set up the window appearance for you, instead of having it done in Main or somewhere else. Don't forget to call base() in the constructors to make sure everything is done correctly.
This works, and it is extremely usefull, because it allows you to have your code better organized, and to isolate components, so that you can reuse them (hey, that's part of why OOP was born :D).
Here's a short example:

public class MyForm: Gtk.Window
{
  // replace "someimage.png" with a image path of your choice
  public Gtk.Image image = new Gtk.Image("someimage.png");
  public Gtk.Label text = new Gtk.Label("Welcome to my form");
  HBox hboxBase = new HBox();

  // constructor
  public MyForm(): base("This is my form")
  {
    // setting up form aspect
    this.DefaultWidth = 600;
    this.DefaultHeight = 300;
    this.AllowGrow = false;
    this.AllowShrink = false;
    this.Modal = true;
    this.SkipTaskbarHint = true;

    this.Add(hboxBase);

    hboxBase.PackStart(image, false, false, 0);
    hboxBase.PackStart(text, false, false, 0);
  }
}

If you now do this:

MyForm form = new MyForm();
form.ShowAll();

You will have a window showing with the title "This is my form", and in the window body, you will have the image of your choice on the left, and a text label showing "Welcome to my form" on the right. Also notice that it won't show anything on the taskbar about this window because we've disabled it with this.SkipTaskbarHint = true;. Take time to try this and to experiment various combinations of widgets. Also, in monodoc there are some tutorials on Gtk# worth taking a look. Notice that all widgets belonging to that form are inside the class, and that it was not necessary to make the base HBox (hboxBase) public.

That's all folks. I hope you will enjoy this and find it useful.

About the author:
My name is Joćo Manuel Moura Paredes, and I'm a student at Faculdade de Engenharia da Universidade do Porto (Engineering School of University of Porto) in Portugal. I'm almost 22 years old and have been a programmer for more than a decade. I have experience in several programming languages (specially at low-level programming) and databases. I amexperient a few OS's, specially in Linux. I am the founder and chair of Chefax I&D student group at my University, and am currently chair of NEACM, our local student chapter for ACM (Association for Computing Machinery).


If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
Table of contents
  1. "Tips for Mono, Page 1/2"
  2. "Tips for Mono, Page 2/2"
e p (0)    60 Comment(s)

Related Articles

posted by Thom Holwerda on Mon 6th Oct 2008 10:37 submitted by John Mills
posted by Thom Holwerda on Thu 15th May 2008 13:38, submitted by gonzo
posted by Thom Holwerda on Fri 14th Mar 2008 20:41 submitted by John Mills