File: adler32.lisp

package info (click to toggle)
ironclad 0.11-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 992 kB
  • ctags: 433
  • sloc: lisp: 12,279; makefile: 47
file content (51 lines) | stat: -rw-r--r-- 1,788 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
;;;; adler32.lisp - computing adler32 checksums (rfc1950) of a byte array

(in-package :crypto)

;;; smallest prime < 65536
(defconstant adler32-modulo 65521)

(defstruct (adler32-state
             (:constructor make-adler32-state)
             (:copier copy-adler32-state))
  (s1 1 :type fixnum)
  (s2 0 :type fixnum)
  (length 0 :type fixnum))

(defun update-adler32-state (state sequence &key (start 0) (end (length sequence)))
  (declare (type adler32-state state)
           (type (simple-array (unsigned-byte 8) (*)) sequence)
           (type index start end))
  (let ((s1 (adler32-state-s1 state))
        (s2 (adler32-state-s2 state))
        (length (adler32-state-length state)))
    (declare (type fixnum s1 s2 length))
    ;; This loop could be unrolled for better performance.
    (do ((i start (1+ i)))
        ((= i end)
         (setf (adler32-state-s1 state) (logand s1 #xffff)
               (adler32-state-s2 state) (logand s2 #xffff)
               (adler32-state-length state) length)
         state)
      (setf s1 (+ s1 (aref sequence i))
            s2 (+ s2 s1))
      (incf length)
      (when (= length 5552)
        (setf s1 (truncate s1 adler32-modulo)
              s2 (truncate s2 adler32-modulo)
              length 0)))))

(defun finalize-adler32-state (state)
  (declare (type adler32-state state))
  (let ((digest (make-array 4 :element-type '(unsigned-byte 8))))
    (store-ub32-be digest 0 (logior (ash (adler32-state-s2 state) 16)
                                    (adler32-state-s1 state)))
    digest))

(defdigest adler32
  (:digest-length 4)
  (:state-type adler32-state)
  (:creation-function make-adler32-state)
  (:copy-function copy-adler32-state)
  (:update-function update-adler32-state)
  (:finalize-function finalize-adler32-state))