tag:blogger.com,1999:blog-99419802024-03-05T09:46:51.734+02:00Vadmyst's Life ChroniclesVhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.comBlogger78125tag:blogger.com,1999:blog-9941980.post-69170046023070701672012-02-03T11:46:00.000+02:002012-02-03T11:47:29.475+02:00Fast Conversion of Hex String Into Decimal NumberToday's post will be about performance. More specifically about converting hex string into decimal number faster than using built-in .NET Framework methods.<br />
<br />
I will compare performance of three methods used to convert hex into decimal number. Two of those methods are built into .NET Framework.<br />
<br />
1) Convert.ToInt32(hexNumberString, 16)<br />
2) int.Parse(hexNumber, NumberStyles.HexNumber);<br />
3) Custom method using pre-populated table. Let us call it TableConvert.<br />
<br />
Here's the code for the TableConvert class. This class just illustrates the idea behind pre-populated table - it is not production code.<br />
<br />
class TableConvert<br />
{<br />
static sbyte[] unhex_table =<br />
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1<br />
,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1<br />
};<br />
<br />
public static int Convert(string hexNumber)<br />
{<br />
int decValue = unhex_table[(byte)hexNumber[0]];<br />
for (int i = 1; i < hexNumber.Length; i++)<br />
{<br />
decValue *= 16;<br />
decValue += unhex_table[(byte)hexNumber[i]];<br />
}<br />
return decValue;<br />
}<br />
}<br />
<br />
The approach uses simple technique of pre-populated table of hex-to-decimal values and some simple math. To measure performance of these three methods I've wrote small test application that performed conversion in the loop and measured time.<br />
<br />
Tests were made using Intel Core i7 2.80 GHz, .NET Framework 4.0. Time measurements were made in ticks using Stopwatch class.<br />
<br />
Results:<br />
Hex string: FF01
<br />
<table border="1" cellpadding="4" cellspacing="1">
<tbody>
<tr><td>Iterations</td><td>TableConvert</td><td>Convert Method</td><td>Parse Method</td></tr>
<tr><td>100</td><td>28</td><td>35</td><td>63</td></tr>
<tr><td>10000</td><td>2134</td><td>2593</td><td>5915</td></tr>
<tr><td>1000000</td><td>191935</td><td>252252</td><td>433490</td></tr>
</tbody></table>
<br />
Hex string: 4AB201<br />
<table border="1" cellpadding="4" cellspacing="1">
<tbody>
<tr><td>Iterations</td><td>TableConvert</td><td>Convert Method</td><td>Parse Method</td></tr>
<tr><td>100</td><td>26</td><td>27</td><td>47</td></tr>
<tr><td>10000</td><td>1930</td><td>2775</td><td>4284</td></tr>
<tr><td>1000000</td><td>192801</td><td>269016</td><td>481308</td></tr>
</tbody></table>
<br />
<div>
Conclusions</div>
<div>
Not surprisingly Parse method has the worst performance of all methods. While TableConvert method is the fastest. Usually about 1.2 - 1.4 times faster (20%-40%) than Convert Method.</div>
<div>
<br /></div>
<div>
If you ever happen to do a lot of convert operations of hex string into decimal number and want to perform it as fast as possible - you can use TableConvert method.</div>
<div>
<br /></div>Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-482418634009209612011-10-14T10:53:00.000+03:002011-10-14T10:53:51.332+03:00Determining .NET Assembly Target Platform<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiehdbmkhGccUt96KJ3G5YhQihfjeGzmMxn2igG7bn1Fa7A7JmEPIGbMY0hCqwYqg5R5i0br1qWXn6yZMEYTJuZmMPxW6ZoajsPA8CmPsRVVobvMxZNiVSxNUSM2aYmUsp1R2LV/s1600/platform.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="91" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiehdbmkhGccUt96KJ3G5YhQihfjeGzmMxn2igG7bn1Fa7A7JmEPIGbMY0hCqwYqg5R5i0br1qWXn6yZMEYTJuZmMPxW6ZoajsPA8CmPsRVVobvMxZNiVSxNUSM2aYmUsp1R2LV/s400/platform.png" width="358" /></a></div><br />
<br />
.NET assembly can be built with different platform targets: any CPU, x86 or x64. <br />
But if all you got is already built binary file: how to determine what is exe or dll target platform?<br />
<br />
In .NET information about assemblies and types is stored using metadata. For instance, assembly metadata is contained in the <a href="http://en.wikipedia.org/wiki/Manifest_(.NET_Framework)">assembly manifest</a>.<br />
<br />
Assembly manifest can be viewed using special tools, e.g. <a href="http://msdn.microsoft.com/en-us/library/f7dy01k1(v=vs.80).aspx">IL Disassembler</a> <br />
<br />
Other tool that we can use for determining CPU type of the assembly is <a href="http://msdn.microsoft.com/en-us/library/ms164699(v=vs.80).aspx">CorFlags Conversion Tool (CorFlags.exe)</a>. I will demonstrate how this tool works and what output it generates.<br />
<br />
Let us assume we have 3 assemblies: CpuTypeSample_x86.exe, CpuTypeSample_x64.exe and CpuTypeSample_any.exe. Having x86, x64 and "Any CPU" respectively platofrm targets.<br />
<br />
In the command prompt we will execute following commands:<br />
Command: "<i>corflags CpuTypeSample_x86.exe</i>" will produce output:<br />
<i>Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8<br />
Copyright (c) Microsoft Corporation. All rights reserved.<br />
<br />
Version : v4.0.30319<br />
CLR Header: 2.5<br />
<u><b>PE : PE32</b></u><br />
CorFlags : 3<br />
ILONLY : 1<br />
<u><b>32BIT : 1</b></u><br />
Signed : 0</i><br />
<br />
The output above means that CpuTypeSample_x86.exe has PE32 executable PE type and 32BIT flag set to 1. If you observe such output on other assemblies it means they were built for x86 platform.<br />
<br />
Here is the output for the x64 assembly:<br />
Command: "<i>corflags CpuTypeSample_x64.exe</i>"<br />
<i>Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8<br />
Copyright (c) Microsoft Corporation. All rights reserved.<br />
<br />
Version : v4.0.30319<br />
CLR Header: 2.5<br />
<u><b>PE : PE32+</b></u><br />
CorFlags : 1<br />
ILONLY : 1<br />
<u><b>32BIT : 0</b></u><br />
Signed : 0</i><br />
<br />
Contrary to x86 it has PE32+ type of the PE file and 32BIT flag is turned off.<br />
<br />
Finally, here is the output for the "Any CPU" assembly:<br />
Command: "<i>corflags CpuTypeSample_any.exe</i>"<br />
<i>Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8<br />
Copyright (c) Microsoft Corporation. All rights reserved.<br />
<br />
Version : v4.0.30319<br />
CLR Header: 2.5<br />
<u><b>PE : PE32</b></u><br />
CorFlags : 1<br />
ILONLY : 1<br />
<u><b>32BIT : 0</b></u><br />
Signed : 0<br />
</i><br />
<br />
PE type in this file is similar to x86 assembly but 32BIT flag is turned off.<br />
Summary table of the above output<br />
<table cellspacing="3" cellpadding="3"><tbody>
<tr><td></td><td>PE Type</td><td>32BIT</td></tr>
<tr><td>x86</td><td>PE32</td><td>1</td></tr>
<tr><td>x64</td><td>PE32+</td><td>0</td></tr>
<tr><td>Any</td><td>PE32</td><td>0</td></tr>
</tbody></table>Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-73604819610158396292010-07-18T23:19:00.000+03:002010-07-18T23:19:38.898+03:00Fastest Way To Retrieve Custom Attributes for a Type MemberIn my previous posts (<a href="http://vadmyst.blogspot.com/2009/11/performance-issues-when-comparing-net.html">Performance Issues When Comparing Strings in .NET</a> and <a href="http://vadmyst.blogspot.com/2008/02/when-stringtolower-is-evil.html">When string.ToLower() is Evil</a>) string related operations were discussed.<br />
<br />
In this post we'll examine performance issues when querying for type member's custom attributes. <br />
Let us define two attributes and a class. Class will have its single method decorated with an attribute. Here's the code:<br />
<pre class="brush: csharp">class FooAttribute : Attribute
{ }
class BarAttribute : FooAttribute
{ }
class Item
{
[Bar]
public int Action()
{
return 0;
}
}</pre>Now the question is what is the fastest way to check <i>Action</i> method for <i>Bar</i> custom attribute. Custom attributes can be queried using instance of a type that implements <i>ICustomAttributeProvider</i> interface. In our case we shall use <i>Assembly</i> class and <i>MethodInfo</i>.<br />
<br />
The code below queries custom attributes using <i>Assembly</i> class and then using <i>MethodInfo</i> instance. Query operation executes 10000 times and duration is measured using <i>Stopwatch</i> class. Code below also measures time required to check if attribute is applied.<br />
<br />
<pre class="brush: csharp">int count = 10000;
Type tBar = typeof(Item);
MethodInfo mInfo = tBar.GetMethod("Action");
//warm up
mInfo.IsDefined(typeof(FooAttribute), true);
object[] attribs = null;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < count; i++)
{
attribs = Attribute.GetCustomAttributes(mInfo, typeof(FooAttribute), true);
}
sw.Stop();
Console.WriteLine("Attribute(specific): {0}, Found: {1}", sw.ElapsedMilliseconds,
attribs.Length);
sw.Reset();
sw.Start();
for (int i = 0; i < count; i++)
{
attribs = mInfo.GetCustomAttributes(typeof(FooAttribute), true);
}
sw.Stop();
Console.WriteLine("MethodInfo: {0}, Found: {1}", sw.ElapsedMilliseconds,
attribs.Length);
sw.Reset();
sw.Start();
for (int i = 0; i < count; i++)
{
attribs = Attribute.GetCustomAttributes(typeof(FooAttribute), true);
}
sw.Stop();
Console.WriteLine("Attribute(general): {0}, Found: {1}", sw.ElapsedMilliseconds,
attribs.Length);
sw.Reset();
sw.Start();
for (int i = 0; i < count; i++)
{
Attribute.IsDefined(mInfo, typeof(FooAttribute), true);
}
sw.Stop();
Console.WriteLine("Attribute::IdDefined: {0}", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < count; i++)
{
mInfo.IsDefined(typeof(FooAttribute), true);
}
sw.Stop();
Console.WriteLine("MethodInfo::IdDefined: {0}", sw.ElapsedMilliseconds);
sw.Reset();</pre>
Code above produces the output:
<pre><i>Attribute(specific): 137, Found: 1
MethodInfo: 130, Found: 1
Attribute(general): 569, Found: 1
Attribute::IdDefined: 40
MethodInfo::IdDefined: 33</i></pre>
Results indicate that the fastest method is querying custom attributes via <i>MethodInfo</i> class. To generalize the results above we can say that the fastest way to get custom attributes - is to use the closest reflection equivalent of type member. (e.g. Method - <i>MethodInfo</i>, Property - <i>PropertyInfo</i> etc)<br />
<br />
Last two results show the time of IsDefined operation. Use this operation in cases when only a check is needed whether attribute is applied to a type member.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-80836566872501880622010-07-08T23:37:00.000+03:002010-07-08T23:37:45.318+03:00Type inference in generic methodsDid you know that in .NET generic methods have <a href="http://en.wikipedia.org/wiki/Type_inference">type inference</a>? It can also be named as implicit typing.<br />
<br />
Let's see how type inference looks in code. In the sample below there is a class with generic methods<br />
<pre class="brush: csharp">class NonGenericType
{
public static int GenericMethod1<TValue>(TValue p1, int p2)
{
Console.WriteLine(p1.GetType().Name);
return default(int);
}
public static TValue GenericMethod2<TValue>(int p1, TValue p2)
{
Console.WriteLine(p2.GetType().Name);
return default(TValue);
}
public static TReturn GenericMethod3<TValue, TReturn>(int p1, TValue p2)
{
Console.WriteLine(p2.GetType().Name);
Console.WriteLine(typeof(TReturn).Name);
return default(TReturn);
}
}</pre>Here's the traditional way of using the above defined methods:<br />
<pre class="brush: csharp">NonGenericType.GenericMethod1<string>("test", 5);
NonGenericType.GenericMethod2<double>(1, 0.5);</pre>Nothing fancy here, we specify what type to place instead of TValue type parameter.<br />
Type inference gives us the possibility to omit directly specifying type parameters. Instead we just use methods as if they're non generic.<br />
<pre class="brush: csharp">NonGenericType.GenericMethod1("test", 5);
NonGenericType.GenericMethod2(1, 0.5);</pre>Type inference can become handy as it reduces typing, but in my opinion it makes code less readable. <br />
Also type inference cannot "guess" the return type of the method:<br />
<pre class="brush: csharp">NonGenericType.GenericMethod3(1, 0.5);
//error CS0411: The type arguments for method 'TypeInference.NonGenericType.GenericMethod3<TValue,TReturn>(int, TValue)' cannot be inferred from the usage. Try specifying the type arguments explicitly.</pre>Nice <a href="http://stackoverflow.com/questions/3203643/generic-methods-in-net-cannot-have-their-return-types-inferred-why">explanation</a> why inference does not work in the scenario above was given by <a href="http://blogs.msdn.com/b/ericlippert/">Eric Lippert</a><br />
Happy coding :)Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-6136021844596467492010-06-18T11:26:00.000+03:002010-06-18T11:26:38.103+03:00Thread Safe Collection Iteration TechniquesUnder multithreaded environment every operation should be tested and analyzed from the viewpoint of thread-safety. That is check every data structure what will happen if it is accessed/changed from multiple threads<br />
<br />
Imagine, we need to iterate over a collection of items and perform some actions over each item of the collection. Since we're talking about threading - iteration should be done in a thread safe way. That is while we are iterating over collection no other thread is allowed to add or remove items from it.<br />
No problemo! you may think - do the iteration under a lock.<br />
<br />
But it is not that simple. <br />
<br />
Code sample below illustrates two approaches how to do the iteration. Both have pros and cons. More on that after the code sample.<br />
<br />
<pre class="brush: csharp">int initialItems = 5;
ICollection<string> coll = new List<string>(initialItems);
for(int i = 1; i <= initialItems; i++)
coll.Add("item" + i.ToString());
//#1 iterating with lock approach
lock(coll)
{
foreach(string item in coll)
{
PerformWorkWithItem(item);
}
}
//
//#2 iteration over a copy
ICollection<string> copyColl = null;
lock(coll)
{
copyColl = new List<string>(coll);
}
foreach(string item in copyColl)
{
PerformWorkWithItem(item);
}
//
void PerformWorkWithItem(string item)
{
//
// perform operations that can take some
// considereable amount of time
//
}</pre><br />
Welcome back. <br />
<br />
Approach #1 uses global lock for iteration. That means that while iterating collection is protected by the lock.<br />
The pros are:<br />
<ul><li>simplicity (just put the lock and do the job)</li>
<li>Memory efficiency - no new object are constructed</li></ul>The cons are:<br />
<ul><li>if <i>PerformWorkWithItem</i> takes long time to complete or is blocking (i.e. reading data from the network) access to collection is blocked for considerable amount of time</li>
<li>action with a collection item is also protected by the lock</li>
</ul><br />
Approach #2 uses different technique. It locks access to the collection only to perform a copy (snapshot) of the original collection. Iteration and <i>PerformWorkWithItem</i> action is made over a snapshot and is not protected by the lock.<br />
The pros are:<br />
<ul><li>Operations on collection items are done without locking the collection. If <i>PerformWorkWithItem</i> takes long time to complete original collection is not locked as in #1</li>
<li>Allows to schedule actions on collection items using separate thread</li></ul>The cons are<br />
<ul><li>If original collection is large enough performing data copy can become inefficient</li>
<li>Add complexity. While performing actions on snapshot items of the original collection may have been already changed.</li></ul><br />
Now that we know pros and cons of these two approaches we can deduce some hints that can help choose appropriate technique.<br />
<br />
For instance, if <i>PerformWorkWithItem</i> action is relatively fast and there is no problem for the rest of the application to wait for iteration process then approach #1 is the best.<br />
<br />
On the other hand if <i>PerformWorkWithItem</i> can take considerable amount of time and other parts of the application frequently access the collection (i.e. it is not desirable to block access to the collection for a long time) then #2 can do.<br />
<br />
P.S. There also exists an approach #3. It utilizes <a href="http://en.wikipedia.org/wiki/Non-blocking_synchronization">lock-free</a> data structures. But it is a whole new story and a topic for separate post.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-74139781047197535472010-06-15T18:38:00.001+03:002010-06-15T18:38:42.419+03:00AesManaged class Key and KeySize properties issueToday when working with <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx">AesManaged</a> class I've encountered very strange behavior. <br />
If you have a code like this - you're in trouble:<br />
<pre><i>AesManaged aes = new AesManaged();
aes.Key = key;
aes.KeySize = key.Length; //the problem</i></pre>The problem with this code is setting <i>KeySize</i> after setting <i>Key</i> value. <br />
When you set <i>KeySize</i> after <i>Key</i> - the previously specified key is discarded and a brand new key value is generated and put into <i>Key</i> property<br />
<br />
I find this behavior rather strange, especially that there is no information describing what will happen after setting <i>KeySize</i>.<br />
<br />
I would expect that when <i>Key</i> value is set setting <i>KeySize</i> will throw exception if specified key's size is bigger or smaller than the new one.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-36240912129880553172010-04-28T17:20:00.001+03:002010-04-28T17:35:36.985+03:00The Big Bang Theory sitcom scientific backgroundUsually I do not write about TV. But the serial in the subject is one of my favorite.<br />
<br />
Recently I've found <a href="http://thebigblogtheory.wordpress.com/">blog of the guy</a> who does scientific background for that sitcom. <br />
There are a lot of interesting scientific facts on that blog in the context of the TV show.<br />
<br />
I totally recommend reading it even if you do not watch <a href="http://en.wikipedia.org/wiki/The_Big_Bang_Theory">The Big Bang Theory</a><br />
The url of the blog is <a href="http://thebigblogtheory.wordpress.com/">http://thebigblogtheory.wordpress.com/</a>Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-79707781271571529982010-04-16T11:37:00.001+03:002010-06-15T21:44:59.757+03:00Refactoring code with lambda expressionsWithout much ado lets go straight to the code that needs to be refactored:<br />
<pre><i>bool SomeMethod(long param)
{
//
// some prefix code
//
try
{
//do specific job here
return DoSpecificJob(param);
}
finally
{
//
// some suffix code
//
}
}
Result SomeOtherMethod(string name, int count)
{
//
// some prefix code
//
try
{
return DoOtherSpecificJob(name, count);
}
finally
{
//
// some suffix code
//
}
}</i></pre>The question is how we can bring prefix and suffix code from the example above in one place (method) without changing code logic.<br />
The goal is to have these two methods rewritten like this:<pre><i>bool SomeMethod(long param)
{
return DoSpecificJob(param);
}
Result SomeOtherMethod(string name, int count)
{
return DoOtherSpecificJob(name, count);
}</i></pre>While another method will be created that executes prefix and suffix code.<br />
<br />
There are several ways how to do that:<br />
1. Create method that contains prefix and suffix code, accepts <i>Delegate</i> object and <i>params object[] array</i><br />
<pre><i>object ExecuteCommon(Delegate d, params object[] args)
{
//
// prefix code
//
try { return d.DynamicInvoke(args); }
finally
{
//
// suffix code
//
}
}
bool SomeMethod_First(long param)
{
Delegate d = new Func<long, bool>((b) => SomeMethod(b));
return (bool)ExecuteCommon(d, new object[] {param});
}
Result SomeOtherMethod_First(string name, int count)
{
Delegate d = new Func<string, int, Result>((n, c) => SomeOtherMethod(n, c));
return (Result)ExecuteCommon(d, new object[] { name, count });
}</i></pre>The approach looks nice but has several caveats. The problems here are: boxing (wrapping value types into reference types) and casting.<br />
2. Move repeated code up on the call stack<br />
This approach is possible if <i>SomeMethod</i> and <i>SomeOtherMethod</i> are on the same call stack level or called from the same method.<br />
<br />
3. Create a generic method that accepts generic delegate and defines several parameters<br />
<pre><i>TResult ExecuteCommon<T1,TResult>(Func<T1, TResult> func, T1 param1)
{
//
// some prefix code
//
try { return func(param1); }
finally
{
//
// some suffix code
//
}
}
TResult ExecuteCommon<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 param1, T2 param2)
{
//
// some prefix code
//
try { return func(param1, param2); }
finally
{
//
// some suffix code
//
}
}
bool SomeMethod_Third(long param)
{
return ExecuteCommon<long, bool>((p) => SomeMethod(param), param);
}
Result SomeOtherMethod_Third(string name, int count)
{
return ExecuteCommon<string, int, Result>(
(n, c) => SomeOtherMethod(n, c), name, count);
}</i></pre>This method does not use casting and there is no boxing present when value type parameters are specified. However, the caveat is that you need to define multiple methods with variable type parameters count. In my opinion the third approach is the best although we have to define two methods that execute prefix/suffix code.<br />
<br />
P.S. Another way of refactoring here is code generation: emitting code on the fly or using template tools like T4 templates in Visual Studio.<br />
<br /><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fvadmyst.blogspot.com%2f2010%2f04%2frefactoring-code-with-lambda.html"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fvadmyst.blogspot.com%2f2010%2f04%2frefactoring-code-with-lambda.html" border="0" alt="kick it on DotNetKicks.com" /></a>Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-81342075588179532332009-12-17T13:15:00.002+02:002010-06-03T17:50:41.076+03:00Mono: C# compiler bug with property inheritanceThe bug appeared quite unexpectedly. <br />
In Visual Studio code sample below compiled fine. But doing the same with <a href="http://www.mono-project.com">Mono</a> C# compiler results in error: Compiler Error <a href="http://msdn.microsoft.com/en-us/library/xt3e9f86%28VS.71%29.aspx">CS0546</a>: 'Derived2.Accessor.set': cannot override because 'Base.Accessor' does not have an overridable set accessor.<br />
It must've been a bug with the compiler I thought to myself. Mono <a href="https://bugzilla.novell.com/">bugzilla</a> search confirmed that bug was there.<br />
<br />
Here is the code sample that produces error report (workaround is described under it):<pre><i>abstract class Base
{
public virtual string Accessor
{
get { return "base"; }
set { }
}
}
class Derived1 : Base
{
public override string Accessor
{
get { return base.Accessor; }
}
}
class Derived2 : Derived1
{
public override string Accessor
{
set { }
}
}</i></pre>Workaround for this error is to add set property to Derived1 class:<pre><i>public override string Accessor
{
get { return base.Accessor; }
set { base.Accessor = value; }
}</i></pre>Happy coding :)Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com13tag:blogger.com,1999:blog-9941980.post-25291278526320375202009-12-13T12:19:00.000+02:002009-12-13T12:19:22.032+02:00MSSQL DATEDIFF Equivalent in MySQLRecently I was porting T-SQL (MSSQL) code into SQL dialect used by MySQL.<br />
Process went smoothly until I have stuck with dates. Especially intervals between two dates. In T-SQL <i>datediff</i> function is used to get interval between to datetime values.<br />
<br />
Let us consider this T-SQL sample:<br />
<pre><i>declare @d1 datetime;
declare @d2 datetime;
set @d1 = '2009-01-18 15:22:01'
set @d2 = '2009-01-19 14:22:01'
select datediff(hour, @d1, @d2) as hour,
datediff(day, @d1, @d2) as day,
datediff(second, @d1, @d2) as second</i></pre>Query results are:<br />
<table><tr><td>hour</td><td>day</td><td>second</td></tr>
<tr><td>23</td><td>1</td><td>82800</td></tr>
</table><br />
After doing some searching I found out that MySQL equivalent is:<br />
<pre><i>set @d1 = '2009-01-18 15:22:01';
set @d2 = '2009-01-19 14:22:01';
select timestampdiff(hour, @d1, @d2) as hour,
timestampdiff(day, @d1, @d2) as day,
timestampdiff(second, @d1, @d2) as second;</i></pre>Query results are:<br />
<table><tr><td>hour</td><td>day</td><td>second</td></tr>
<tr><td>23</td><td>0</td><td>82800</td></tr>
</table>Query results are nearly the same except day difference. Somehow, MSSQL treats 23 hours as one day. <br />
<br />
In general we can think of timestampdiff (MySQL) as 1-to-1 equivalent of datediff (MSSQL). To make them truly equal it is better to get difference in seconds and then convert (calculate) required interval (hours, days).Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-34594972267680922332009-11-21T00:22:00.005+02:002009-11-21T00:22:00.364+02:00String Compare Performance in DA while ago I was measuring <a href="http://vadmyst.blogspot.com/2009/11/performance-issues-when-comparing-net.html">performance of string comparison in .NET</a>. Today I played with string type in <a href="http://www.digitalmars.com/d/index.html">D programming language</a> and decided to make similar tests. <br />
<br />
D is relatively new language with some good perspectives (by the way <a href="http://en.wikipedia.org/wiki/Andrei_Alexandrescu">Andrei Alexandrescu</a> is engaged in D development).<br />
<br />
Here is relatively simple code, that I have used to make the tests:<pre><i>import std.string;
import std.date;
import std.stdio;
string cmp1 = "SomeString";
string cmp2 = "Someotherstring";
auto iters = 100000;
void test_f()
{
for(int i = 0; i < iters; i++) { auto res = icmp(cmp1, cmp2); }
}
void test_equal()
{
for(int i = 0; i < iters; i++) { auto res = cmp1 == cmp2; }
}
void main()
{
ulong[] results;
int mean1 = 0;
int mean2 = 0;
for(int i = 0; i < 5; i++)
{
results = benchmark!(test_f, test_equal)(1, results);
mean1 += results[0];
mean2 += results[1];
writefln("Test_f: %d", results[0]);
writefln("Test_equal: %d", results[1]);
}
mean1 = mean1 / 5;
mean2 = mean2 / 5;
writefln("Mean Test_f: %d", mean1);
writefln("Mean Test_equal %d", mean2);
}</i></pre>Test results where interesting:<br />
<pre><i>Test_f: 21
Test_equal: 2
Test_f: 21
Test_equal: 2
Test_f: 22
Test_equal: 2
Test_f: 14
Test_equal: 1
Test_f: 12
Test_equal: 1
Mean Test_f: 18
Mean Test_equal 1</i></pre>18 millis for 100000 iterations looks pretty nice. It is faster then .NET string case insensitive ordinal string comparison. If you remember: .NET version completed in about 26 milliseconds. Second test function just compares two values for equality, I assume that mere pointer compare is made.<br />
<br />
I have decided to give this relatively new language a try, it is highly possible that there will be more posts about D in this blog :).Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-44609551306788213382009-11-18T21:54:00.000+02:002009-11-18T21:54:58.976+02:00Local Computer Connection Failure When Using ActiveSyncNot so long ago I have encountered strange problem with Windows Mobile device connectivity when using ActiveSync. <br />
<br />
Here is long story cut short and the solution I came up with.<br />
<br />
Server software was located on the Host1. Windows Mobile device was supposed to connect to that server software.<br />
<br />
When device was cradled and connected to Host1's ActiveSync it was unable to open connection to server software. However, it could connect perfectly well to the same server software located on Host2. Strange? <br />
<br />
It turned out that for local connections (connections to the host where ActiveSync is located) ActiveSync substitutes remote address device wants to connect to with 127.0.0.1. It is loopback address. <br />
Server software was listening on particular IP address (at that time this was by design). <br />
I discovered this by using <i>netstat</i> command and connecting with Windows Mobile browser to local IIS web server.<br />
The command I have used was: <i>netstat -anbp tcp</i><br />
<br />
Obvious fix: listen on 0.0.0.0 (in .NET it is IpAddress.Any). <br />
Any time when connection to local computer from cradled device fails - check if software you are connecting to listens on all IP addresses or is configured to listen on loopback (127.0.0.1) too.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com2tag:blogger.com,1999:blog-9941980.post-4222206444135093952009-11-12T00:13:00.000+02:002009-11-12T00:13:53.569+02:00Performance Issues When Comparing .NET StringsEvery time when you want to use string.Compare("str1", "str2", true) for case insensitive string comparison - think twice.<br />
<br />
To illustrate my point I am bringing this example:<pre><i>
int iters = 100000;
string cmp1 = "SomeString";
string cmp2 = "Someotherstring";
Stopwatch sw = Stopwatch.StartNew();
for(int i =0 ;i < iters;i++)
{
int res = string.Compare(cmp1, cmp2, true);
}
sw.Stop();
Console.WriteLine("First:" + sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int i = 0; i < iters; i++)
{
int res = string.Compare(cmp1, cmp2, StringComparison.OrdinalIgnoreCase);
}
sw.Stop();
Console.WriteLine("Second:" + sw.ElapsedMilliseconds);</i></pre><br />
Quick question which method is faster, first or second?<br />
<br />
...<br />
...<br />
<br />
Here is my result in milliseconds:<br />
<i>First:77<br />
Second:26</i><br />
<br />
Wow, second sample nearly 3 times faster!!! <br />
This is because first method uses culture-specific information to perform comparison, while the second uses ordinal compare method (compares numeric values of each char of the string).<br />
<br />
Knowing the above we can deduce general rule of thumb: when culture-specific string comparison is not required we should use second way otherwise first one.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-42798787571661332332009-09-24T16:53:00.000+03:002009-09-24T16:53:01.171+03:00Howto: C++ Class Conversion Operator in .CPP fileIn case someone did not know how to do this. It took me some time to figure out the right syntax for writing conversion operator implementation in the CPP file. Here is the definition of the <a href="http://msdn.microsoft.com/en-us/library/5s5sk305.aspx">conversion operator</a>.<br />
<br />
In a header (.h) file we have TestCase class declared.<br />
<pre><i>class TestCase
{
public:
operator std::string ();
};</i></pre>While in .CPP we should have declaration written in the form <i>TestCase::</i>.<br />
The declaration of the "to std::string" conversion operator will look like this<br />
<pre><i>TestCase::operator std::string()
{
std::string msg("TestCase internals");
return msg;
}</i></pre>Now we can use this operator in the code<br />
<pre><i>TestCase testClass;
std::string msg = testClass;
</i></pre>msg variable will be equal to "TestCase internals" string.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-71558571048803434122009-06-23T23:35:00.005+03:002009-06-24T00:09:36.085+03:00Complex Keys In Generic DictionaryLet us start with the quiz about generic dictionary.<br /><pre><i>Dictionary<string, string> simpleDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);<br />simpleDict["name1"] = "value";<br />simpleDict["Name1"] = "value2";</i></pre>What value will <i>simpleDict["name1"]</i> return?<br /><br />Let's get back to using complex keys in generic dictionary.<br /><br />.NET Framework provides <a href="http://msdn.microsoft.com/en-us/library/ms132151.aspx">IEqualityComparer<T></a> interface that can be used by dictionary to distinguish between different keys.<br /><br />Imagine we have a complex class that we want to serve as a key in our dictionary. <pre><i>public class ComplexKey<br />{<br /> public int Part1 { get; set; }<br /> public string Part2 { get; set; }<br />}</i></pre>The implentation of the comparer will be the following:<br /><pre><i>public class ComplexKeyComprarer : IEqualityComparer<ComplexKey><br />{<br /> public bool Equals(ComplexKey x, ComplexKey y)<br /> {<br /> return x.Part1.Equals(y.Part1) && x.Part2.Equals(y.Part2);<br /> }<br /><br /> public int GetHashCode(ComplexKey obj)<br /> {<br /> return obj.Part1.GetHashCode() ^ obj.Part2.GetHashCode();<br /> }<br />}</i></pre>Having created the comparer we can now instantiate dictionary and operate with complex keys in the same way as with simple ones.<br /><pre><i>Dictionary<ComplexKey, string> complexDict = <br /> new Dictionary<ComplexKey, string>(new ComplexKeyComprarer());<br /><br />ComplexKey ck1 = new ComplexKey() { Part1 = 1, Part2 = "name1" };<br />ComplexKey ck2 = new ComplexKey() { Part1 = 1, Part2 = "name2" };<br /><br />complexDict[ck1] = "value1";<br />complexDict[ck2] = "value2";</i></pre><br />Very convenient by the way :)Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com4tag:blogger.com,1999:blog-9941980.post-77916523926756920562009-05-07T12:41:00.010+03:002009-05-07T19:35:30.495+03:00Check If Local Port Is Available For TCP SocketFrom time to time we need to check if specified port is not occupied. It can be some sort of setup action where we install server product and want to assure that tcp listener will start without any problems.<br /><br />How, to check if port is busy - start listening on it.<br /><br />Version #1<br /><pre><i>bool IsBusy(int port)<br />{<br /> Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,<br /> ProtocolType.Tcp);<br /> try<br /> { <br /> socket.Bind(new IPEndPoint(IPAddress.Any, port));<br /> socket.Listen(5);<br /> return false;<br /> } catch { return true; }<br /> finaly { if (socket != null) socket.Close(); }<br />}</i></pre>If another process is listening on specified address our code will return false. This will make our code think that port was free while it was not. Remember, we are checking port availability. We need exclusive access to the port.<br /><br />Version #2<br /><pre><i>bool IsBusy(int port)<br />{<br /> Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,<br /> ProtocolType.Tcp);<br /> try<br /> { <br /> <b>socket.SetSocketOption(SocketOptionLevel.Socket, <br /> SocketOptionName.ExclusiveAddressUse, true);</b><br /> socket.Bind(new IPEndPoint(IPAddress.Any, port));<br /> socket.Listen(5);<br /> return false;<br /> } catch { return true; }<br /> finaly { if (socket != null) socket.Close(); }<br />}</i></pre>This version of the code is much better. It tries to bind the endpoint with exclusive access. If some other process is listening on the port or established connection is bound to the port an exception will be thrown.<br /><br />And, of course, there is another way how to perform the check. We shall use classes from <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.aspx">System.Net.NetworkInformation</a> namespace<pre><i>bool IsBusy(int port)<br />{<br /> IPGlobalProperties ipGP = IPGlobalProperties.GetIPGlobalProperties();<br /> IPEndPoint[] endpoints = ipGlobalProperties.GetActiveTcpListeners();<br /> if ( endpoints == null || endpoints.Length == 0 ) return false;<br /> for(int i = 0; i < endpoints.Length; i++)<br /> if ( endpoints[i].Port == port )<br /> return true;<br /> return false; <br />}</i></pre>Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-61895990782405787672009-04-27T19:30:00.019+03:002009-04-29T23:20:24.558+03:00Discovering System Endianess<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUthGgsY0l7kHBKSmuSfPC5-L1r5YIHU-N8bNik13QW9IXjhGhZxflTtcaTqnOfBblmFZkOnwpmD06K931fbv5iJuZssL4FSOPL_ajivGAAkVsWEHN0tX2dKNO2LizyYuPvnCP/s1600-h/endianess.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 381px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUthGgsY0l7kHBKSmuSfPC5-L1r5YIHU-N8bNik13QW9IXjhGhZxflTtcaTqnOfBblmFZkOnwpmD06K931fbv5iJuZssL4FSOPL_ajivGAAkVsWEHN0tX2dKNO2LizyYuPvnCP/s400/endianess.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5329452774130586098" /></a><br />When doing network programming we send bytes to and from peers. These bytes sometimes constitute complex protocols.<br /><br />Let us assume we have simple message exchange protocol with some header and some data. Like in the picture <a href="http://vadmyst.blogspot.com/2008/03/part-2-how-to-transfer-fixed-sized-data.html">here</a>.<br /><br />Our prefix contains the size of the message. When peer receives bytes from network it reads header first (which is fixed length) then decodes information from the header (data size etc) and finally tries to read the specified number of bytes from the network. <br /><br />Network applications usually have at least two peers. These peers can be hosted on different systems. Say, peer1 is working on Windows OS, while peer2 - is Java app working in Unix environment. <br />Our protocol contains integer value that holds message's data size. This value is 4-bytes long. <br /><br />Windows OS works with numbers that are considered to be little endian, that is <a href="http://en.wikipedia.org/wiki/Least_significant_byte">least significant byte</a> is placed on the lowest address. Vice versa for Java number. This division is known as <a href="http://en.wikipedia.org/wiki/Endianness">endianess</a>. <br /><br />To transfer multi-byte values over network in uniform manner an agreement was established. Multi-byte data is written into network in big endian byte order.<br /><br />Earlier I have said that Windows is little endian system, do you really believe me?<br />If you do not - check yourself, here's how you can do this in C#.<br /><br />First approach:<br /><pre><i>int number = 0x00000001;<br />byte[] bytes = BitConverter.GetBytes(number);<br />bool isBigEndian = bytes[0] == 0x00;</i></pre>Second approach (for geeks):<br /><pre><i>int number = 0x00000001;<br />int* p = &number;<br />bool isBigEndian = p[0] == 0x00;</i></pre>And finally the third one:<br /><pre><i>bool isBigEndian = !BitConverter.IsLittleEndian;</i></pre>When you want to write self-contained code, the above approaches can be used to determine endianess of the system your code operates on.<br /><br />P.S. Third method is the best :).Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com3tag:blogger.com,1999:blog-9941980.post-28788792037431933092009-03-26T23:13:00.011+02:002009-03-26T23:51:04.214+02:00Windows Vista Defragmentation ToolsWindows Vista by default uses NTFS file system. Sooner or later files on it will start to fragment. <br /><br />Fragmentation can lead to significant disk I/O performance decrease. Common way how to handle this problem is a process called <a href="http://en.wikipedia.org/wiki/Defragmentation">defragmentation</a><br /><br />It turns out that Vista's defragmentation tools is little bit oversimplified<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrYe_pHcsGQzJqXWDjNehIWQFPEjy7Ek0ekAgrAgz08_4micAIktHEBe_OlfXuTeZTJBGbO4FDLqjNn1s_R2d8JNQlMfchumlEU8z6x3YYUnmH1zZuAuL4LrBP6ztPzC0WHyCx/s1600-h/vista_defrag.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 208px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrYe_pHcsGQzJqXWDjNehIWQFPEjy7Ek0ekAgrAgz08_4micAIktHEBe_OlfXuTeZTJBGbO4FDLqjNn1s_R2d8JNQlMfchumlEU8z6x3YYUnmH1zZuAuL4LrBP6ztPzC0WHyCx/s400/vista_defrag.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5317610813262279090" /></a><br />As you can see, user interface lacks volume fragmentation information. So it is hard to say whether my volume needs defragmentation.<br /><br />Be afraid not as Vista has command-line based tool - <i>defrag.exe</i>.<br /><i><pre>Windows Disk Defragmenter<br />Copyright (c) 2006 Microsoft Corp.<br />Description: Locates and consolidates fragmented files on local volumes to<br /> improve system performance.<br /><br />Syntax: defrag <volume> -a [-v]<br /> defrag <volume> [{-r | -w}] [-f] [-v]<br /> defrag -c [{-r | -w}] [-f] [-v]<br /><br />Parameters:<br /><br />Value Description<br /><br /><volume> Specifies the drive letter or mount point path of the volume to<br /> be defragmented or analyzed.<br /><br />-c Defragments all volumes on this computer.<br /><br />-a Performs fragmentation analysis only.<br /><br />-r Performs partial defragmentation (default). Attempts to<br /> consolidate only fragments smaller than 64 megabytes (MB).<br /><br />-w Performs full defragmentation. Attempts to consolidate all file<br /> fragments, regardless of their size.<br /><br />-f Forces defragmentation of the volume when free space is low.<br /><br />-v Specifies verbose mode. The defragmentation and analysis output<br /> is more detailed.<br /><br />-? Displays this help information.<br /><br />Examples:<br /><br />defrag d:<br />defrag d:\vol\mountpoint -w -f<br />defrag d: -a -v<br />defrag -c -v<br /></pre></i><br />Here's sample output on my system volume (C:),<br /><i>defrag c: -a</i><br /><i><pre>Windows Disk Defragmenter<br />Copyright (c) 2006 Microsoft Corp.<br /><br />Analysis report for volume C: VISTA<br /><br /> Volume size = 70.00 GB<br /> Free space = 21.84 GB<br /> Largest free space extent = 6.20 GB<br /> Percent file fragmentation = 4 %<br /><br /> Note: On NTFS volumes, file fragments larger than 64MB are not included in the fragmentation statistics<br /><br /> You do not need to defragment this volume. <br /></pre></i><br />It is also possible to increase the amount of information returned by the tool, just specify <i>-v</i> switch.<br /><br />Now we have some information about disk fragmentation and hence can decide when to start defragmentation process.<br /><br />P.S. I had a strange filling when writing this post. In an operating system like Windows Vista with redesigned user interface it is awkward too use command-line tools to perform common task like disk defragmentation.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-47851019313409395852009-03-15T23:52:00.011+02:002009-03-16T00:14:37.293+02:00Image Watermarking<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgFV4uRoWusZK-VLzaQ6NiotCRjgPip7hHusZ8Boyd6wC7CDQyBIPkRBIjZifIHpSWbRT0NH7Z04fuFdM3W0-oQYBcWkXcff89i-BmAwXJZ0ky7fcCqyg6V9g4PZfU6eUpGVV8/s1600-h/BigSunWatermark.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 380px; height: 400px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgFV4uRoWusZK-VLzaQ6NiotCRjgPip7hHusZ8Boyd6wC7CDQyBIPkRBIjZifIHpSWbRT0NH7Z04fuFdM3W0-oQYBcWkXcff89i-BmAwXJZ0ky7fcCqyg6V9g4PZfU6eUpGVV8/s400/BigSunWatermark.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313541053135214098" /></a><br /><br />We all know that when image is posted on the internet it no longer belongs to you. <br /><br />It can be arguable, but nevertheless, any user with browser can simply save it on HDD and you can do nothing about it.<br /><br />One of the ways how to control image distribution is <a href="http://en.wikipedia.org/wiki/Digital_watermarking">Digital watermarking</a>.<br /><br />In my case I had ~100 images that had to be watermarked. There are two ways how to do this: manually (e.g using Photoshop) or write some code to do the job automatically.<br /><br />In case of simple watermarks: horizontal/vertical text everything is simple, but things become harder when watermark text should be positioned diagonally. <br /><br />After poking around the web I found <a href="http://www.codeproject.com/KB/audio-video/TrigWaterMark.aspx?display=Print">this</a> brilliant article. The code did it job well, so I wired it into small console app, and voilĂ - 105 files watermaked in less then 20 seconds.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0tag:blogger.com,1999:blog-9941980.post-17062435699960446182009-01-19T23:32:00.013+02:002009-01-20T00:16:51.297+02:00Searching for Similar Words. Similarity Metric<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhapxvHLIvDLtl1mzhrty-Ygwa3nCBr50KEERpapMC1S-Oi2QSrTq1fksbHmRlXtB43VVZJBNEXzXfLOJRxYgzWdRgJE5O4UL1dbiNJY45zKIoTEIVUStznaTIoy79ZMfduS6x0/s1600-h/euc.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 321px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhapxvHLIvDLtl1mzhrty-Ygwa3nCBr50KEERpapMC1S-Oi2QSrTq1fksbHmRlXtB43VVZJBNEXzXfLOJRxYgzWdRgJE5O4UL1dbiNJY45zKIoTEIVUStznaTIoy79ZMfduS6x0/s400/euc.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5293131918132779954" /></a><br /><br />How one can find out if two or more words are similar? I do not mean semantically similar (synonyms aren't taken into consideration), but visually similar.<br /><br />Consider, these two words, "sample1" and "sample2". Do they look similar? Well, at least they have the same start - "sample". The next two have merely common letters in them: "fox" and "wolf".<br /><br />One of the methods that can be used to measure words similarity is <a href="http://en.wikipedia.org/wiki/Euclidean_distance">Euclidian distance</a>. It is used to measure distance beetwen two point in space.<br /><br />The code to measure similarity of 2 strings:<br /><pre>public static double Euclidian(string v1Orig, string v2Orig)<br />{<br /> string v1, v2;<br /> if (v1Orig.Length > v2Orig.Length)<br /> {<br /> v1 = v1Orig; v2 = v2Orig;<br /> }<br /> else<br /> {<br /> v1 = v2Orig; v2 = v1Orig;<br /> }<br /><br /> double d = 0.0;<br /> for (int i = 0; i < v1.Length; i++)<br /> {<br /> if ( i < v2.Length )<br /> d += Math.Pow((v1[i] - v2[i]), 2);<br /> else<br /> d += Math.Pow((v1[i] - 0.0), 2);<br /> }<br /> return Math.Sqrt(d);<br />}</pre><br />Using the code above we can get numbers that measure words similarity:<br />"sample1" and "sample2" will give 1.0. While "wolf" and "fox" give 104.10091258005379. Words that are identical will give 0.0. Thus the less number you get the more two words are similar.<br /><br />In the context of Euclidean distance, "fox" and "wolf" have greater distance then "sample1" and "sample2".<br /><br />This measurement approach can be used when searching for word groups in the text.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-17154931198851752092008-11-03T22:48:00.005+02:002008-11-07T12:50:47.077+02:00Bit Flags: The Simple Way<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmPhRcpF5gL2qW6HyjcS8tyx1jTRQ1UfmTL_QEq3PrV4ZHLj87N81LSFxFVCnq9qsrdASVCMj4rJCE0BfF_L0VES04Pv8yfQtpLf606U9aT8HOVWRgLmZAsMDVojGSC9WTqxiI/s1600-h/bits.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 199px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmPhRcpF5gL2qW6HyjcS8tyx1jTRQ1UfmTL_QEq3PrV4ZHLj87N81LSFxFVCnq9qsrdASVCMj4rJCE0BfF_L0VES04Pv8yfQtpLf606U9aT8HOVWRgLmZAsMDVojGSC9WTqxiI/s400/bits.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5265866231238438834" /></a><br />Time from time we face the need or (for some of us) an opprotunity to mess with the bit fields. As we all know bytes consist of bits. Bit can have two values "0" and "1".<br /><br />Using this knowledge we can store several flags under single byte. In one byte of information we can efficiently store eight one bit flags (1 byte has 8 bits). If we use int values, which has four bytes - we can store 32 bit flags (4*8=32).<br /><br />So, lets define 8 bit flags. We should receive following picture.<pre>0000000<b>1</b> - 1-st flag<br />000000<b>1</b>0 - 2-nd flag<br />00000<b>1</b>00 - 3-rd flag<br />0000<b>1</b>000 - 4-th flag<br />000<b>1</b>0000 - 5-th flag<br />00<b>1</b>00000 - 6-th flag<br />0<b>1</b>000000 - 7-th flag<br /><b>1</b>0000000 - 8-th flag</pre><br />There are two ways how to define these flags in C#. Here is the first way: convert each binary number into hexadecimal representation (decimal can be also used). The result will be like this:<pre>[Flags]<br />public enum FirstApproach : byte<br />{<br /> First = 0x01,<br /> Second = 0x02,<br /> Third = 0x04,<br /> Forth = 0x08,<br /> Fifth = 0x10,<br /> Sixth = 0x20,<br /> Seventh = 0x40,<br /> Eighth = 0x80, <br />}</pre>We obtained rather compact definition. But if someone cannot convert binary (01000000) into hex (0x40) number very fast - she will have to use some special tool like calc.exe :). I consider the above mentioned way little bit tiresome.<br /><br />Here is the second approach: we define <u>"base"</u> at first.<pre>[Flags]<br />public enum DefBase : byte<br />{<br /> First = 0,<br /> Second = 1,<br /> Third = 2,<br /> Forth = 3,<br /> Fifth = 4,<br /> Sixth = 5,<br /> Seventh = 6,<br /> Eigth = 7,<br />}</pre>Then, using "base" we can define our flags:<pre>[Flags]<br />public enum SecondApproach : byte<br />{<br /> First = 1 << (byte)DefBase.First,<br /> Second = 1 << (byte)DefBase.Second,<br /> Third = 1 << (byte)DefBase.Third,<br /> Forth = 1 << (byte)DefBase.Forth,<br /> Fifth = 1 << (byte)DefBase.Fifth,<br /> Sixth = 1 << (byte)DefBase.Sixth,<br /> Seventh = 1 << (byte)DefBase.Seventh,<br /> Eighth = 1 << (byte)DefBase. Eigth, <br />}</pre>Using 2-nd approach does not involve conversion from binary to hex. Using this method we can reuse DefBase multiple times to create required bit flags. Defining next bit flag is no more pain.<br /><br />If application will have a lot of bit flags declarations then it is more usefull to use 2-nd approach as it can save time of not using additional tools.Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-19869945949462917232008-10-30T19:06:00.007+02:002009-06-01T13:27:21.085+03:00Handling Windows Operating System Version Mess<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPXqMOee3DuAWbx-kXnOb-uE6U_T6DcU-d3HOU4mjIcn4PoJ04Q4W52qFpNiDXZJqQ-bSKMop0D51swvlPGvqnTQsyE7hvn_-EDfu7CCt5wmK9UOmtWtmw1NKr2O2IwQGBjvk1/s1600-h/installer_error.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 315px; height: 236px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPXqMOee3DuAWbx-kXnOb-uE6U_T6DcU-d3HOU4mjIcn4PoJ04Q4W52qFpNiDXZJqQ-bSKMop0D51swvlPGvqnTQsyE7hvn_-EDfu7CCt5wmK9UOmtWtmw1NKr2O2IwQGBjvk1/s400/installer_error.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5263004424486211602" /></a><br /><br />Operating System (OS) like any other software should have a version. So do new OSes from Microsoft.<br /><br />Sometimes OS version is crucial for the installation software development process. Some products can work on XP and Vista, but cannot work on Windows Server 2003. MSI (Microsoft Installer) has special properties called VersionNT and WindowsBuild to ensure OS version.<br /><br />Quite logically, eh?<br /><br />Official <a href="http://msdn.microsoft.com/en-us/library/aa370556(VS.85).aspx">documentation</a> gives a reference table with OS versions and build numbers.<br /><br />Using information from table we can define following WiX condition:<pre><Condition Message='This software requires the Windows Server<br /> 2003 to operate correctly'><![CDATA[VersionNT = "502"]]><br /></Condition></pre>At the bottom of this table we can see strange thing: Vista and Windows Server 2008 have the same VersionNT and WindowsBuild numbers.<table border="0" align="center"><tr><td colspan="3" align="center">...</td></tr><tr><td>Windows Vista</td><td>600</td><td>6000</td><td>Not applicable</td></tr><tr><td>Windows Vista Service Pack 1 (SP1)</td><td>600</td><td>6001</td><td>1</td></tr><tr><td>Windows Server 2008</td><td>600</td><td>6001</td><td>Not applicable</td></tr><br /><tr><td colspan="3" align="center">...</td></tr><br /></table><br /><br />So, at this time to determine whether your installer runs on Windows Server 2008 you have to rely on ServicePackLevel property. It is bad, very bad - because when Microsoft will release service pack for the Server 2008 your WIX condition will not be telling truth...<br /><br />Nontheless, here's how to include Windows Server 2008 launch condition into WIX script:<pre><Condition Message='This software requires the Windows Server<br /> 2003 or 2008 to operate correctly'><![CDATA[Installed OR (VersionNT = 502<br /> OR VersionNT = "600" AND MsiNTProductType > 1)]]><br /></Condition></pre><br /><b>Update</b>: In the launch condition above property <a href="http://msdn.microsoft.com/en-us/library/aa370329.aspx">MsiNTProductType</a> was used to differentiate server from workstationVhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com1tag:blogger.com,1999:blog-9941980.post-41101881743444095282008-07-18T09:58:00.006+03:002008-07-18T10:26:00.312+03:00"Using" magic or working with type aliases<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJgZF1lhKplJgUDpV55t4erYKobbjhcToLroJkcJey35_Q-INKmOgrf9MEHAN6IXNkV6vrW-1O5mi1meCiPXCSZcAVQhtNCtQ7VR7XG_-iog5kBFaMgeUZMwxBoU8UhAGklNMi/s1600-h/redirect.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJgZF1lhKplJgUDpV55t4erYKobbjhcToLroJkcJey35_Q-INKmOgrf9MEHAN6IXNkV6vrW-1O5mi1meCiPXCSZcAVQhtNCtQ7VR7XG_-iog5kBFaMgeUZMwxBoU8UhAGklNMi/s400/redirect.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5224250405710961810" /></a><br /><br />Generics in C# allow us specify and construct rather complex types. For instance, we can create a dictionary that maps Id number with the name: <br /><pre><i>Dictionary<int, string> idNameMapping;</i></pre>We can create even more complex data structure, when Id number has to be mapped on another dictionary:<br /><pre><i>Dictionary<int, Dictionary<string, int>> complexIdMapping;</i></pre>Nothing can stop us if we want put another types into dictionary (or any generic type) declaration.<br /><br />You've noticed already that the more types we put into declaration the more clumsier it becomes. I'm not even mentioning typing effort :).<br />Here's how "using" keyword can help us reduce typing and introduce some level of self-documentation for the code.<br /><pre><i>using Item = System.Collections.Generic.Dictionary<string, string>;<br />namespace Sample<br />{<br /> using Records = Dictionary<int, <b>Item</b>>;<br /> public class Controller<br /> {<br /> <b><u>Records recordDictionary = new Records();</u></b><br /> }<br />}</i></pre>Isn't that cool? Instead of typing in a lot of nested types with all that < and > we can get "normal" looking type names.<br /><br />What do I read:<br /><ul><li><a href="http://cooking-together.blogspot.com/2008/04/salad-vitaminous.html">The recipe of a very tasty salad</a></li><li><a href="http://www.shcherbyna.com/?p=11">The case of mysterious BSOD</a></li><li><a href="http://feeds.feedburner.com/~r/PeterRitchiesMvpBlog/~3/338060358/excellent-overview-of-domain-driven-design-and-why-it-helps.aspx">Nice description of Domain Driven Design (DDD)</a></li></ul>Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com8tag:blogger.com,1999:blog-9941980.post-69327730343197518732008-06-27T18:51:00.023+03:002008-06-28T22:26:35.711+03:00The basics of secure data exchange under TCP<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqh0gXLqVT3r69X8R5jkgFkqxlkypK6SuPBXvLnm7heA5-V1OqxTy9FeFbuwrtL8iqEfF-vA4tNOnxE9OfzKEGB0JKT4PfsvVWzyZ-gNPY-IlJZbV_3qyRDghoQq8l-LigpdP3/s1600-h/ssl_lock.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqh0gXLqVT3r69X8R5jkgFkqxlkypK6SuPBXvLnm7heA5-V1OqxTy9FeFbuwrtL8iqEfF-vA4tNOnxE9OfzKEGB0JKT4PfsvVWzyZ-gNPY-IlJZbV_3qyRDghoQq8l-LigpdP3/s400/ssl_lock.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5217014708675493890" /></a><br />Doing data exchange in plain text is very convenient and easy to implement but what can you do to prevent eavesdropping, tampering, and message forgery of the data you send back and forth? Here's where secure communication comes into play. At present the most common secure communication method is using <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security">Transport Layer Security (TLS)</a> or Secure Sockets Layer (SSL). In web context you can see secure data exchange in action when browsing web-sites with <a href="http://en.wikipedia.org/wiki/Https">HTTPS</a> prefix<br /><br />In .NET framework secure communications can be done with <a href="http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx">SslStream</a> class. It can use both TLS and SSL protocols.<br /><br />TLS and SSL for authentication process use <a href="http://en.wikipedia.org/wiki/Public_key_infrastructure">public key infrastructure</a> or PKI. It requires certificates. <br /><br />Here's nice explanation <a href="http://blogs.technet.com/jhoward/archive/2005/02/02/365323.aspx">how to create certificate using makecert utility</a><br /><br />After reading and doing what was said in the above mentioned blogpost we should end up with 2 installed certificates. They're depicted on the picture below.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3CmRE0CUq0yrNNwsiNi5vPjj7j9RdwDVpgcivlDcPNL3ffpM0Fk9zNR3APurbOiXl46PicxVR-W95DkoG05evKs5FCS4c2f319OU2Z9AYamtbDmO9_EpUaREhwTVIArKmhR_y/s1600-h/certificates.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3CmRE0CUq0yrNNwsiNi5vPjj7j9RdwDVpgcivlDcPNL3ffpM0Fk9zNR3APurbOiXl46PicxVR-W95DkoG05evKs5FCS4c2f319OU2Z9AYamtbDmO9_EpUaREhwTVIArKmhR_y/s400/certificates.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216994525155582722" /></a><br />The certificate we'll use will be "vadmyst-enc".<br /><br />SslStream gives you the look and feel of a common .NET stream.<br /><br />So, what are the basic steps to start secure communication with SslStream?<br />Very often the communication happens between server (e.g web server) and client (e.g. browser).<br />Here are the steps for the server side:<ul><li>Start listening on specific address and port</li><br /><li>When connection is accepted wrap obtained NetworkStream with SslStream</li><br /><li>Call SslStream::AuthenticateAsServer</li><br /><li>Start doing I/O (in our case that's basic echo server</li></ul><br />In code it looks like this:<pre><i>TcpListener listener = new TcpListener(ipEndpoint);<br />listener.Start(5);<br />TcpClient tcpClient = listener.AcceptTcpClient();<br /><br />SslStream secureStream = new SslStream(tcpClient.GetStream(), false);<br /> <br />secureStream.AuthenticateAsServer(serverCertificate);<br />//use anonymous delegate for simplicity<br />ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object unused)<br />{<br /> //simple echo server<br /> byte[] tempBuffer = new byte[1024];<br /> int read = 0;<br /> try<br /> {<br /> while ((read = secureStream.Read(tempBuffer, 0, tempBuffer.Length)) > 0)<br /> {<br /> secureStream.Write(tempBuffer, 0, read);<br /> }<br /> }<br /> finally<br /> {<br /> secureStream.Close();<br /> }<br />}), null);</i></pre>serverCertificate is obtained from certificate storage on the local machine:<br /><pre><i>X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);<br />store.Open(OpenFlags.ReadOnly);<br />X509Certificate serverCertificate = null;<br />for (int i = 0; i < store.Certificates.Count; i++)<br />{<br /> serverCertificate = store.Certificates[i];<br /> if (serverCertificate.Subject.Contains("vadmyst-enc"))<br /> break;<br />}<br />store.Close();</i></pre>In this post I'll will not cover usage of client certificates to perform client authentication for the simplicity's sake. Client will only authenticate server.<br />The steps required by the client:<ul><li>Open TCP connection to the remote server</li><br /><li>Wrap obtained NetworkStream with SslStream instance</li><br /><li>Call SslStream::AuthenticateAsClient</li><br /><li>Begin do the I/O</li></ul><br />Source code below demonstrates basic TCP client that transfers data in a secure way.<pre><i>TcpClient client = new TcpClient();<br />client.Connect(endPoint);<br />SslStream sslStream = new SslStream(client.GetStream(), false);<br />sslStream.AuthenticateAsClient("vadmyst-enc");<br /><br />byte[] plaintext = new byte[5*1024 + 35];<br />byte[] validation = new byte[plaintext.Length];<br /> <br />RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();<br />rng.GetNonZeroBytes(plaintext);<br /><br />sslStream.Write(plaintext);<br />sslStream.Flush();<br /><br />int read = 0;<br />int totalRead = 0;<br />while( (read = sslStream.Read(validation, totalRead, <br /> validation.Length - totalRead)) > 0)<br />{<br /> totalRead += read;<br /> if (totalRead == plaintext.Length)<br /> break; //we've received all sent data<br />}<br />//check received data<br />for(int i=0; i < plaintext.Length; i++)<br />{<br /> if ( validation[i] != plaintext[i] )<br /> throw new InvalidDataException("Data is not the same");<br />}<br />sslStream.Close();</i></pre><br />SslStream appeared in .NET framework on version 2.0. As you can see doing secure communications with it is very easy. However, there are number of situations that require additional coding: client authentication using client certificates, using other algorithms when doing secure I/O. I will cover these advanced topics on the next posts. Stay tuned!Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com10tag:blogger.com,1999:blog-9941980.post-76299139333888687332008-06-17T21:28:00.027+03:002008-06-18T23:55:28.558+03:00Hashing in .NET (cryptography related battle tactics)<br/><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRqL8uAYfzaBJeVLWBHrDHeyYY3dLN2NR0ZXbKJs0u2lJzKbL4pu3u7UzYYSC7fUxm9-1z9GInwxtI7F7PMRjsSjKK0JcZE2IHa2fl4HiCwfVJPXpcc9bcTnh5HTaCIQLHXex1/s1600-h/hash1.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRqL8uAYfzaBJeVLWBHrDHeyYY3dLN2NR0ZXbKJs0u2lJzKbL4pu3u7UzYYSC7fUxm9-1z9GInwxtI7F7PMRjsSjKK0JcZE2IHa2fl4HiCwfVJPXpcc9bcTnh5HTaCIQLHXex1/s400/hash1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5213327457949321106" /></a><br />Those who think I'm going to talk about stuff related to <a href="http://en.wikipedia.org/wiki/Hashish">hashish</a> or <a href="http://en.wikipedia.org/wiki/Hash_brown">hash brown</a> are totally not right. (By the way I do like hash brown as well as this great <a href="http://cooking-together.blogspot.com/2008/06/japanese-plum-wine-choya-umeshu-kishu.html">Japanese liquor</a> ;) )<br /><br />I will be talking about hashing that is related to cryptography and security. Hashing can be described as a process of getting small digital "fingerprint" from any kind of data. Those interested in general information can get it <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">here</a>. <br /><br />In .NET, security and cryptography related stuff is located in <i>System.Security.Cryptography</i> namespace. Our hero of the day will be <a href="http://en.wikipedia.org/wiki/SHA-1">SHA1</a> algorithm. .NET class <i>SHA1Managed</i> implements it. According to <a href="http://msdn.microsoft.com/en-us/library/0ss79b2x.aspx">.NET cryptography model</a> this class implements abstract class <i>SHA1</i>. The same, by the way, is valid for other hash algorithms e.g. <i>MD5</i>. They both inherit from <i>HashAlgorithm</i> class. It is very likely if new hashing algorithm is added to the .NET framework it will inherit from HashAlgorithm.<br /><br />There are three ways how to calculate hash value for some data.<br /><ol><li>Use <i>ComputeHash</i> method</li><br /><li>Use <i>TransformBlock/TransformFinalBlock</i> directly</li><br /><li>Use <i>CryptoStream</i></li></ol> <br />I'll show how to use above mentioned approaches. Let's assume we have some application data<pre><i><br />RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();<br />byte[] data = new byte[5 * 4096 + 320];<br />//fill data array with arbitrary data<br />rng.GetNonZeroBytes(data);<br />//initialize HashAlgorithm instance<br />SHA1Managed sha = new SHA1Managed(); </i></pre><br />The first way:<pre><i><br />byte[] hash1 = sha.ComputeHash(data);</i></pre><br />It very straightforward and simple: pass data and get hash output. But this method is not suitable when hash has to be calculated for several byte arrays or when data size is very large (calculate hash value for the binary file). <br />This leads us to the second way:<pre><i><br />int offset = 0;<br />int blockSize = 64;<br />//reset algorithm internal state<br />sha.Initialize(); <br />while (data.Length - offset >= blockSize)<br />{<br /> offset += sha.TransformBlock(data, offset, blockSize, <br /> data, offset);<br />}<br />sha.TransformFinalBlock(data, offset, data.Length - offset);<br />//get calculated hash value<br />byte[] hash2 = sha.Hash;</i></pre><br />This way is much more flexible because: we can reuse HashAlgorithm instance (using <i>Initialize</i> method) and calculate hash value for large data objects.<br />However, to do that we still have to write additional code to read chunks from file and then pass them to <i>TransformBlock</i> method.<br /><br/>Finally, the third way:<pre><i><br />//reuse SHA1Managed instance<br />sha.Initialize(); <br />MemoryStream memoryStream = new MemoryStream(data, false);<br />CryptoStream cryptoStream = new CryptoStream(memoryStream, sha,<br /> CryptoStreamMode.Read);<br />//temporary array used by the CryptoStream to store <br />//data chunk for which hash calculation was performed<br />byte[] temp = new byte[16];<br />while (cryptoStream.Read(temp, 0, temp.Length) > 0) { }<br />cryptoStream.Close();<br />hash3 = sha.Hash;</i></pre><br />Isn't it beautiful? CryptoStream can use any Stream object to read from. Thus calculating hash value for a large file isn't a problem - just pass FileStream to CryptoStream constructor!<br />Under the hood CryptoStream uses TransformBlock/TransformFinalBlock, so the third way is derivative from the second one. <br />CryptoStream links data streams to cryptographic transformations: it can be chained together with any objects that implement Stream, so the streamed output from one object can be fed into the input of another object.<br /><br />The first approach is good when you're calculating hash values from time to time.<br />The second and third are best when large part of your application's operation is connected with hash calculations (like using cryptography in network I/O).Vhttp://www.blogger.com/profile/07384298883237115882noreply@blogger.com0