[armedbear-cvs] r13330 - trunk/abcl/tools
mevenson at common-lisp.net
mevenson at common-lisp.net
Wed Jun 15 09:26:03 UTC 2011
Author: mevenson
Date: Wed Jun 15 02:26:03 2011
New Revision: 13330
Log:
Create API for message digests via generic function DIGEST.
DIGEST-PATH will return the ascii encoding of the SHA-256
cryptographic hash of the resource at PATH as fast as possible.
Added:
trunk/abcl/tools/abcl-tools.asd
Modified:
trunk/abcl/tools/digest.lisp
Added: trunk/abcl/tools/abcl-tools.asd
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/abcl/tools/abcl-tools.asd Wed Jun 15 02:26:03 2011 (r13330)
@@ -0,0 +1,9 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP -*-
+(require 'asdf)
+(in-package :asdf)
+
+(defsystem :abcl-tools :version "0.1.0" :components
+ ((:module src :pathname "" :components
+ ((:file "digest")
+ (:file "code-grapher")))))
+
\ No newline at end of file
Modified: trunk/abcl/tools/digest.lisp
==============================================================================
--- trunk/abcl/tools/digest.lisp Tue Jun 14 23:26:32 2011 (r13329)
+++ trunk/abcl/tools/digest.lisp Wed Jun 15 02:26:03 2011 (r13330)
@@ -1,8 +1,22 @@
+;;;; Cryptographic message digest calculation with ABCL with different implementations.
+;;;;
+;;;; Mark <evenson.not.org at gmail.com>
+;;;;
+
+(in-package :cl-user)
+
+;;; API
+(defgeneric digest (url algorithim &optional (digest 'sha-256))
+ (:documentation "Digest byte based resource at URL with ALGORITHIM."))
+(defun digest-path (path) (ascii-digest (digest path 'nio 'sha-256)))
+
(defvar *digest-types*
- '((:sha-1 . "SHA-1")
- (:sha-256 . "SHA-256")
- (:sha-512 . "SHA-512")))
+ '((sha-1 . "SHA-1")
+ (sha-256 . "SHA-256")
+ (sha-512 . "SHA-512"))
+ "Normalization of cryptographic digest naming.")
+;;; Implementation
(defconstant +byte-buffer-rewind+
(jmethod "java.nio.ByteBuffer" "rewind"))
(defconstant +byte-buffer-get+
@@ -10,24 +24,15 @@
(defconstant +digest-update+
(jmethod "java.security.MessageDigest" "update" "[B" "int" "int"))
-;;; needs ABCL svn > r13328 and is probably not faster than the NIO version
+(defmethod digest ((url t) (algorithim (eql 'nio)) &optional (digest 'sha-256))
+ "Calculate digest with default of :SHA-256 pathname specified by URL.
+Returns an array of JVM primitive signed 8-bit bytes.
-(defun digest-file-1 (path &key (digest :sha-256))
- (let* ((digest-type (cdr (assoc digest *digest-types*)))
- (digest (jstatic "getInstance" "java.security.MessageDigest" digest-type))
- (buffer (make-array 8192 :element-type '(unsigned-byte 8))))
- (with-open-file (input path :element-type '(unsigned-byte 8))
- (loop :for bytes = (read-sequence buffer input)
- :while (plusp bytes)
- :do
- (jcall-raw "update" digest
- (jnew-array-from-array "byte" buffer) 0 bytes))
- (jcall "digest" digest))))
+*DIGEST-TYPES* controls the allowable digest types."
-(defun digest-file (path &key (digest :sha-256))
(let* ((digest-type (cdr (assoc digest *digest-types*)))
(digest (jstatic "getInstance" "java.security.MessageDigest" digest-type))
- (namestring (if (pathnamep path) (namestring path) path))
+ (namestring (if (pathnamep url) (namestring url) url))
(file-input-stream (jnew "java.io.FileInputStream" namestring))
(channel (jcall "getChannel" file-input-stream))
(length 8192)
@@ -42,27 +47,55 @@
(jcall +digest-update+ digest array 0 read))
(jcall "digest" digest)))
+(defmethod digest ((url pathname) (algorithim (eql 'lisp)) &optional (digest 'sha-256))
+ "Compute digest of URL in Lisp where possible.
+
+Currently much slower that using 'nio.
+
+Needs ABCL svn > r13328."
+
+ (let* ((digest-type (cdr (assoc digest *digest-types*)))
+ (digest (jstatic "getInstance" "java.security.MessageDigest" digest-type))
+ (buffer (make-array 8192 :element-type '(unsigned-byte 8))))
+ (with-open-file (input url :element-type '(unsigned-byte 8))
+ (loop
+ :for
+ bytes = (read-sequence buffer input)
+ :while
+ (plusp bytes)
+ :do
+ (jcall-raw "update" digest
+ (jnew-array-from-array "byte" buffer) 0 bytes))
+ (jcall "digest" digest))))
+
(defun ascii-digest (digest)
(format nil "~{~X~}"
(mapcar (lambda (b) (if (< b 0) (+ 256 b) b))
(java::list-from-jarray digest))))
(defun benchmark (directory)
- (let (results start-1 end-1 start-2 end-2)
+ "For a given DIRECTORY containing a wildcard of files, run the benchmark tests."
+ (let (results)
+ (flet ((benchmark (task)
+ (let (start end result)
+ (psetf start (get-internal-run-time)
+ result (push (funcall task) result)
+ end (get-internal-run-time))
+ (nconc result (list start (- end start))))))
(dolist (entry (directory directory))
- (setf start-1 (get-internal-run-time))
- (digest-file-1 entry)
- (setf end-1 (get-internal-run-time))
- (setf start-2 (get-internal-run-time))
- (digest-file entry)
- (setf end-2 (get-internal-run-time))
- (let ((result (list entry (- end-1 start-1) (- end-2 start-2))))
- (format t "~&~A" result)
- (push result results)))
- results))
-
-
-
-
-
-
+ (let ((result
+ (list
+ (list 'nio (benchmark (lambda () (digest entry 'nio))))
+ (list 'lisp (benchmark (lambda () (digest entry 'lisp)))))))
+ (format t "~&~{~A~&~A~}" result)
+ (push result results))))))
+
+;;; Deprecated
+(setf (symbol-function 'digest-file-1) #'digest)
+
+;;; Test
+
+#|
+(benchmark "/usr/local/bin/*") ;; unix
+(benchmark "c:/*") ;; win32
+|#
More information about the armedbear-cvs
mailing list