Updated version to 2.1.
[salza2.git] / crc32.lisp
blobee37258a0ae9e650c71c7f51166de1c4686dca8c
1 ;;;
2 ;;; Copyright (c) 2007 Zachary Beane, All Rights Reserved
3 ;;;
4 ;;; Redistribution and use in source and binary forms, with or without
5 ;;; modification, are permitted provided that the following conditions
6 ;;; are met:
7 ;;;
8 ;;; * Redistributions of source code must retain the above copyright
9 ;;; notice, this list of conditions and the following disclaimer.
10 ;;;
11 ;;; * Redistributions in binary form must reproduce the above
12 ;;; copyright notice, this list of conditions and the following
13 ;;; disclaimer in the documentation and/or other materials
14 ;;; provided with the distribution.
15 ;;;
16 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
17 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 ;;;
29 (in-package #:salza2)
31 (defun crc32-table ()
32 (let ((table (make-array 512 :element-type '(unsigned-byte 16))))
33 (dotimes (n 256 table)
34 (let ((c n))
35 (declare (type (unsigned-byte 32) c))
36 (dotimes (k 8)
37 (if (logbitp 0 c)
38 (setf c (logxor #xEDB88320 (ash c -1)))
39 (setf c (ash c -1)))
40 (setf (aref table (ash n 1)) (ldb (byte 16 16) c)
41 (aref table (1+ (ash n 1))) (ldb (byte 16 0) c)))))))
43 (defvar *crc32-table* (crc32-table))
45 (defun crc32 (high low buf start count)
46 (declare (type (unsigned-byte 16) high low)
47 (type array-index start count)
48 (type octet-vector buf)
49 (optimize speed))
50 (let ((i start)
51 (table *crc32-table*))
52 (declare (type array-index i)
53 (type (simple-array (unsigned-byte 16) (*)) table))
54 (dotimes (j count (values high low))
55 (let ((index (logxor (logand low #xFF) (aref buf i))))
56 (declare (type (integer 0 255) index))
57 (let ((high-index (ash index 1))
58 (low-index (1+ (ash index 1))))
59 (declare (type (integer 0 511) high-index low-index))
60 (let ((t-high (aref table high-index))
61 (t-low (aref table low-index)))
62 (declare (type (unsigned-byte 16) t-high t-low))
63 (incf i)
64 (setf low (logxor (ash (logand high #xFF) 8)
65 (ash low -8)
66 t-low))
67 (setf high (logxor (ash high -8) t-high))))))))
69 ;;; Class interface
71 (defclass crc32-checksum (checksum)
72 ((low
73 :initarg :low
74 :accessor low)
75 (high
76 :initarg :high
77 :accessor high))
78 (:default-initargs
79 :low #xFFFF
80 :high #xFFFF))
82 (defmethod update ((checksum crc32-checksum) input start count)
83 (setf (values (high checksum)
84 (low checksum))
85 (crc32 (high checksum) (low checksum)
86 input start count)))
88 (defmethod result ((checksum crc32-checksum))
89 (+ (ash (logxor (high checksum) #xFFFF) 16)
90 (logxor (low checksum) #xFFFF)))
92 (defmethod result-octets ((checksum crc32-checksum))
93 (ub32-octets (result checksum)))
95 (defmethod reset ((checksum crc32-checksum))
96 (setf (low checksum) #xFFFF
97 (high checksum) #xFFFF))