(defun compress (input) (let ((table (make-hash-table :test #'equal))) (dotimes (i 256) (setf (gethash (string (code-char i)) table) i)) (let ((s (string (read-char input)))) (loop for c = (read-char input nil :eof) for sc = (concatenate 'string s (string c)) when (gethash sc table) do (setf s sc) else collect (prog1 (gethash s table) (setf (gethash sc table) (hash-table-count table)) (setf s (string c))) until (eq :eof c))))) (defun decompress (input) (let ((table (make-hash-table :test #'eql))) (dotimes (i 256) (setf (gethash i table) (string (code-char i)))) (with-output-to-string (output) (let ((old-code (gethash (pop input) table))) (princ old-code output) (do ((new-code (pop input) (pop input))) ((null new-code)) (let ((s (gethash new-code table (concatenate 'string old-code (string (char old-code 0)))))) (princ s output) (setf (gethash (hash-table-count table) table) (concatenate 'string old-code (subseq s 0 1))) (setf old-code s)))))))