Liomblr RSS

Archive

Jun
19th
Sat
permalink

dgst.exe (‘openssl dgst’-like tool for windows)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;

namespace Dgst
{
    class Program
    {
        static int Main(string[] args)
        {
            // parse arguments
            var format = "hex";
            var algorithm = "SHA256";
            var files = new List<string>();
            foreach (var arg in args)
                if (arg.StartsWith("-") && (arg != "-"))
                    switch (arg)
                    {
                        case "-hex":
                        case "-binary":
                            format = arg.Substring(1);
                            break;
                        case "-sha1":
                        case "-sha256":
                        case "-sha384":
                        case "-sha512":
                        case "-ripemd160":
                            algorithm = arg.Substring(1).ToUpper();
                            break;
                        default:
                            Console.Error.WriteLine("unknown option '{0}'", arg);
                            ShowHelp();
                            return 1;
                    }
                else
                    files.Add(arg);

            // start processing
            var exitCode = 0;

            var hasher = GetHasher(algorithm);
            Debug.Assert(hasher != null, "unexpected algorithm");

            // digest stdin
            if (files.Count < 1)
            {
                var hash = hasher.ComputeHash(Console.OpenStandardInput());
                if (format == "binary")
                    using (var w = new BinaryWriter(Console.OpenStandardOutput()))
                        w.Write(hash);
                else
                {
                    foreach (var b in hash)
                        Console.Write(b.ToString("x2"));
                    Console.WriteLine();
                }
            }

            // digest files
            foreach (var path in files)
            {
                byte[] hash = null;

                // input part
                try
                {
                    using (var f = File.OpenRead(path))
                        hash = hasher.ComputeHash(f);
                }
                catch (FileNotFoundException)
                {
                    exitCode++;
                    Console.Error.WriteLine("{0}: no such file or directory", path);
                }
                catch (Exception e)
                {
                    exitCode++;
                    Console.Error.WriteLine("{0}: {1}", path, e.Message);
                }
                if (hash == null)
                    break;

                // output part
                if (format == "binary")
                    using (var w = new BinaryWriter(Console.OpenStandardOutput()))
                        w.Write(hash);
                else
                {
                    Console.Write("{0}({1})= ", algorithm, path);
                    foreach (var b in hash)
                        Console.Write(b.ToString("x2"));
                    Console.WriteLine();
                }
            }


            return exitCode;
        }

        static HashAlgorithm GetHasher(string name)
        {
            switch (name.ToUpper())
            {
                case "SHA1":
                    return new SHA1Managed();
                case "SHA256":
                    return new SHA256Managed();
                case "SHA384":
                    return new SHA384Managed();
                case "SHA512":
                    return new SHA512Managed();
                case "RIPEMD160":
                    return new RIPEMD160Managed();
                default:
                    return null;
            }
        }

        static void ShowHelp()
        {
            Console.Error.WriteLine("Usage: dgst [OPTION]... FILE...");
            Console.Error.WriteLine();
            Console.Error.WriteLine("options are");
            Console.Error.WriteLine("-hex        output as hex dump (default)");
            Console.Error.WriteLine("-binary     output in binary form");
            Console.Error.WriteLine("-sha1       to use the sha1 message digest algorithm");
            Console.Error.WriteLine("-sha256     to use the sha256 message digest algorithm (default)");
            Console.Error.WriteLine("-sha384     to use the sha384 message digest algorithm");
            Console.Error.WriteLine("-sha512     to use the sha512 message digest algorithm");
            Console.Error.WriteLine("-ripemd160  to use the ripemd160 message digest algorithm");
        }
    }
}