Friday, May 26, 2006

RadioButtonList Javascript Accessible

{

I recently was trying to write some javascript that interacted with the ASP.NET 2.0 RadioButtonList. My first attempts at obtaining a handle to the control via document.getElementById were successful but unsuccessful. Successful in that they weren't giving me a "null" reference back, but unsuccessful in that I was not getting the selected value of the radio buttons.

It turns out the RadioButtonList is rendered as an HTML Table element, with the table getting the corresponding id of the server control and the radio buttons getting id values that had an increment on the end. Their name attribute, which groups them, was the same as the RadioButtonList id.

Simple example: you have a RadioButtonList you give an id of myList. ASP.NET 2.0 renders a table with the id attribute of "myList." You'll have your radio buttons inside, named myList_0, myList_1, and so on. These radio buttons, rendered as getElementsByTagName("input") to get your radio buttons. Test to see which is selected and you're all done. The following function encapsulates that logic, and we've begun reusing it all over the place. The radioList argument should just be the ClientId of your RadioButtonList:

function getRadioSelectedValue(radioList){
var options = radioList.getElementsByTagName('input');
for(i=0;i<options.length;i++){
var opt = options[i];
if(opt.checked){
return opt.value;
}
}
}

}

Tuesday, May 23, 2006

Crypto with Schneier II: One Way Hash

{

My reading of Schneier has continued. He still proves to be a very accomodating writer; consider the following on the "One-Time Pad," a encryption scheme that can be literally unbreakable:

"Many Soviet spy messages to agents were encrypted using one-time pads. These messages are still secure today and will remain that way forever. It doesn't matter how long the supercomputers work on the problem. Even after the aliens from Andromeda land with their massive spaceships and undreamed-of computing power, they will not be able to read the Soviet spy messages encrypted with one-time pads (unless they can also go back in time and get the one-time pads)."
In the second chapter he is discussing the basics of protocols and describes the one-way hash: "a function, mathematical or otherwise, that takes a variable-length input string (pre-image) and converts it to a fixed-length output string. Essentially, a computed hash represents a fixed length byte array that is unique for whatever its input stream was. This is interesting and useful beyond cryptography.

Here's a simple idea from Steve Oualline's book "Wicked Cool Perl Scripts," but implemented in C#: you can compute a hash to check to see if two files are different or the same.

The following code uses the System.IO and System.Security.Cryptography namespaces:

private static bool CompareFiles(string path1, string path2) {
byte[] hash1 = GetMD5Hash(path1);
byte[] hash2 = GetMD5Hash(path2);
for (int i = 0; i < hash1.Length; i++)
{
if (hash1[i] != hash2[i])
{
return false;
}
}
return true;
}

private static byte[] GetMD5Hash(string pth)
{
MD5 hasher = MD5.Create();
byte[] fileBytes = File.ReadAllBytes(pth);
byte[] hash = hasher.ComputeHash(fileBytes);
return hash;
}

I was curious about the performance of this technique - I was originally testing it on 40MB files. I extracted some old database backup files - about 200MB a piece and the comparison took somewhere on the order of 20 seconds. My laptop has a P4 3Ghz with 1GB of RAM. Nice, but not out of the ordinary (especially these days). I've also got suspicions that the speed was not necessarily on the hash computation, but rather on reading out the byte array in the file. I'll test sometime to see...

}

Saturday, May 20, 2006

Personal Projects

{

One of my jedi masters, Darren Neimke, posted the following about having personal projects:

"One of the questions that I always ask is for the applicant to tell me about their favorite personal project that they have going right now. It's a bit of a loaded question I suppose because of how it assumes that they do have a personal project - but that's almost my point. Having a personal project (or more than one) is a trait that is shared by every developer that I respect and so I rate it rather highly."
Interesting, because my latest "personal" project is a tool I called Palantir which let's the developers browse around the database getting schema information much more quickly and effeciently than writing queries like:

select * from information_schema.columns where table_name = 'foo'
or
select * from information_schema.columns where column_name like '%foo%'
It pleasures me to no end when I walk through our work area and see it running on everyone's machines. Usually in the evening I add features that are in response to feedback and what I think will make it more effective of a tool. For example, one screen, devoted to exposing stored procedures, displayed TSQL without syntax highlighting and it became a request. That evening I spent some time with regular expressions and search/replace to get a "pretty" version of procedure definitions into the software.

Invariably the question of why I wrote Palantir comes up, and my response usually a bit of surprise; I thought everyone had little pet projects of software they worked on at home. In fact, most don't. In fact, as I ask around, I find that I'm quite unique in that environment for working on my own stuff at home.

I don't think it necessarily defines me as a better programmer but I know that it's when I write my own stuff that I get that free reign to improve my skills instead of working against a spec and a deadline. My projects give me a chance to do things with regular expressions, backreferences, web services, RSS, XML, and a ton of other things that don't come up in the regular work day.

I'm still considering what to do with Palantir; I want to keep it personal for now so that I can work in some more features and leave it with my personal vision at its core. Then I may work up the courage to put it up on CodePlex or SourceForge.

}

