I am working on implementing a remote backup solution - basically something I can script that will securely transfer some files over the Internet to a remote server. As yet I have not made my mind up on the transfer method but it will most likely be either FTPS, FTP (but sending encrypted data) or using a VPN to secure the transmission.
Either way I have some large files to backup - 20GB database backup files, that sort of thing and so I am going to use Delta Compression (of which I am a fan and will no doubt blog about some other time). I will use my favourite DC tool, xdelta.
As I said, I want to script the backup - I like DOS style batch files (I have yet to get in to Power Shell, but it's on my list of things to do - it's a long list). I am primarily a software developer and so creating new command line applications to help me create a scriptable solution is not a problem, but I like to create lots of small tools that I can reuse again and again for different tasks rather than code the whole job in a single executable that will have no other use.
As well as transmitting a "binary difference" or "patch" file, I also want to send over the signature of the most up-to-date copy of the file I am backing up, so that when the patch is applied at the other end to the older file I can compare signatures to make sure my file is intact and matches. The easiest way to do this is to use a Hash algorithm (also known as a Message Digest).
So I have built myself a very small, very simple command line application that will calculate the hash of any file and write it to an INI file (you might consider INI files a little old fashioned, a little Windows 3.1 - but they remain an excellent way to store application settings and I would always choose an INI file over the registry, and Delphi has excellent classes for working with INI files). That way I can also transmit the INI file (which due to it's nature could be reused and so contain many hashes for many files).
Today then, HashFile was conceived, incubated and born.
Usage:
HashFile <switches> [ini_file] [file_to_hash]
<switches>
-h{algorithm}: can be one of the following: MD2, MD4, MD5, SHA1, RIPEMD160, default is MD5.
-s{ini section}: set the name of the ini section header, default is HASH_FILE.
-k{ini key}: set the name of the key in the ini file, default is the file name of the file being hashed.
Assuming I am happy with the default values, I could just run:
HashFile D:\Temp\Test.ini D:\Temp\Untitled.jpg
The contents of Test.ini look like this:
[HASH_FILE]
Untitled.jpg=3b7101d7d93f80dc7ac0135830d5ccd3
You can use 0, 1, 2 or all 3 switches. Here is an example of using them all:
HashFile -hSHA1 -sMY_SECTION -kMY_VALUE D:\Temp\Test.ini D:\Temp\Untitled.jpg
Because Test.ini already exists from the last example the new content is appended (nothing is overwritten because the values are different) and it now looks like this:
[HASH_FILE]
Untitled.jpg=3b7101d7d93f80dc7ac0135830d5ccd3
[MY_SECTION]
MY_VALUE=64f280a904f7dc729ee8ea9ba932dbfe136d2c10
That's it. It will do for now, but I am already planning on expanding it:
- Allowing the user to pass multiple files to be hashed instead of just one at a time (which is why I made sure that the file to be hashed was the very last parameter - you will just add more).
- Adding another switch that will direct the output to be a XML file rather than an INI file.