cumtjh 发表于 2011-6-16 14:07:14

[转]alisp文件加密测试.LSP

本帖最后由 cumtjh 于 2011-6-16 14:10 编辑

转自:http://zml84.blog.sohu.com/100535521.html

alisp文件加密测试.LSP
最后修改时间:
--------------------------------------------------------------------------------

;|alisp文件加密的探索

AutoLISP保护文件的格式
    AutoCAD虽然没有提供加密、解密AutoLISP的工具软件,但其本身却可以接收两种格式的LISP文件。
一种是保护格式的;另一种是文本格式的。读入文件后,AutoCAD首先会作出判断,一旦确定文件是保护
格式的,则在加载该程序前,自动将加密文件代码予以还原,然后再读入命令解释器。

下面我们来看看AutoLISP保护格式文件的格式。
----------------------------------------------------------------------------------------
起始地址及终止地址(Bytes)            功能
      0-29                     保护文件的标识字符串计30Bytes,为"AutoCAD PROTECTED LISP file\0x0D\0x0A\0x1A"。
      30                     密码字符,只有一个字节。
      31及以后               已加密的程序码。

注意:前30个字节用户不得改动;
      第30位是密码字母,用户可以任意给定,譬如字母'A';
      第31位起可由附录程序经过加密计算后写入文件。

**加密与解密的原理**
    加密与解密的一个重要工具是"按位异或(^)运算"。
其作用是判断两运算量相应位的值是否"相异",若为异,则为1,否则为0。
即:0^0=0;0^1=1;1^0=1;1^1=0。
因其具有双向转换、还原的能力,故在密码学上得到广泛应用。

让我们来看看:
         A|01000001    8|00111000
      ^y|01111001   ^A|01000001
      -------------------------
         8|00111000    y|01111001

上式中0x41='A'、0x79='y'、0x38='8',
   'A'^'y'='8';'8'^'A'='y';'y'^'8'='A'。
   可以看出按位异或运算具有双向转换、还原的能力。
   AutoCAD在加密、解密时,除了运用上述方法外,另外还使用了一个技巧,就是移位运算,
   将被转换字符的8个位全部左移一位,相当于将该整数乘以2,若最高位是1(移位后>256),
   则将溢出位1移至最末位,否则用0代替末位,这样就保证了加密码与原代码一一对应。

我们假设用函数F表示这一运算过程。
----字符0x96,二进制为10010110,则F(0x96)=F(10010110)=00101101=0x2D。

----我们用下面两个算式,来说明加密、解密的具体过程,式中各符号的意义:
A0->B=A^B;A-B=F(A)^B;A/B=F(A)^B;'||'='='。
各字符均以16进制表示,假设密码字母是'A'(0x41)。

原始程序码为:
(PRINC)
加密过程如下:

----(princ)->28 70 72 69 6E 63 29
      具体过程为:
      1、0x41^0x28=0x69; (按位异或)
      2、F(0x69)=0xD2; (移位运算)
      3、0xD2^0x70=0xA2; (按位异或)
      2、F(0xA2)=0x45; (移位运算)
      3、0x45^0x72=0x37;......

      
----结果(69 A2 37 07 60 A3 6E)


解密过程如下:

----41->   69-A2-37-76-0A-36-ED
----||||||||……(依次类推)

----287072696E6329结果(PRINC)

具体过程为:
1、0x41^0x69=0x28;(字符'(')
2、F(0x69)=0xD2;
3、0xD2^0xA2=0x70;(字符'p')……

|;

;;;========================================================
;;;功能:定义函数,实现 左移一位操作
;|;;测试:(setq lst (vl-string->list "(princ)"))
          (++++ lst65)
