[comp.lang.postscript] GNU Emacs eexec encode/decode routines attached

merlyn@iwarp.intel.com (Randal Schwartz) (07/20/89)

I have been rather sternly warned against distributing the decrypted
version of the chess font from a week ago.  However, the same words
did not seem to apply to my GNU Emacs eexec encode/decode routines.  I
received about 100 requests for it, so here it is.  (Hint: stop
sending requests!)

This is an update of the code I posted a few months ago to comp.emacs
and comp.lang.postscript.  The code works on GNU Emacs version 18.54,
and should probably work all the way back to 18.forty-something, but I
can't be sure.  It's sloooooowwww... but it was a quick hack anyway.
This is more properly done in C or (gack!) Postscript.

To repeat what I said before, and make it perfectly clear: I DID NOT
CRACK THE ALGORITHM.  I used an article posted in comp.lang.postscript
about six months ago from someone in Europe.  I was curious to see if
the numbers were accurate, and implemented them as a quick hack using
the closest roll-your-own tool I had around: GNU Emacs Elisp.  My only
claim to fame is *this* *particular* *implementation*.  I do not know
anything (nor do I have the time or motivation to find out) about any
other "secrets" regarding Postscript, so don't ask.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  eexec.el
# Wrapped by merlyn@iwarpl3 on Thu Jul 20 09:12:48 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'eexec.el' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'eexec.el'\"
else
echo shar: Extracting \"'eexec.el'\" \(3707 characters\)
sed "s/^X//" >'eexec.el' <<'END_OF_FILE'
X;;; Postscript eexec support routines
X;;; LastEditDate "Fri May 19 08:57:31 1989"
X;;; Copyright (c) 1989 by Randal L. Schwartz. All Rights Reserved.
X;;; This code may be freely distributed according to the GNU Public License
X
X(defconst hex-string-to-int-table
X  (let ((ht (make-vector 256 nil)))	; nil gives error at + if out-of-range
X    (mapcar (function (lambda (pair) (aset ht (nth 0 pair) (nth 1 pair))))
X	    '((?0 0) (?1 1) (?2 2) (?3 3) (?4 4)
X	      (?5 5) (?6 6) (?7 7) (?8 8) (?9 9)
X	      (?a 10) (?b 11) (?c 12) (?d 13) (?e 14) (?f 15)
X	      (?A 10) (?B 11) (?C 12) (?D 13) (?E 14) (?F 15)))
X    ht)
X  "Table used by hex-string-to-int.")
X
X(defun hex-string-to-int (str)
X  "Convert STRING to an integer by parsing it as a hexadecimal number."
X  (let ((result 0))
X    (mapcar
X     (function (lambda (ch)
X		 (setq result (+ (lsh result 4)
X				 (aref hex-string-to-int-table ch)))))
X     str)
X    result))
X
X(defun byte-to-hex-string (byte)
X  "Convert BYTE to a two-chararacter string by printing it in hexadecimal."
X  (format "%02x" byte))
X
X(defconst eexec-const-init (hex-string-to-int "d971")
X  "Used by eexec-endecode.  Initial value for state machine.")
X
X(defconst eexec-const-mult (hex-string-to-int "ce6d")
X  "Used by eexec-endecode.  Multiplier value for state machine.")
X
X(defconst eexec-const-add (hex-string-to-int "58bf")
X  "Used by eexec-endecode.  Adder value for state machine.")
X
X(defconst eexec-const-seed (concat (mapcar 'hex-string-to-int
X					   '("17" "ec" "9c" "f3")))
X  "Used by eexec-encode.  A known good seed from uartpatch.ps.")
X
X(defun eexec-decode ()
X  "Decode the first eexec string in the current (possibly narrowed) buffer.
XResult is displayed in a temp buffer."
X  (interactive)
X  (with-output-to-temp-buffer "*eexec-decode-output*"
X    (goto-char (point-min))
X    (search-forward "eexec")
X    (let (str)
X      (while (re-search-forward "[ \t\n]*\\([0-9a-fA-F][0-9a-fA-F]\\)" nil t)
X	(setq str (cons (buffer-substring (match-beginning 1)
X					  (match-end 1))
X			str)))
X      (setq str (nreverse str))
X      (setq str (eexec-endecode (concat (mapcar 'hex-string-to-int str))))
X      (princ "Seed: ")
X      (princ (apply 'concat (mapcar 'byte-to-hex-string (substring str 0 4))))
X      (princ "\nText:\n")
X      (princ (substring str 4)))))
X
X(defun eexec-encode (start end &optional seed)
X  "Encode text from START to END (region if interactive).
XResult is displayed in a temp buffer.  If optional SEED is passed as a
Xfour-character string, use it for initial state, else use the known
Xgood seed (the current value of eexec-const-seed)."
X  (interactive "r")
X  (with-output-to-temp-buffer "*eexec-encode-output*"
X    (let ((i 0))
X      (princ "currentfile eexec\n")
X      (mapcar (function
X	       (lambda (ch)
X		 (princ (byte-to-hex-string ch))
X		 (if (< (setq i (1+ i)) 32) nil
X		   (princ "\n")
X		   (setq i 0))))
X	      (eexec-endecode
X	       (concat (or (and (stringp seed)
X				(= (length seed) 4)
X				seed)
X			   eexec-const-seed)
X		       (buffer-substring start end))
X	       t))
X      (if (> i 0) (princ "\n")))))
X
X(defun eexec-endecode (str &optional encode)
X  "Decode STR (or encode if optional ENCODE is non-nil), returning result.
XIf decoding, you will probably want to toss the first four bytes,
Xbut they are returned anyway so that you may reencode a decoded string
Xfor verification."
X  (let ((state eexec-const-init) outbyte)
X    (concat
X     (mapcar
X      (function
X       (lambda (inbyte)
X	 (setq outbyte (logxor inbyte (logand (lsh state -8)))
X	       state (logand 65535 (+ state (if encode outbyte inbyte)))
X	       state (logand 65535 (* state eexec-const-mult))
X	       state (logand 65535 (+ state eexec-const-add)))
X	 outbyte))
X      str))))
END_OF_FILE
if test 3707 -ne `wc -c <'eexec.el'`; then
    echo shar: \"'eexec.el'\" unpacked with wrong size!
fi
# end of 'eexec.el'
fi
echo shar: End of shell archive.
exit 0
-- 
/== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\
| on contract to Intel, Hillsboro, Oregon, USA                           |
| merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn	         |
\== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/