明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3139|回复: 12

[源码] [风之影]文本BASE64编码解码

[复制链接]
发表于 2017-10-21 23:24 | 显示全部楼层 |阅读模式
本帖最后由 cabinsummer 于 2017-10-31 12:51 编辑

近期用到BASE64编码,用XMLDOM加ADODB.Stream的方法没试成功。百度了一些LISP方法,觉得效率太低,所以自己写了一个文本BASE64编码的函数。数字lsh和logand确实比十进制转二进制再查表快不知多少倍,顺便用了一下gcd函数。
因为LISP不能直接操作二进制数据,所以只好先拿文本来试试。函数如下:
  1. (defun Base64Encode (str / strlst n i map ad y base64 a b c s)
  2.   (setq map "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
  3.   (setq strlst (vl-string->list str))
  4.   (setq n (/ (length strlst) 3))
  5.   (setq ad "")
  6.   (if (= (gcd (length strlst) 3) 1)(setq n (1+ n)))
  7.   (setq i 0)
  8.   (repeat n
  9.     (if (< i (length strlst))(setq a (append a (list (nth i strlst)))))
  10.     (if (< (1+ i) (length strlst))(setq b (append b (list (nth (1+ i) strlst)))))
  11.     (if (< (+ i 2) (length strlst))(setq c (append c (list (nth (+ i 2) strlst)))))
  12.     (setq i (+ i 3))
  13.   )
  14.   (if (< (length b)(length a))(setq ad (strcat ad "=") b (append b (list 0))))
  15.   (if (< (length c)(length a))(setq ad (strcat ad "=") c (append c (list 0))))
  16.   (setq s (apply 'strcat (mapcar '(lambda(x)(substr map (1+ x) 1)) (foreach x (mapcar '(lambda(x)(alter34 x)) (mapcar '(lambda(x y z)(list x y z)) a b c)) (setq y (append y x))))))
  17.   (setq s (strcat (substr s 1 (- (strlen s)(strlen ad))) ad))
  18.   (setq base64 "" i 1)
  19.   (if (zerop (rem (strlen s) 76))(/ (strlen s) 76)(1+ (/ (strlen s) 76)))
  20.   (repeat (if (zerop (rem (strlen s) 76))(/ (strlen s) 76)(1+ (/ (strlen s) 76)))
  21.     (setq base64 (strcat base64 "\n" (substr s i 76)) i (+ i 76))
  22.   )
  23.   (substr base64 2)
  24. )

  25. (defun alter34 (lst3 / n1 n2 n3 m1 m2 m3 m4)
  26.   (setq n1 (car lst3) n2 (cadr lst3) n3 (last lst3))
  27.   (setq m1 (lsh n1 -2) m2 (+ (lsh (logand n1 3) 4) (lsh (logand n2 240) -4)) m3 (+ (lsh (logand n2 15) 2) (lsh (logand n3 192) -6)) m4 (logand n3 63))
  28.   (list m1 m2 m3 m4)
  29. )


测试:
  1. (setq txt "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.")
  2. (base64encode txt)

结果已经把\n显示为换行
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

