md5.c revision 32074
1/*
2 * $Id: md5.c,v 1.10 1997/02/22 14:32:37 peter Exp $
3 *
4 * Derived from:
5 */
6
7/*
8 * MDDRIVER.C - test driver for MD2, MD4 and MD5
9 */
10
11/*
12 *  Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
13 *  rights reserved.
14 *
15 *  RSA Data Security, Inc. makes no representations concerning either
16 *  the merchantability of this software or the suitability of this
17 *  software for any particular purpose. It is provided "as is"
18 *  without express or implied warranty of any kind.
19 *
20 *  These notices must be retained in any copies of any part of this
21 *  documentation and/or software.
22 */
23
24#include <sys/types.h>
25#include <md5.h>
26
27#include <stdio.h>
28#include <string.h>
29#include <time.h>
30#include <unistd.h>
31
32#include "global.h"
33
34/*
35 * Length of test block, number of test blocks.
36 */
37#define TEST_BLOCK_LEN 1000
38#define TEST_BLOCK_COUNT 1000
39
40static void MDString PROTO_LIST((char *));
41static void MDTimeTrial PROTO_LIST((void));
42static void MDTestSuite PROTO_LIST((void));
43static void MDFilter PROTO_LIST((int));
44static void usage PROTO_LIST((void));
45
46/* Main driver.
47
48Arguments (may be any combination):
49  -sstring - digests string
50  -t       - runs time trial
51  -x       - runs test script
52  filename - digests file
53  (none)   - digests standard input
54 */
55int
56main(argc, argv)
57	int     argc;
58	char   *argv[];
59{
60	int     i;
61	char   *p;
62	char	buf[33];
63
64	if (argc > 1) {
65		while ((i = getopt(argc, argv, "ps:tx")) != EOF) {
66			switch (i) {
67			case 'p':
68				MDFilter(1);
69				break;
70			case 's':
71				MDString(optarg);
72				break;
73			case 't':
74				MDTimeTrial();
75				break;
76			case 'x':
77				MDTestSuite();
78				break;
79			default:
80				usage();
81			}
82		}
83		while (optind < argc) {
84			p = MD5File(argv[optind], buf);
85			if (!p)
86				perror(argv[optind]);
87			else
88				printf("MD5 (%s) = %s\n", argv[optind], p);
89			optind++;
90		}
91	} else
92		MDFilter(0);
93
94	return (0);
95}
96/*
97 * Digests a string and prints the result.
98 */
99static void
100MDString(string)
101	char   *string;
102{
103	unsigned int len = strlen(string);
104	char buf[33];
105
106	printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf));
107}
108/*
109 * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
110 */
111static void
112MDTimeTrial()
113{
114	MD5_CTX context;
115	time_t  endTime, startTime;
116	unsigned char block[TEST_BLOCK_LEN];
117	unsigned int i;
118	char   *p, buf[33];
119
120	printf
121	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
122	    TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
123
124	/* Initialize block */
125	for (i = 0; i < TEST_BLOCK_LEN; i++)
126		block[i] = (unsigned char) (i & 0xff);
127
128	/* Start timer */
129	time(&startTime);
130
131	/* Digest blocks */
132	MD5Init(&context);
133	for (i = 0; i < TEST_BLOCK_COUNT; i++)
134		MD5Update(&context, block, TEST_BLOCK_LEN);
135	p = MD5End(&context,buf);
136
137	/* Stop timer */
138	time(&endTime);
139
140	printf(" done\n");
141	printf("Digest = %s", p);
142	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
143	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
144	 * Anderson, ric@Artisoft.COM.) */
145	printf
146	    ("Speed = %ld bytes/second\n",
147	    (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
148}
149/*
150 * Digests a reference suite of strings and prints the results.
151 */
152static void
153MDTestSuite()
154{
155	printf("MD5 test suite:\n");
156
157	MDString("");
158	MDString("a");
159	MDString("abc");
160	MDString("message digest");
161	MDString("abcdefghijklmnopqrstuvwxyz");
162	MDString
163	    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
164	MDString
165	    ("1234567890123456789012345678901234567890\
1661234567890123456789012345678901234567890");
167}
168
169/*
170 * Digests the standard input and prints the result.
171 */
172static void
173MDFilter(int pipe)
174{
175	MD5_CTX context;
176	int     len;
177	unsigned char buffer[BUFSIZ];
178	char buf[33];
179
180	MD5Init(&context);
181	while ((len = fread(buffer, 1, BUFSIZ, stdin))) {
182		if(pipe && (len != fwrite(buffer, 1, len, stdout))) {
183			perror("stdout");
184			exit(1);
185		}
186		MD5Update(&context, buffer, len);
187	}
188	printf("%s\n", MD5End(&context,buf));
189}
190
191/*
192 * Displays a usage summary.
193 */
194static void
195usage(void)
196{
197	(void)fprintf(stderr,
198		"usage: md5 [-ptx] [-s string] [file ...]\n");
199	exit(1);
200}
201