From: ··········@yahoo.com
Subject: crc-16
Date: 
Message-ID: <1145368391.958828.301400@t31g2000cwb.googlegroups.com>
Hello!

Below is a function to calculate CRC-16 (one possible variant). The
question is: surely there is something to be done to make it more fast
(it seems that tail-recursive version is as fast as dotimes/setf, at
least in SBCL)? I'm not sure about correct type declarations, in
particular.

Thank you,
Dmitri


;order = 16
;polynom = #x8005
;direct = t
;crcinit = #xffff
;crcxor = #xffff
;refin = nil
;refout = nil

;contents of this table was shamelessly stolen from SLIB
(defconstant *crc-table*
  (make-array
   256
   :element-type '(unsigned-byte 16)
   :initial-contents
'(0 32773 32783 10 32795 30 20 32785 32819 54 60 32825 40 32813 32807
34 32867 102 108 32873 120 32893 32887 114 80 32853 32863 90 32843 78
68 32833 32963 198 204 32969 216 32989 32983 210 240 33013 33023 250
33003 238 228 32993 160 32933 32943 170 32955 190 180 32945 32915 150
156 32921 136 32909 32903 130 33155 390 396 33161 408 33181 33175 402
432 33205 33215 442 33195 430 420 33185 480 33253 33263 490 33275 510
500 33265 33235 470 476 33241 456 33229 33223 450 320 33093 33103 330
33115 350 340 33105 33139 374 380 33145 360 33133 33127 354 33059 294
300 33065 312 33085 33079 306 272 33045 33055 282 33035 270 260 33025
33539 774 780 33545 792 33565 33559 786 816 33589 33599 826 33579 814
804 33569 864 33637 33647 874 33659 894 884 33649 33619 854 860 33625
840 33613 33607 834 960 33733 33743 970 33755 990 980 33745 33779 1014
1020 33785 1000 33773 33767 994 33699 934 940 33705 952 33725 33719 946
912 33685 33695 922 33675 910 900 33665 640 33413 33423 650 33435 670
660 33425 33459 694 700 33465 680 33453 33447 674 33507 742 748 33513
760 33533 33527 754 720 33493 33503 730 33483 718 708 33473 33347 582
588 33353 600 33373 33367 594 624 33397 33407 634 33387 622 612 33377
544 33317 33327 554 33339 574 564 33329 33299 534 540 33305 520 33293
33287 514)))

;while (len--) crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^
*p++];

(defun update-crc (buf len n crc)
  (declare (type (unsigned-byte 32) crc)
	   (type (simple-array (unsigned-byte 8)) buf)
	   (type fixnum len)
	   (type fixnum n)
	   (optimize speed))
  (if (zerop len) (logand #xffff (logxor crc #xffff))
      (update-crc
       buf (1- len) (1+ n)
       (logxor
	(ash crc 8)
	(aref *crc-table* (logxor (logand #xff (ash crc -8)) (aref buf
n)))))))

(defun crc (buf)
  (update-crc buf (length buf) 0 #xffff))

;should be 20760 = #x5118
(defun test-crc ()
  (let ((a (make-array 9 :element-type '(unsigned-byte 8)
		       :initial-contents '(#x31 #x32 #x33 #x34 #x35 #x36 #x37 #x38
#x39))))

From: Alexey Dejneka
Subject: Re: crc-16
Date: 
Message-ID: <87odyyx6jt.fsf@tochka.ru>
··········@yahoo.com writes:

> Below is a function to calculate CRC-16 (one possible variant). The
> question is: surely there is something to be done to make it more fast
> (it seems that tail-recursive version is as fast as dotimes/setf, at
> least in SBCL)? I'm not sure about correct type declarations, in
> particular.
[...]
> ;while (len--) crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^
> *p++];
>
> (defun update-crc (buf len n crc)
>   (declare (type (unsigned-byte 32) crc)
> 	   (type (simple-array (unsigned-byte 8)) buf)
> 	   (type fixnum len)
> 	   (type fixnum n)
> 	   (optimize speed))
>   (if (zerop len) (logand #xffff (logxor crc #xffff))
>       (update-crc
>        buf (1- len) (1+ n)
>        (logxor
> 	(ash crc 8)
> 	(aref *crc-table* (logxor (logand #xff (ash crc -8)) (aref buf
> n)))))))

If I remove (OPTIMIZE SPEED), the test fails with type error "CRC is
not of type (UNSIGNED-BYTE 32)"; I think you need to strip high bits
of new CRC.

(defun update-crc (buf len n crc)
  (declare (type (unsigned-byte 32) crc)
	   (type (simple-array (unsigned-byte 8)) buf)
	   (type (integer 0 #.(1- most-positive-fixnum)) len n) ; so (1- LEN) and (1+ N) are FIXNUMs
           (optimize speed (safety 0)))
  (if (zerop len) (logand #xffff (logxor crc #xffff))
      (update-crc
       buf (1- len) (1+ n)
       (logand (1- (ash 1 32))
               (logxor
                (ash crc 8)
                (aref *crc-table* (logxor (logand #xff (ash crc -8)) (aref buf n))))))))

-- 
Regards,
Alexey Dejneka

"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer
From: ··········@yahoo.com
Subject: Re: crc-16
Date: 
Message-ID: <1145461742.237410.196800@g10g2000cwb.googlegroups.com>
Thanks!

Dmitri