; fletcher's checksum
(define (readc n)
(if (eof-object? (peek-char)) -1
(let loop ((k n) (v 0))
(if (or (eof-object? (peek-char)) (zero? k)) v
(loop (- k 1) (+ (* v 256) (char->integer (read-char))))))))
(define (fletcher k) ; k in {16, 32, 64}
(let* ((chars (/ k 16))
(base (expt 2 (/ k 2)))
(mod (- base 1)))
(let loop ((i 0) (c 0) (v (readc chars)))
(if (negative? v)
(+ (* c base) i)
(let* ((i (modulo (+ i v) mod))
(c (modulo (+ c i) mod)))
(loop i c (readc chars)))))))
(display (with-input-from-string "abcde"
(lambda () (fletcher 16)))) (newline)
(display (with-input-from-string "abcde"
(lambda () (fletcher 32)))) (newline)
(display (with-input-from-string "abcde"
(lambda () (fletcher 64)))) (newline)