Back to index

tetex-bin  3.0
md5main.c
Go to the documentation of this file.
00001 /*
00002   Copyright (C) 2002 Aladdin Enterprises.  All rights reserved.
00003 
00004   This software is provided 'as-is', without any express or implied
00005   warranty.  In no event will the authors be held liable for any damages
00006   arising from the use of this software.
00007 
00008   Permission is granted to anyone to use this software for any purpose,
00009   including commercial applications, and to alter it and redistribute it
00010   freely, subject to the following restrictions:
00011 
00012   1. The origin of this software must not be misrepresented; you must not
00013      claim that you wrote the original software. If you use this software
00014      in a product, an acknowledgment in the product documentation would be
00015      appreciated but is not required.
00016   2. Altered source versions must be plainly marked as such, and must not be
00017      misrepresented as being the original software.
00018   3. This notice may not be removed or altered from any source distribution.
00019 
00020   L. Peter Deutsch
00021   ghost@aladdin.com
00022 
00023  */
00024 /* $Id: md5main.c,v 1.1 2002/04/13 19:20:28 lpd Exp $ */
00025 /*
00026   Independent implementation of MD5 (RFC 1321).
00027 
00028   This code implements the MD5 Algorithm defined in RFC 1321, whose
00029   text is available at
00030        http://www.ietf.org/rfc/rfc1321.txt
00031   The code is derived from the text of the RFC, including the test suite
00032   (section A.5) but excluding the rest of Appendix A.  It does not include
00033   any code or documentation that is identified in the RFC as being
00034   copyrighted.
00035 
00036   The original and principal author of md5.c is L. Peter Deutsch
00037   <ghost@aladdin.com>.  Other authors are noted in the change history
00038   that follows (in reverse chronological order):
00039 
00040   2002-04-13 lpd Splits off main program into a separate file, md5main.c.
00041  */
00042 
00043 #include "md5.h"
00044 #include <math.h>
00045 #include <stdio.h>
00046 #include <string.h>
00047 
00048 /*
00049  * This file builds an executable that performs various functions related
00050  * to the MD5 library.  Typical compilation:
00051  *     gcc -o md5main -lm md5main.c md5.c
00052  */
00053 static const char *const usage = "\
00054 Usage:\n\
00055     md5main --test          # run the self-test (A.5 of RFC 1321)\n\
00056     md5main --t-values             # print the T values for the library\n\
00057     md5main --version              # print the version of the package\n\
00058 ";
00059 static const char *const version = "2002-04-13";
00060 
00061 /* Run the self-test. */
00062 static int
00063 do_test(void)
00064 {
00065     static const char *const test[7*2] = {
00066        "", "d41d8cd98f00b204e9800998ecf8427e",
00067        "a", "0cc175b9c0f1b6a831c399e269772661",
00068        "abc", "900150983cd24fb0d6963f7d28e17f72",
00069        "message digest", "f96b697d7cb7938d525a2f31aaf161d0",
00070        "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b",
00071        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
00072                             "d174ab98d277d9f5a5611c2c9f419d9f",
00073        "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a"
00074     };
00075     int i;
00076     int status = 0;
00077 
00078     for (i = 0; i < 7*2; i += 2) {
00079        md5_state_t state;
00080        md5_byte_t digest[16];
00081        char hex_output[16*2 + 1];
00082        int di;
00083 
00084        md5_init(&state);
00085        md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
00086        md5_finish(&state, digest);
00087        for (di = 0; di < 16; ++di)
00088            sprintf(hex_output + di * 2, "%02x", digest[di]);
00089        if (strcmp(hex_output, test[i + 1])) {
00090            printf("MD5 (\"%s\") = ", test[i]);
00091            puts(hex_output);
00092            printf("**** ERROR, should be: %s\n", test[i + 1]);
00093            status = 1;
00094        }
00095     }
00096     if (status == 0)
00097        puts("md5 self-test completed successfully.");
00098     return status;
00099 }
00100 
00101 /* Print the T values. */
00102 static int
00103 do_t_values(void)
00104 {
00105     int i;
00106     for (i = 1; i <= 64; ++i) {
00107        unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
00108 
00109        /*
00110         * The following nonsense is only to avoid compiler warnings about
00111         * "integer constant is unsigned in ANSI C, signed with -traditional".
00112         */
00113        if (v >> 31) {
00114            printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i,
00115                  v, (unsigned long)(unsigned int)(~v));
00116        } else {
00117            printf("#define T%d    0x%08lx\n", i, v);
00118        }
00119     }
00120     return 0;
00121 }
00122 
00123 /* Main program */
00124 int
00125 main(int argc, char *argv[])
00126 {
00127     if (argc == 2) {
00128        if (!strcmp(argv[1], "--test"))
00129            return do_test();
00130        if (!strcmp(argv[1], "--t-values"))
00131            return do_t_values();
00132        if (!strcmp(argv[1], "--version")) {
00133            puts(version);
00134            return 0;
00135        }
00136     }
00137     puts(usage);
00138     return 0;
00139 }