Notes from Daily Encounters with Technology RSS 2.0
 
# Saturday, November 24, 2007

In my opinion RSACryptoServiceProvider class is seriously under-documented in MSDN. Since there is also no abundance of examples on the web, I spent more time than I should figuring out how to use it correctly. For future reference I'm listing below the solution to two problems I had.

The maximum byte array length for encrypting without OAEP padding is Modulus size - 11 which is written somewhere in the Encrypt() method documentation. If you pass it a larger array it will return a not so informative Unspecified error. To encrypt a larger chunk of data you have to split it in smaller parts, encrypt them individually and concatenate them back together. You have to do the same when decrypting the data, with the only difference that each part has the size of Modulus in stead of Modulus - 11. To get the modulus size you can use the following piece of code (rsa is an instance of RSACryptoServiceProvider):

RSAParameters rsaParams = rsa.ExportParameters(false);
int modulusSize = rsaParams.Modulus.Length;

Each time you instantiate RSACryptoServiceProvider it generates a new pair of keys. If you want to use existing ones, you can import them by calling:

rsa.FromXmlString(key);

The key parameter is a string with the XML representation of the keys. You can get it by calling the ToXmlString() method once and storing its results. It's only parameter specifies whether to also export the private key. I guess I don't have to remind you that you need the private key only for decryption and that you should always keep it private for the encryption to make any sense at all.

Saturday, November 24, 2007 5:31:53 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET

Is the code below correct? Will inputString and outputString be equal?

string inputString = "The text to compress and decompress";
byte[] inputArray = Encoding.UTF8.GetBytes(inputString);

MemoryStream stream = new MemoryStream();
DeflateStream compressionStream =
    new DeflateStream(stream, CompressionMode.Compress);
compressionStream.Write(inputArray, 0, inputArray.Length);
compressionStream.Flush();

stream.Position = 0;

DeflateStream decompressionStream =
    new DeflateStream(stream, CompressionMode.Decompress);
byte[] outputArray = new byte[inputArray.Length];
decompressionStream.Read(outputArray, 0, outputArray.Length);
string outputString = Encoding.UTF8.GetString(outputArray);

Console.WriteLine(outputString == inputString);
Console.ReadLine();

As it turns out, they won't. The reason for it being that compressionStream.Close() was not called before reading from stream started. Calling compressionStream.Flush() is not enough in this case. I haven't managed to find this documented anywhere but the example in the DeflateStream documentation does it correctly. You can find the fixed code below. Notice the additional last parameter in the first call to the DeflateStream constructor. Without it stream will also be closed when compressionStream gets closed.

string inputString = "The text to compress and decompress";
byte[] inputArray = Encoding.UTF8.GetBytes(inputString);

MemoryStream stream = new MemoryStream();
DeflateStream compressionStream =
    new DeflateStream(stream, CompressionMode.Compress, true);
compressionStream.Write(inputArray, 0, inputArray.Length);
compressionStream.Close();

stream.Position = 0;

DeflateStream decompressionStream =
    new DeflateStream(stream, CompressionMode.Decompress);
byte[] outputArray = new byte[inputArray.Length];
decompressionStream.Read(outputArray, 0, outputArray.Length);
string outputString = Encoding.UTF8.GetString(outputArray);

Console.WriteLine(outputString == inputString);
Console.ReadLine();

Thanks once again to my coworker for suggesting this when I was already running out of ideas.

Saturday, November 24, 2007 4:44:37 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET

Not so long ago I've been called to my boss's office to prevent him losing unsaved work in a PowerPoint presentation. It turned out that when he tried to save the file to a new location the message box with the overwrite warning for some reason didn't render completely and it was impossible to close it. As it turned out at the end I could have just killed the application and restart it, since the AutoRecover feature kicked in and offered a version of the file with all changes applied.

But just to be on the save side I wanted to copy the AutoRecover files to a save location before actually killing the application. But unlike Word or Excel where the location of these files is set in the options, PowerPoint does not have such an option. After some googling I finally stumbled across a page, correctly stating that the files are stored in the %temp% folder and named ppt*.tmp. I decided to publish this info here just in case I need it again.

Saturday, November 24, 2007 3:11:03 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Software | Office
# Tuesday, July 24, 2007

Figuring this out took me much longer than it should. The following line in a batch file will execute a command for each file in a directory:

for %%I in (C:\*.*) do echo %%~nxI

I had to overcome two obstacles to make this work:

  • When including the command in a batch file the % characters must be duplicated in comparison to the syntax for executing the command directly from the command line.
  • The ~nx prefix to the variable name causes only the filename with extension to be used instead of the complete path.
Tuesday, July 24, 2007 4:19:03 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | Scripting

Once you start putting CruiseControl.NET to production use you'll sooner or later encounter the need for custom build tasks. There's only a limited set of them in the package and Executable Task can only do so much. Unfortunately there is not much information available on development of custom tasks. Your best sources will be:

Apart from that I feel obliged to mention a few of the most important points I've come across during the development of a few custom tasks:

  • ThoughtWorks.CruiseControl.Core.Util.ProcessExecutor is a nice little wrapper around System.Diagnostics.Process class you'll end up using quite a lot.
  • You can add your own information to the build log by calling AddTaskResult on the IIntegrationResult instance passed to your ITask.Run method. There are two overloads available: one accepting a System.String and another one accepting ITaskResult to which you can pass a new FileTaskResult instance to quickly include a complete file.
  • If you're doing any checkins to your source control system as a part of the build you should call the MarkStartTime method of your IIntegrationResult instance afterwards to prevent triggering another build of the same project by setting the last build start time after the last checkin time.
  • Make sure you use a unique ReflectorType name for your task. The service will just silently fail to start in case of a duplicate value.

This information should make your first attempts at making your own custom task a little easier.

Tuesday, July 24, 2007 1:57:26 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | Software | CruiseControl
Sponsored Ads

About Me
Twitter
@MladenPrajdic @andrejt use the middle mouse button then 1 day ago
@matevzg @MladenPrajdic Ctrl+F4, as well 1 day ago
Great #DotNetRocks show: Troy Hunt Secures http://t.co/oxClbXLe http://t.co/MiMasNuZ PDF is worth checking out as well http://t.co/z4BHAzqh 3 days ago
Hazards of Converting Binary Data To A String http://t.co/lb8kRSsU via @haacked 5 days ago
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2012, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.