home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / misc / eexec.shar / eexec.el
Encoding:
Text File  |  1990-03-21  |  3.6 KB  |  102 lines

  1. ;;; Postscript eexec support routines
  2. ;;; LastEditDate "Fri May 19 08:57:31 1989"
  3. ;;; Copyright (c) 1989 by Randal L. Schwartz. All Rights Reserved.
  4. ;;; This code may be freely distributed according to the GNU Public License
  5.  
  6. (defconst hex-string-to-int-table
  7.   (let ((ht (make-vector 256 nil)))    ; nil gives error at + if out-of-range
  8.     (mapcar (function (lambda (pair) (aset ht (nth 0 pair) (nth 1 pair))))
  9.         '((?0 0) (?1 1) (?2 2) (?3 3) (?4 4)
  10.           (?5 5) (?6 6) (?7 7) (?8 8) (?9 9)
  11.           (?a 10) (?b 11) (?c 12) (?d 13) (?e 14) (?f 15)
  12.           (?A 10) (?B 11) (?C 12) (?D 13) (?E 14) (?F 15)))
  13.     ht)
  14.   "Table used by hex-string-to-int.")
  15.  
  16. (defun hex-string-to-int (str)
  17.   "Convert STRING to an integer by parsing it as a hexadecimal number."
  18.   (let ((result 0))
  19.     (mapcar
  20.      (function (lambda (ch)
  21.          (setq result (+ (lsh result 4)
  22.                  (aref hex-string-to-int-table ch)))))
  23.      str)
  24.     result))
  25.  
  26. (defun byte-to-hex-string (byte)
  27.   "Convert BYTE to a two-chararacter string by printing it in hexadecimal."
  28.   (format "%02x" byte))
  29.  
  30. (defconst eexec-const-init (hex-string-to-int "d971")
  31.   "Used by eexec-endecode.  Initial value for state machine.")
  32.  
  33. (defconst eexec-const-mult (hex-string-to-int "ce6d")
  34.   "Used by eexec-endecode.  Multiplier value for state machine.")
  35.  
  36. (defconst eexec-const-add (hex-string-to-int "58bf")
  37.   "Used by eexec-endecode.  Adder value for state machine.")
  38.  
  39. (defconst eexec-const-seed (concat (mapcar 'hex-string-to-int
  40.                        '("17" "ec" "9c" "f3")))
  41.   "Used by eexec-encode.  A known good seed from uartpatch.ps.")
  42.  
  43. (defun eexec-decode ()
  44.   "Decode the first eexec string in the current (possibly narrowed) buffer.
  45. Result is displayed in a temp buffer."
  46.   (interactive)
  47.   (with-output-to-temp-buffer "*eexec-decode-output*"
  48.     (goto-char (point-min))
  49.     (search-forward "eexec")
  50.     (let (str)
  51.       (while (re-search-forward "[ \t\n]*\\([0-9a-fA-F][0-9a-fA-F]\\)" nil t)
  52.     (setq str (cons (buffer-substring (match-beginning 1)
  53.                       (match-end 1))
  54.             str)))
  55.       (setq str (nreverse str))
  56.       (setq str (eexec-endecode (concat (mapcar 'hex-string-to-int str))))
  57.       (princ "Seed: ")
  58.       (princ (apply 'concat (mapcar 'byte-to-hex-string (substring str 0 4))))
  59.       (princ "\nText:\n")
  60.       (princ (substring str 4)))))
  61.  
  62. (defun eexec-encode (start end &optional seed)
  63.   "Encode text from START to END (region if interactive).
  64. Result is displayed in a temp buffer.  If optional SEED is passed as a
  65. four-character string, use it for initial state, else use the known
  66. good seed (the current value of eexec-const-seed)."
  67.   (interactive "r")
  68.   (with-output-to-temp-buffer "*eexec-encode-output*"
  69.     (let ((i 0))
  70.       (princ "currentfile eexec\n")
  71.       (mapcar (function
  72.            (lambda (ch)
  73.          (princ (byte-to-hex-string ch))
  74.          (if (< (setq i (1+ i)) 32) nil
  75.            (princ "\n")
  76.            (setq i 0))))
  77.           (eexec-endecode
  78.            (concat (or (and (stringp seed)
  79.                 (= (length seed) 4)
  80.                 seed)
  81.                eexec-const-seed)
  82.                (buffer-substring start end))
  83.            t))
  84.       (if (> i 0) (princ "\n")))))
  85.  
  86. (defun eexec-endecode (str &optional encode)
  87.   "Decode STR (or encode if optional ENCODE is non-nil), returning result.
  88. If decoding, you will probably want to toss the first four bytes,
  89. but they are returned anyway so that you may reencode a decoded string
  90. for verification."
  91.   (let ((state eexec-const-init) outbyte)
  92.     (concat
  93.      (mapcar
  94.       (function
  95.        (lambda (inbyte)
  96.      (setq outbyte (logxor inbyte (logand (lsh state -8)))
  97.            state (logand 65535 (+ state (if encode outbyte inbyte)))
  98.            state (logand 65535 (* state eexec-const-mult))
  99.            state (logand 65535 (+ state eexec-const-add)))
  100.      outbyte))
  101.       str))))
  102.