找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 690|回复: 2

[每日一码] [风之影]文本BASE64编码解码

[复制链接]
发表于 2017-10-31 12:51:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
近期用到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)

返回
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

解码函数
  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. )


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 6056个

财富等级: 富甲天下

发表于 2017-11-8 12:33:54 | 显示全部楼层
太棒了,这个一定要支持。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 9个

财富等级: 恭喜发财

发表于 2019-1-22 13:58:28 | 显示全部楼层
正需要这个,非常感谢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-25 22:04 , Processed in 0.265819 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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