Base64解码函数
  1. (defun Base64Decode (str / map ad s1 i lst a b c d ss)
  2.   (setq map "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
  3.   (setq lst (vl-remove-if '(lambda(x)(= x 10)) (vl-string->list str)))
  4.   (if (member 61 lst)
  5.     (setq ad (length (member 61 lst)))
  6.     (setq ad 0)
  7.   )
  8.   (setq lst (mapcar '(lambda(x)(vl-string-position (ascii x) map)) (mapcar 'chr (subst 65 61 lst))))
  9.   (setq i 0)
  10.   (repeat (/ (length lst) 4)
  11.     (setq a (append a (list (nth i lst))))
  12.     (setq b (append b (list (nth (1+ i) lst))))
  13.     (setq c (append c (list (nth (+ i 2) lst))))
  14.     (setq d (append d (list (nth (+ i 3) lst))))
  15.     (setq i (+ i 4))
  16.   )
  17.   (setq ss (apply 'strcat (mapcar 'vl-list->string (mapcar '(lambda(u)(alter43 u)) (mapcar '(lambda(w x y z)(list w x y z)) a b c d)))))
  18.   (substr ss 1 (- (strlen ss) ad))
  19. )

  20. (defun alter43 (lst4 / n1 n2 n3 n4 m1 m2 m3)
  21.   (setq n1 (car lst4))
  22.   (setq n2 (cadr lst4))
  23.   (setq n3 (caddr lst4))
  24.   (setq n4 (last lst4))
  25.   (setq m1 (+ (lsh n1 2)(lsh (logand n2 48) -4)))
  26.   (setq m2 (+ (lsh (logand n2 15) 4) (lsh (logand n3 60) -2)))
  27.   (setq m3 (+ (lsh (logand n3 3) 6) n4))
  28.   (list m1 m2 m3)
  29. )
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2020-1-8 00:12 | 显示全部楼层
  1. (defun $str->base64$
  2.     (str / code *SCR DATA)
  3.           ;大于20kb后速度很慢
  4.   (if (and STR (= (type str) 'str))
  5.     (if  (or
  6.     *SCR
  7.     (setq
  8.       *SCR (vlax-create-object
  9.        "Aec32BitAppServer.AecScriptControl.1"
  10.      )
  11.     )
  12.     (setq *SCR (vlax-create-object "ScriptControl"))
  13.   )
  14.       (progn
  15.   (vlax-put *SCR 'language "VBScript")
  16.   (setq code
  17.          "Base64Encode(str)
  18.   Function Base64Encode(byVal s)
  19.   b=\"\"
  20.   h=\"\"
  21.   bs=\"\"
  22.   n=0  
  23.   For i=1 to len(s)
  24.   h=h & StrToHex(Mid(s, i, 1))  
  25.   Next
  26.   For i=1 to len(h) Step 2  
  27.   b=b & HexToBin(Mid(h,i,2))
  28.   Next
  29.   For i=1 to len(b) Step 6
  30.   n=n+1
  31.   t=(Mid(b,i,6))
  32.   If len(t) <> 6 Then  
  33.   t=Left(t & \"000000\", 6)
  34.   End If
  35.   bs=bs & BinToChr(BinToDec(t))
  36.   Next
  37.   m=n Mod 4
  38.   If m =2 Then  
  39.   bs=bs & \"==\"
  40.   End If
  41.   If m =3 Then
  42.   bs=bs & \"=\"  
  43.   End If
  44.   Base64Encode=bs  
  45.   End Function
  46.   Function StrToHex(byVal s)  
  47.   h=\"\"
  48.   c=\"&H\" & Hex(AscW(s))  
  49.   If c >= &H0001 And c <= &H007F Then  
  50.   h=h & Hex(c)
  51.   ElseIf c > &H07FF Then  
  52.   h=h & Hex(&HE0 Or (c\\(2^12) And &H0F))
  53.   h=h & Hex(&H80 Or (c\\(2^6) And &H3F))
  54.   h=h & Hex(&H80 Or (c\\(2^0) And &H3F))
  55.   Else
  56.   h=h & Hex(&HC0 Or (c\\(2^6) And &H1F))
  57.   h=h & Hex(&H80 Or (c\\(2^0) And &H3F))
  58.   End If
  59.   StrToHex=h
  60.   End Function
  61.   Function HexToBin(byVal s)
  62.   b=\"\"
  63.   dec=Clng(\"&H\" & s)
  64.   Do While dec > 0
  65.   b=dec Mod 2 & b
  66.   dec=dec \\ 2
  67.   Loop
  68.   b=Right(\"00000000\" & CStr(b), 8)
  69.   HexToBin=b
  70.   End Function
  71.   Function BinToDec(byVal s)
  72.   d=0
  73.   For i=6 to 1 Step -1
  74.   d=d + CInt(Mid(s, i, 1)) * 2 ^ (6 - i)
  75.   Next
  76.   BinToDec=d
  77.   End Function
  78.   Function BinToChr(byVal s)
  79.   dic=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
  80.   BinToChr=Mid(dic, s+1, 1)
  81.   End Function"
  82.   )
  83.   (if (and
  84.         (not (vl-catch-all-error-p
  85.          (vl-catch-all-apply
  86.            'vlax-invoke
  87.            (list *SCR
  88.            'addcode
  89.            code
  90.            )
  91.          )
  92.        )
  93.         )
  94.         (not (vl-catch-all-error-p
  95.          (setq str (vl-catch-all-apply
  96.          'vlax-invoke
  97.          (list *SCR
  98.                'run
  99.                "Base64Encode"
  100.                str
  101.          )
  102.              )
  103.          )
  104.        )
  105.         )
  106.       )
  107.     ()
  108.     (setq str nil)
  109.   )
  110.   (if *SCR
  111.     (vlax-release-object *SCR)
  112.   )
  113.       )
  114.       (progn (print "调用VBScript转码失败,组件未找到"))
  115.     )
  116.   )
  117.   str
  118. )

发表于 2017-10-24 09:31 | 显示全部楼层
本帖最后由 Gu_xl 于 2017-10-24 09:34 编辑

XLRX函数库提供相应的Base64功能如下:
XLRX-String-Base64Encode
   功能:将指定的字串编码为Base64字符串
      语法: (XLRX-String-Base64Encode String)
   参数:        String 字符串
   返回值: 成功返回Base64字符串 ,否则返回nil
XLRX-String-Base64Decode
   功能:将指定的Base64字符串解码
   语法: (XLRX-String-Base64Decode String)   
   参数:        String Base64字符串
   返回值: 成功返回字符串 ,否则返回nil
XLRX-File-Base64Encode
   语法1: (XLRX-File-Base64Encode Filename [Flag])

     功能:将指定二进制文件编码为Base64编码字串或Base64编码字串表
     参数:   Filename 指定的文件名称。
             Flag 可选参数,存在且不为nil时,返回Base64编码字串表,否则返回Base64编码字串
      返回值: 成功返回Base64编码字串或Base64编码字串表,否则返回nil
     语法2: (XLRX-File-Base64Encode Filename SaveName [Flag])
     功能:将指定二进制文件编码为Base64编码文本文件
     参数:          Filename 指定的文件名称。
      SaveName 要保存的文本文件名称
      Flag 可选参数,存在且不为nil时,文本文件保存为Base64编码字串表,否则文本文件中直接Base64编码字串      
         返回值: 成功返回T,否则返回nil
XLRX-File-Base64Decode
   功能:将Base64编码字串转为二进制文件保存

   语法: (XLRX-File-Base64Decode strBase64 Filename)   
        参数:          strBase64 Base64编码字串
      Filename 保存的二进制文件名称。      
         返回值: 成功返回T,否则返回nil
另外,二进制文件和文本文件转换提供如下函数:
XLRX-File-Binary2Text
   功能:将二进制文件输出为十六进制文本文件

   语法: (xlrx-File-Binary2Text BinaryFileName TextFileName)
    参数:           BinaryFileName 二进制文件名称   
    TextFileName 输出的文本文件名称   
   返回值: 成功返回T,否则返回nil
XLRX-File-Binary2TextStr
   功能:将二进制文件输出为十六进制文本字符串

   语法: (xlrx-File-Binary2TextStr BinaryFileName)
    参数:           BinaryFileName 二进制文件名称   
   返回值: 成功返回十六进制文本字符串,否则返回nil
XLRX-File-TextStr2Binary
   功能:将由函数XLRX-File-Binary2TextStr输出的十六进制文本字符串还原成二进制文件

   语法: (xlrx-File-TextStr2Binary TextBuf BinaryFileName)
     参数:           TextBuf 十六进制文本字符串
     BinaryFileName 二进制文件名称   
   返回值: 成功返回T,否则返回nil
XLRX-File-Text2Binary
   功能:将由函数XLRX-File-Binary2Text输出的十六进制文本文件还原成二进制文件

   语法: (xlrx-File-Text2Binary TextFileName BinaryFileName)   
   参数:           TextFileName 文本文件名称
     BinaryFileName 二进制文件名称
     返回值: 成功返回T,否则返回nil


上述两组函数,均可实现任意二进制文件打包到vlx中去!


 楼主| 发表于 2017-10-23 22:01 来自手机 | 显示全部楼层
elitefish 发表于 2017-10-23 15:10
用自己的码表可以实现简单的加密

这个完全可以,但是这样加密是有缺陷的,只要拿到一组足够长明文和密文,就破解了。
发表于 2017-10-21 23:53 | 显示全部楼层
"地板“http://bbs.xdcad.net/forum.php?m ... F2%B0%FC&page=1
功能是不是一样的呢?
 楼主| 发表于 2017-10-22 05:17 来自手机 | 显示全部楼层
不是为了打包。用vbs功能会更强大一些,因为vbs可以处理二进制,我这个纯lisp的,就只能处理文本了。
发表于 2017-10-23 09:02 | 显示全部楼层
回帖是一种美德!感谢楼主的无私分享 谢谢
发表于 2017-10-23 13:55 | 显示全部楼层
好高达上,base64是用来做什么的?给扫一下盲
发表于 2017-10-23 15:10 | 显示全部楼层
用自己的码表可以实现简单的加密
发表于 2018-1-9 20:29 | 显示全部楼层
回帖是一种美德!感谢楼主的无私分享 谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-3 16:04 , Processed in 0.364357 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表