Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Leave Comments, Critiques, and Suggestions Here?

Tango Cryptography and Encoding

The Cryptography and Encoding portion of the Tango library defines interfaces for creating hashes of an arbitrary buffer. Hashes can be used for a variety of purposes. Some are used in serial communications to make sure a buffer hasn’t been corrupted during transmission. Some are used as digital signatures – proof that you are who you say you are. Similarly, some are used as part of an authentication header, such as those defined by IPSEC. In any case, the Tango library provides you with easy to use interfaces to leverage this capability in your own application.

The Tango library encapsulates the basic behaviors of these hash functions with the base class Digest. Once this simple interface is understood you will be able to make use of the following hash algorithms:

  • General
    • CRC 32
  • Secure
    • MD2, MD4, MD5
    • SHA0, SHA1, SHA256, SHA512
    • Tiger

How it works

At the highest level a cipher is capable of generating a hash using the .update(void[]) method. The cipher encapsulate the algorithms used to generate a hash. The Digest base class of all chipher classes let you provide the cipher with new data and give access to the results of the hash operation.

Do it all at once

To create a hash of an entire buffer you use the update method of the Digest class.

Digest digest = new Crc32();

// process the data
digest.update("The quick brown fox jumps over the lazy dog");

Do it as part of a stream

To create a hash of an ongoing stream you use the update method of Digest.

// create an MD5 cipher
Digest digest = new Md5();

// process some data
digest.update("The quick brown fox");

// process some more data
digest.update(" jumps over the lazy dog");

// conclude cipher and produce digest
ubyte[] hash = digest.binaryDigest()

Getting the results

Once you’ve generated your hash you can get the results by using the Digest classes. Digest supports the following two methods:

  • hexDigest() – use this to generate a human readable hex representation of the hash
  • binaryDigest() – use this to generate a binary representation of the hash.

Exceptions

The Tango library defines Exceptions to handle error conditions as required. Digest should not throw any Exception

Putting it all together

The following simple program illustrates what we’ve learned so far. This program will accept a string from the command line and create the requested hash of that string.

module ciphertest;

import tango.io.Console;
import tango.io.digest.Crc32;
import tango.io.digest.Md2;
import tango.io.digest.Md4;
import tango.io.digest.Md5;
import tango.io.digest.Sha0;
import tango.io.digest.Sha1;
import tango.io.digest.Sha256;
import tango.io.digest.Sha512;
import tango.io.digest.Tiger;


// Read string from the command line and generate a hash
//  - The first parameter is the desired hash
//  - The rest of the command line is the string
//
// Format: cipher hash string to hash goes here
// where:
//  'hash' can be crc32, md2, md4, md5, sha0, sha1, sha256, sha512, tiger
//
// Output the resulting digest as a hex string

int main(char[][] args)
{
	Digest digest;
	char[] name = args[1];
	char[] text;
	
	for( int i=2; i<args.length-1; i++ )
	{
		text ~= args[i];
		text ~= " ";
	}
	text ~= args[length-1];

	Cout( "Calculating " ) (name) ( " hash of '") (text) ("'"). newline; 

	try
	{
		digest = MakeADigest(name);
		digest.update(text);
		
		Cout( digest.hexDigest() ).newline;
	}
	catch( Exception e )
	{
		Cout( "Exception occured ") (e.toString()).newline;
	}

	return( 0 );
}

Digest MakeADigest( char[] desiredDigest )
{
	Digest c;

	switch( desiredDigest )
	{
		case "crc32":
			c = new Crc32;
			break;
			
		case "md2":
			c = new Md2;
			break;
			
		case "md4":
			c = new Md4;
			break;
			
		case "md5":
			c = new Md5;
			break;
			
		case "sha0":
			c = new Sha0;
			break;
			
		case "sha1":
			c = new Sha1;
			break;
			
		case "sha256":
			c = new Sha256;
			break;
			
		case "sha512":
			c = new Sha512;
			break;
			
		case "tiger":
			c = new Tiger;
			break;
	}

	return( c );
}