Redirect to Self (ASP.NET)

{

It's easy to reset a page to it's initial state in ASP.NET by redirecting to itself. Here are 3 ways you can do it:

1. Response.Redirect(Request.Path);

In which the path to the request is presented in the following form: /MyApp/MyFile.aspx

2. Response.Redirect(Request.RawUrl);

In which not only is the path exposed, but also any querystring parameters like:
/MyApp/MyFile.aspx?foo=bar

3. Response.Redirect(Request.Url.ToString());

In which not only is the path and querystring parameters exposed, but made available as an absolute reference in the form:
http://MyServer/MyApp/MyFile.aspx?foo=bar

Interestingly enough, if you have a named anchor in the form of <a name=#test, this is not exposed by any of these methods! (You'll see how I know a post or so from now, but suffices to say that you can still get this information from the client side by parsing the window.location object:

alert(window.location);

}

Sunday, May 14, 2006

Crypto with Schneier

{

A coworker loaned me Bruce Schneier's Applied Cryptography. So far it's a very interesting book, and surprisingly readable. I may see if I can work my way through various forms of encryption but translate his samples to C#. Here's a version of a substitution cipher that uses XOR operations in C# (make sure you're using System.Text):

private static string Cipher(byte key, string plainText)
{
byte[] plain = ASCIIEncoding.ASCII.GetBytes(plainText);
byte[] ciph = new byte[plain.Length];
for (int i = 0; i < plain.Length; i++)
{
ciph[i] = (byte)(++key ^ plain[i]);
}

string cipherText = ASCIIEncoding.ASCII.GetString(ciph);
return cipherText;
}

To decrypt, if you have the key:

private static string Decipher(byte key, string cipherText)
{
byte[] ciph = ASCIIEncoding.ASCII.GetBytes(cipherText);
byte[] plain = new byte[ciph.Length];
for (int i = 0; i < ciph.Length; i++)
{
plain[i] = (byte)(++key ^ ciph[i]);
}

string plainText = ASCIIEncoding.ASCII.GetString(plain);
return plainText;
}

Back to my earlier comment on Schneier being readable, his comments on this approach are as follows:

"... the list of software vendors that tout this toy algorithm as being "almost as secure as DES" is staggering... An XOR might keep your kid sister from reading your files, but it won't stop a cryptanalyst for more than a few minutes."


}

Tuesday, May 09, 2006

AAARGH!!!

{

Can you spot the mistake?

string where = PathContext.Value += "\\" + subfolder;

Another night of programming my little mistakes away...

}

Sunday, May 07, 2006

Mac Adverts

{

The most recent Mac advertisements have two guys, side by side: a chubby guy that looks like a dishevled Bill Gates and a young hipster. You can guess who represents the PC and who represents the Mac.

But truth is a little bit more boring than fiction: Macs are vulnerable too. They are expensive too - I was salivating over a MacBook until I priced one out.

Luckily I have an iBook courtesy of the company that I can use. I love it, but I don't have that kind of money - or rather, I'd drop it on a nice Thinkpad or Alienware and keep that extra money I had left over.

I always liked Mac ads (Remember the "switch" campaign?). Who else would get folks like De La Soul and Liza Richardson for an endorsement?

But alas, here I sit in the coffeehouse: a monstrosity of a HP laptop in front of me, upon which I write code in javascript, perl, C#, VB.NET, and C++, running my RSS aggregator, messenger, and of course, of course Firefox amongst other things in the toolbox. And I'm not in a bad suit either.

}