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