comparison lisp/gnus/md5.el @ 108:360340f9fd5f r20-1b6

Import from CVS: tag r20-1b6
author cvs
date Mon, 13 Aug 2007 09:18:39 +0200
parents ec9a17fef872
children 1a767b41a199
comparison
equal deleted inserted replaced
107:523141596bda 108:360340f9fd5f
9 ;;; Details: ------------------------------------------------------------------ 9 ;;; Details: ------------------------------------------------------------------
10 10
11 ;; This is a direct translation into Emacs LISP of the reference C 11 ;; This is a direct translation into Emacs LISP of the reference C
12 ;; implementation of the MD5 Message-Digest Algorithm written by RSA 12 ;; implementation of the MD5 Message-Digest Algorithm written by RSA
13 ;; Data Security, Inc. 13 ;; Data Security, Inc.
14 ;; 14 ;;
15 ;; The algorithm takes a message (that is, a string of bytes) and 15 ;; The algorithm takes a message (that is, a string of bytes) and
16 ;; computes a 16-byte checksum or "digest" for the message. This digest 16 ;; computes a 16-byte checksum or "digest" for the message. This digest
17 ;; is supposed to be cryptographically strong in the sense that if you 17 ;; is supposed to be cryptographically strong in the sense that if you
18 ;; are given a 16-byte digest D, then there is no easier way to 18 ;; are given a 16-byte digest D, then there is no easier way to
19 ;; construct a message whose digest is D than to exhaustively search the 19 ;; construct a message whose digest is D than to exhaustively search the
20 ;; space of messages. However, the robustness of the algorithm has not 20 ;; space of messages. However, the robustness of the algorithm has not
21 ;; been proven, and a similar algorithm (MD4) was shown to be unsound, 21 ;; been proven, and a similar algorithm (MD4) was shown to be unsound,
22 ;; so treat with caution! 22 ;; so treat with caution!
23 ;; 23 ;;
24 ;; The C algorithm uses 32-bit integers; because GNU Emacs 24 ;; The C algorithm uses 32-bit integers; because GNU Emacs
25 ;; implementations provide 28-bit integers (with 24-bit integers on 25 ;; implementations provide 28-bit integers (with 24-bit integers on
26 ;; versions prior to 19.29), the code represents a 32-bit integer as the 26 ;; versions prior to 19.29), the code represents a 32-bit integer as the
27 ;; cons of two 16-bit integers. The most significant word is stored in 27 ;; cons of two 16-bit integers. The most significant word is stored in
28 ;; the car and the least significant in the cdr. The algorithm requires 28 ;; the car and the least significant in the cdr. The algorithm requires
31 31
32 ;;; Usage: -------------------------------------------------------------------- 32 ;;; Usage: --------------------------------------------------------------------
33 33
34 ;; To compute the MD5 Message Digest for a message M (represented as a 34 ;; To compute the MD5 Message Digest for a message M (represented as a
35 ;; string or as a vector of bytes), call 35 ;; string or as a vector of bytes), call
36 ;; 36 ;;
37 ;; (md5-encode M) 37 ;; (md5-encode M)
38 ;; 38 ;;
39 ;; which returns the message digest as a vector of 16 bytes. If you 39 ;; which returns the message digest as a vector of 16 bytes. If you
40 ;; need to supply the message in pieces M1, M2, ... Mn, then call 40 ;; need to supply the message in pieces M1, M2, ... Mn, then call
41 ;; 41 ;;
42 ;; (md5-init) 42 ;; (md5-init)
43 ;; (md5-update M1) 43 ;; (md5-update M1)
44 ;; (md5-update M2) 44 ;; (md5-update M2)
45 ;; ... 45 ;; ...
46 ;; (md5-update Mn) 46 ;; (md5-update Mn)
48 48
49 ;;; Copyright and licence: ---------------------------------------------------- 49 ;;; Copyright and licence: ----------------------------------------------------
50 50
51 ;; Copyright (C) 1995 by Gareth Rees 51 ;; Copyright (C) 1995 by Gareth Rees
52 ;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm 52 ;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
53 ;; 53 ;;
54 ;; md5.el is free software; you can redistribute it and/or modify it 54 ;; md5.el is free software; you can redistribute it and/or modify it
55 ;; under the terms of the GNU General Public License as published by the 55 ;; under the terms of the GNU General Public License as published by the
56 ;; Free Software Foundation; either version 2, or (at your option) any 56 ;; Free Software Foundation; either version 2, or (at your option) any
57 ;; later version. 57 ;; later version.
58 ;; 58 ;;
59 ;; md5.el is distributed in the hope that it will be useful, but WITHOUT 59 ;; md5.el is distributed in the hope that it will be useful, but WITHOUT
60 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 60 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
61 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 61 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
62 ;; for more details. 62 ;; for more details.
63 ;; 63 ;;
64 ;; The original copyright notice is given below, as required by the 64 ;; The original copyright notice is given below, as required by the
65 ;; licence for the original code. This code is distributed under *both* 65 ;; licence for the original code. This code is distributed under *both*
66 ;; RSA's original licence and the GNU General Public Licence. (There 66 ;; RSA's original licence and the GNU General Public Licence. (There
67 ;; should be no problems, as the former is more liberal than the 67 ;; should be no problems, as the former is more liberal than the
68 ;; latter). 68 ;; latter).
153 153
154 ;; FF, GG, HH and II are basic MD5 functions, providing transformations 154 ;; FF, GG, HH and II are basic MD5 functions, providing transformations
155 ;; for rounds 1, 2, 3 and 4 respectively. Each function follows this 155 ;; for rounds 1, 2, 3 and 4 respectively. Each function follows this
156 ;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x 156 ;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x
157 ;; by y bits to the left): 157 ;; by y bits to the left):
158 ;; 158 ;;
159 ;; FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b 159 ;; FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b
160 ;; 160 ;;
161 ;; so we use the macro `md5-make-step' to construct each one. The 161 ;; so we use the macro `md5-make-step' to construct each one. The
162 ;; helper functions F, G, H and I operate on 16-bit numbers; the full 162 ;; helper functions F, G, H and I operate on 16-bit numbers; the full
163 ;; operation splits its inputs, operates on the halves separately and 163 ;; operation splits its inputs, operates on the halves separately and
164 ;; then puts the results together. 164 ;; then puts the results together.
165 165
367 367
368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
369 ;;; Here begins the merger with the XEmacs API and the md5.el from the URL 369 ;;; Here begins the merger with the XEmacs API and the md5.el from the URL
370 ;;; package. Courtesy wmperry@spry.com 370 ;;; package. Courtesy wmperry@spry.com
371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
372 (defun md5 (object &optional start end) 372 (eval-and-compile
373 "Return the MD5 (a secure message digest algorithm) of an object. 373 (unless (fboundp 'md5)
374 (defun md5 (object &optional start end)
375 "Return the MD5 (a secure message digest algorithm) of an object.
374 OBJECT is either a string or a buffer. 376 OBJECT is either a string or a buffer.
375 Optional arguments START and END denote buffer positions for computing the 377 Optional arguments START and END denote buffer positions for computing the
376 hash of a portion of OBJECT." 378 hash of a portion of OBJECT."
377 (let ((buffer nil)) 379 (let ((buffer nil))
378 (unwind-protect 380 (unwind-protect
379 (save-excursion 381 (save-excursion
380 (setq buffer (generate-new-buffer " *md5-work*")) 382 (setq buffer (generate-new-buffer " *md5-work*"))
381 (set-buffer buffer) 383 (set-buffer buffer)
382 (cond 384 (cond
383 ((bufferp object) 385 ((bufferp object)
384 (insert-buffer-substring object start end)) 386 (insert-buffer-substring object start end))
385 ((stringp object) 387 ((stringp object)
386 (insert (if (or start end) 388 (insert (if (or start end)
387 (substring object start end) 389 (substring object start end)
388 object))) 390 object)))
389 (t nil)) 391 (t nil))
390 (prog1 392 (prog1
391 (if (<= (point-max) md5-maximum-internal-length) 393 (if (<= (point-max) md5-maximum-internal-length)
392 (mapconcat 394 (mapconcat
393 (function (lambda (node) (format "%02x" node))) 395 (function (lambda (node) (format "%02x" node)))
394 (md5-encode (buffer-string)) 396 (md5-encode (buffer-string))
395 "") 397 "")
396 (call-process-region (point-min) (point-max) 398 (call-process-region (point-min) (point-max)
397 (or shell-file-name "/bin/sh") 399 (or shell-file-name "/bin/sh")
398 t buffer nil 400 t buffer nil
399 "-c" md5-program) 401 "-c" md5-program)
400 ;; MD5 digest is 32 chars long 402 ;; MD5 digest is 32 chars long
401 ;; mddriver adds a newline to make neaten output for tty 403 ;; mddriver adds a newline to make neaten output for tty
402 ;; viewing, make sure we leave it behind. 404 ;; viewing, make sure we leave it behind.
403 (buffer-substring (point-min) (+ (point-min) 32))) 405 (buffer-substring (point-min) (+ (point-min) 32)))
404 (kill-buffer buffer))) 406 (kill-buffer buffer)))
405 (and buffer (kill-buffer buffer) nil)))) 407 (and buffer (kill-buffer buffer) nil))))))
406 408
407 (provide 'md5) 409 (provide 'md5)
408 410
409 ;;; md5.el ends here ---------------------------------------------------------- 411 ;;; md5.el ends here ----------------------------------------------------------