home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.eterna.com.au
/
2014.06.ftp.eterna.com.au.tar
/
ftp.eterna.com.au
/
lisp
/
rc16.el
< prev
next >
Wrap
Lisp/Scheme
|
1998-04-13
|
2KB
|
85 lines
;; this is GPL'd code.
;; most numbers in here are meant to be 16bits
(defconst xFFFF (- 65536 1))
;; rc16-context functions
(defun rc16-create-context ()
(vector 0 0 (make-vector 65536 0)))
(defsubst rc16-context-x (context)
(aref context 0))
(defsubst rc16-context-y (context)
(aref context 1))
(defsubst rc16-context-state (context)
(aref context 2))
;; sigh. why doesn't elisp have (setf (aref ...))?
(defsubst rc16-context-set-x (context val)
(aset context 0 val))
(defsubst rc16-context-set-y (context val)
(aset context 1 val))
;; set a key, init the context
(defun rc16-set-key (context key)
(let ((state (rc16-context-state context)))
;; init context
(rc16-context-set-x context 0)
(rc16-context-set-y context 0)
(let ((counter 0))
(while (< counter 65536)
(aset state counter counter)
(setq counter (1+ counter))))
;; mix in key
(let ((keyidx 0)
(keylen (length key))
(stateidx 0)
(counter 0)
temp1 temp2)
(while (< counter 65536)
(setq temp1 (aref state counter))
(setq stateidx (logand (+ stateidx temp1 (aref key keyidx)) xFFFF))
(setq temp2 (aref state stateidx))
(aset state stateidx temp1)
(aset state counter temp2)
(setq keyidx (1+ keyidx))
(if (= keyidx keylen) (setq keyidx 0))
(setq counter (1+ counter))))))
(defun rc16-short (context)
(let* ((state (rc16-context-state context))
(x (logand (1+ (rc16-context-x context)) xFFFF))
(sx (aref state x))
(y (logand (+ sx (rc16-context-y context)) xFFFF))
(sy (aref state y)))
(rc16-context-set-x context x)
(rc16-context-set-y context y)
(aset state y sx)
(aset state x sy)
(aref state (logand (+ sx sy) xFFFF))))
(defun rc16-encrypt (context data)
(let* ((cipher (make-string (length data) 0))
(rc16-val (rc16-short context))
(hi-byte (ash rc16-val -8))
(lo-byte (logand rc16-val 255))
(bytes-left 2)
(count 0)
(length (length data)))
(while (< count length)
(aset cipher count (logxor (aref data count) hi-byte))
(setq bytes-left (1- bytes-left))
(if (= bytes-left 0)
(progn
(setq bytes-left 2)
(setq rc16-val (rc16-short context))
(setq hi-byte (ash rc16-val -8))
(setq lo-byte (logand rc16-val 255)))
(setq hi-byte lo-byte))
(setq count (1+ count)))
cipher))