|;
(defun F+ (INT / TMP)
    ;;先转换成二进制
    (setq TMP (DEG->BIN INT))
    ;;补齐为 8 位
    (while (< (strlen TMP) 8)
(setq TMP (strcat "0" TMP))
    )
    ;;将首位移动到末位
    (setq TMP (strcat (substr TMP 2 7) (substr TMP 1 1)))
    ;;返回
    (BIN->DEG TMP)
)
;;;========================================================
;;;功能:仿autolisp加密文本
(defun ++++ (LST KEYSCI / LST1 N TMP)
    (setq LST1 '()
    )
    ;;
    (foreach N LST
(progn
      ;;=====================
      ;;异或操作
      (setq TMP (boole 6 KEYSCI N))
      (setq LST1 (cons TMP LST1))

      ;;=====================
      ;;计算下一个 密匙
      (setq KEYSCI (F+ TMP))
)
    )
    ;;返回
    ;;(vl-list->string (reverse LST1))
    (reverse LST1)
)
;;;==============================================================
;;;解密
;;;
(defun ---- (LST KEYSCI / LST1 N TMP)
    (setq LST1 '())
    ;;
    (foreach N LST
(progn
      ;;=====================
      ;;异或操作
      (setq TMP (boole 6 KEYSCI N))
      (setq LST1 (cons TMP LST1))

      ;;=====================
      ;;计算下一个 秘匙
      (setq KEYSCI (F+ N))
)
    )
    ;;返回
    ;;(vl-list->string (reverse LST1))
    (reverse LST1)
)

;;;================
(defun C:TT1 (/ STR LST FF N)
    ;;
    (setq STR "(PRINC \"OK\")")
    (setq LST (vl-string->list STR))
    (setq LST (++++ LST 65))

    ;;写入文件
    (setq FF (open "d:\\test\\test.txt" "w"))
    (foreach N LST
(write-char N FF)
    )
    (close FF)

    (princ)
)

;;;===================
(defun C:TT2 (/ LST FF TMP N)

    (setq LST '())
    ;;读文件
    (setq FF (open "d:\\test\\test.txt" "r"))
    (while (setq TMP (read-char FF))
(setq LST (cons TMP LST))
    )
    (close FF)

    ;;
    (setq LST (---- (reverse LST) 65))
    (princ (vl-list->string LST))
    (princ)
)


;;;===================
;;;加入文件头
(defun C:TT3 (/ LST FF TMP N I)

    (setq LST '())
    ;;读文件
    (setq FF (open "d:\\test\\test.txt" "r"))
    (while (setq TMP (read-char FF))
(setq LST (cons TMP LST))
    )
    (close FF)

    ;;写入文件
    (if(setq FF (open "d:\\test\\test.lsp" "w"))
(progn
      ;;写入文件头
      (foreach N (vl-string->list "AutoCAD PROTECTED LISP file")
    (write-char N FF)
      )
      (write-char 13 FF)
      (write-char 10 FF)
      (write-char 26 FF)
      ;;写入
      (write-char 65 FF)
      ;;写入文件内容
      (setq STR "(alert \"测试成功\")(PRINC \"OK\")")
      (setq LST (vl-string->list STR))
      (setq LST (++++ LST 65))
      (foreach N LST
    (write-char N FF)
      )
)
    )
    (princ)
)
;;;======================================================================================
;;;十进制转化为二进制
;;;例如:(deg->bin 3) 返回"11"
;;;      (deg->bin 5) 返回"101"
(defun DEG->BIN(INT / A B)
    (if(< INT 1)
"0"
(if (= INT 1)
      "1"
      (progn
    (setq A(/ INT 2)
          B(- INT (* A 2))
    )
    (strcat(DEG->BIN A)
      (itoa B)
    )
      )
)
    )
)
;;;======================================================================================
;;;二进制转化为十进制
;;;例如:(bin->deg "11")返回 3
;;;      (deg->bin "101") 返回 5
(defun BIN->DEG(STR)
    (if(<= (strlen STR) 1)
(if (= STR "1")
      1
      0
)
(if (= (substr STR 1 1) "1")
      (+ (expt 2 (- (strlen STR) 1))
         (BIN->DEG (substr STR 2))
      )
      (BIN->DEG (substr STR 2))
)
    )
)

转自:http://zml84.blog.sohu.com/100535521.html

http://bbs.mjtd.com/xwb/images/bgimg/icon_logo.png 该贴已经同步到 cumtjh的微博

LLXXZZ 发表于 2011-6-16 22:16:05

水平太高了.....

skynoon 发表于 2011-6-16 22:44:17

    AutoCAD虽然没有提供加密、解密AutoLISP的工具软件,但其本身却可以接收两种格式的LISP文件。
学习了

haiyunzhou 发表于 2011-12-31 15:46:41

太厉害了 学习了

zyhandw 发表于 2012-12-27 11:44:25

学习了!

无语且听吟 发表于 2012-12-27 15:47:06

看不懂,不会用
用不了

ALXY 发表于 2012-12-28 13:06:12

本帖最后由 ALXY 于 2012-12-28 13:07 编辑

什么用途?如何使用?
页: [1]
查看完整版本: [转]alisp文件加密测试.LSP