中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 批处理编码解码文件(Base64 算法)
« [1] [2] »
作者:
标题: 批处理编码解码文件(Base64 算法) 上一主题 | 下一主题
0401
中级用户

带走



积分 435
发帖 88
注册 2005-9-24
状态 离线
『楼 主』:  批处理编码解码文件(Base64 算法)


:: Base64.cmd Beta -- Base64 编码解码 01/28/2007 By 0401

@echo off
setlocal enabledelayedexpansion
set op=
set Key=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
set hexstr=0 1 2 3 4 5 6 7 8 9 A B C D E F
set d=0
for %%i in (%hexstr%) do set d!d!=%%i&set/a d+=1

if "%~1"=="" goto :help
if "%~1"=="/?" goto :help
for %%i in (d D e E h H) do (
        if "%~1"=="/%%i" call :arg%%i %*
        if exist "%~1" (
                if exist "%~1\" set error=Sorry,不支持对一个目录进行 Base64 编码。& goto :error
                set op=encode
                set infile=%~sf1
        )
)
if defined error goto :error
if defined op goto :%op%
set error=无效的参数或文件名:%1。& goto :error


:arge
set op=encode
:argd
if not defined op set op=decode
set infile=%~sf2
if not defined infile set error=没有指定输入文件。& exit/b
if not exist "%infile%" set error=找不到指定文件:%infile%。& exit/b
set outfile=%~f3
goto :eof
:argh
set op=help
goto :eof
:error
echo %error%
exit/b


goto :encode

s 文件大小
l 文件加上100H f子命令填充内存的长度。
c 只用来计算第一次编码的时间
k 判断 c1 c2 c3
w 每行生成几组4个字节的编码字符,默认18
q 判断等于w时输出一行编码字符串
n 用来过滤掉重复的字节

:encode
>nul (chcp 437&graftabl 936)
cls

for %%i in (%infile%) do set s=%%~zi
if %s% equ 0 exit/b
if %s% gtr 65535 set error=编码失败,文件大小上限为 64KB。& goto :error

set/p=编码初始化中,请稍等。<nul
set of=B64ENC
set/p=<nul>"%~dp0%of%"
set/a l=s+255
call :d2h %l%
set l=%hex%
call :d2h %s%
echo exit|%comspec%/kprompt f cs:100 l %l% 0A$_r cx$_%hex%$_n a.t1$_w$_f cs:100 l %l% 0D$_n b.t1$_w$_q$_|debug>nul

fc/b %infile% a.t1|find ": ">.t1
fc/b %infile% b.t1|find ": ">>.t1
sort .t1>.t2

call :time t1

set n=
set c=0
set k=0
set q=0
set w=18
for /f "tokens=1,2" %%i in (.t2) do (
        if not "!n!"=="%%i" (
                set/a d=0x%%j
                set/a k+=1
                if !k! equ 1 set c1=!d!
                if !k! equ 2 set c2=!d!
                if !k! equ 3 set c3=!d!
                if !k! equ 3 (
                        set/a e1="c1>>2!
                        set/a e2="((c1&3)<<4)|(c2>>4)"
                        set/a e3="((c2&15)<<2)|(c3>>6)"
                        set/a e4="c3&63"
                        call set b64=!b64!%%Key:~!e1!,1%%%%Key:~!e2!,1%%%%Key:~!e3!,1%%%%Key:~!e4!,1%%
                        set/a q+=1
                        if !q! equ !w! (
                                echo !b64!>>"%~dp0%of%"
                                set b64=
                                set q=0
                                if !c! equ 0 (
                                        set/a c+=1
                                        call :time t2
                                        set/a t="s/(w*3)*(t2-t1)/100"
                                        echo 估计剩余时间 !t! 秒。
                                )
                                set/p=#<nul
                        )
                        set k=0
                )
        )
        set n=%%i
)

if !k! equ 1 (
        set/a e1="c1>>2"
        set/a e2="(c1&3)<<4"
        call set b64=!b64!%%Key:~!e1!,1%%%%Key:~!e2!,1%%==
)

if !k! equ 2 (
        set/a e1="c1>>2"
        set/a e2="((c1&3)<<4)|(c2>>4)"
        set/a e3="((c2&15)<<2)"
        call set b64=!b64!%%Key:~!e1!,1%%%%Key:~!e2!,1%%%%Key:~!e3!,1%%=
)

echo.
if defined b64 echo %b64%>>"%~dp0%of%"
if defined outfile move/y "%~dp0%of%" "%outfile%"
echo 编码完成。
del a.t1 b.t1 .t1 .t2
::chcp 936>nul
exit/b



goto :decode

k 用来判断 e1 e2 e3 e4
e e子命令每行写入的字节数,默认是24个字节生成一个debug的e子命令。可自行修改(3<=e<=24)
s1 转换后的HEX串
m 判断s1是否包含指定的字节数
q 每行有(几个字节*3)被编码
cx 表示文件大小(字节),每运算一次加3,因为每4个字节解码为3个字节
cs e子命令在cs段地址内的多少偏移处写入
v1 每行字节数加2(2个字节既回车与换行)
v2 行数
v3 q的3倍 用来判断处理第1行所用时间

:decode
>nul (chcp 437&graftabl 936)
cls
set/p=解码中<nul

set/p=<nul>dbg.src
set/p v1=<%infile%
set/p=%v1%<nul>.t1
for %%i in (.t1) do set/a q=%%~zi/4&set v1=%%~zi+2&del .t1
for %%i in (%infile%) do set/a v2=%%~zi/v1+1
set/a v3="q*3"

call :time t1
set e=24
set k=1
set m=1
set cx=0
set cs=256
for /f %%i in (%infile%) do (
        set str=%%i
        for /l %%j in (1,1,%q%) do (
                if not defined str if %%j lss %q% goto :decend
                for /l %%k in (0,1,3) do (
                        for /l %%l in (0,1,64) do (
                                if "!str:~%%k,1!"=="!Key:~%%l,1!" (
                                        if !k! equ 1 set e1=%%l
                                        if !k! equ 2 set e2=%%l
                                        if !k! equ 3 set e3=%%l
                                        if !k! equ 4 set e4=%%l
                                        set/a k+=1
                                )
                        )
                )
                set/a c1="(e1<<2)|(e2>>4)"
                call :d2h !c1!
                set s1=!s1! !hex!
                set/a c2="((e2&15)<<4)|(e3>>2)"
                call :d2h !c2!
                set s1=!s1! !hex!
                set/a c3="((e3&3)<<6)|e4"
                call :d2h !c3!
                set s1=!s1! !hex!
               
                set k=1
                set/a cx+=3
                set/a m=cx"%%"e
                if !m! equ 0 (
                        if !e4! equ 64 (
                                set/a cx-=1
                                set s1=!s1:~0,-3!
                                if !e3! equ 64 (
                                        set/a cx-=1
                                        set s1=!s1:~0,-3!
                                )
                        )
                        call :d2h !cs!
                        echo e !hex! !s1! >>dbg.src
                        set/a cs+=e
                        set s1=
                )
                set str=!str:~4!
        )
        if !cx! equ %v3% (
                call :time t2
                set/a ts=t2-t1
                set/a t="ts*v2/100"
                echo ,文件共 !v2! 行,每行用时约 !ts! 毫秒,估计剩余时间 !t! 秒。
        )
        set/p=#<nul
)
:decend
if defined s1 (
        if %e4% equ 64 (
                set/a cx-=1
                set s1=!s1:~0,-3!
                if %e3% equ 64 (
                        set/a cx-=1
                        set s1=!s1:~0,-3!
                )
        )
        call :d2h %cs%
        echo e !hex! !s1! >>dbg.src
)

call :d2h %cx%
(echo r cx
echo %hex%
echo n b64dec
echo w
echo q) >>dbg.src

echo.
debug<dbg.src>nul
if defined outfile move/y b64dec "%outfile%"
echo 解码完成。
del dbg.src
::chcp 936>nul
exit/b


:time
for /f "tokens=1-4 delims=:." %%i in ("%time%") do (
        set/a time1="%%i*360000"
        set/a time2="(1%%j-100)*6000"
        set/a time3="(1%%k-100)*100"
        set/a time4="1%%l-100"
)
set/a %~1=time1+time2+time3+time4
exit/b

:d2h
set/a d=%1
set hex=
if %d% equ 0 set hex=00&exit/b
if %d% gtr 255 (set c=4) else (set c=2)
for /l %%i in (1,1,%c%) do (
        set/a td=d"&"15
        set/a d">>="4
        call set hex=%%d!td!%%!hex!
)
exit/b


:help
for /f "tokens=1 delims=:" %%i in ('findstr/n /c:"=help=" "%~f0"') do more +%%i "%~f0">con & goto :eof

Base64 Encode n Decode Beta By 0401

Usage:
Base64 [/e] filename1 [filename2]
       [/d filename1] [filename2]
       [/h]
    /e        Base64 编码操作,处理文件大小上限 64KB
    /d        Base64 解码操作
    filename1 输入文件名
    filename2 输出文件名
              /e 缺省输出文件名为 B64ENC
              /d 缺省输出文件名为 B64DEC
    /h        帮助
大家帮忙测试,如果没问题可能也就不更新了,直接把 Beta 去掉。效率是有点低,大家将就下。编码采用 Herbert Kleebauer 大牛的结构。
关于支持的文件只能到64KB,一来效率太低,没必要支持大文件了。我这机子本身配置就不高,解码一个1KB的就得20几秒。二来文件大于64KB,用debug来生成文件时其高地址位在BX寄存器中,我怕麻烦,不再修改了。真需要编码大文件,先用RAR分卷压缩吧。或者您可以自己改个,当然别忘了拿出来与大家分享^_^
编码文件最简单的办法就是直接将文件拖到该批处理文件上。

参考:[思路挑战][讨论]批处理做 Base64 编码运算 理论原型

[ Last edited by 0401 on 2007-1-30 at 01:51 PM ]

   此帖被 +69 点积分        点击查看详情   
评分人:【 electronixtar 分数: +5  时间:2007-1-29 04:50
评分人:【 pengfei 分数: +15  时间:2007-1-29 04:51
评分人:【 vkill 分数: +9  时间:2007-1-29 09:14
评分人:【 redtek 分数: +15  时间:2007-1-29 11:34
评分人:【 ccwan 分数: +15  时间:2007-1-29 20:58
评分人:【 xycoordinate 分数: +2  时间:2007-3-17 06:50
评分人:【 kcdsw 分数: +4  时间:2007-6-13 16:51
评分人:【 3mcat 分数: +1  时间:2010-8-2 19:06
评分人:【 gool123456 分数: +2  时间:2010-8-28 23:20
评分人:【 89762566 分数: +1  时间:2010-9-27 11:35


附件 1: Base64.rar (2007-1-29 10:50, 2.35 K, 下载附件所需积分 1 点 ,下载次数: 153)
2007-1-29 04:17
查看资料  发短消息 网志   编辑帖子
electronixtar
铂金会员





积分 7493
发帖 2672
注册 2005-9-2
状态 离线
『第 2 楼』:  

I like it! 超级顶

0401兄牛X。当初我弄批处理Base64是为了用nc.exe来登陆邮箱,也就是用批处理来下载 163 的邮件,呵呵

参考 这个帖子
http://www.cn-dos.net/forum/viewthread.php?tid=24835

[ Last edited by electronixtar on 2007-1-29 at 05:12 AM ]

   此帖被 +1 点积分    点击查看详情   
评分人:【 xdjm 分数: +1  时间:2010-1-2 17:30





C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
2007-1-29 04:49
查看资料  发送邮件  发短消息 网志   编辑帖子
electronixtar
铂金会员





积分 7493
发帖 2672
注册 2005-9-2
状态 离线
『第 3 楼』:  

还有那个自动登陆QQ的帖子也可以解决Base64问题了,呵呵,太安逸了


http://www.cn-dos.net/forum/view ... =1&highlight=QQ




C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
2007-1-29 05:01
查看资料  发送邮件  发短消息 网志   编辑帖子
0401
中级用户

带走



积分 435
发帖 88
注册 2005-9-24
状态 离线
『第 4 楼』:  

可能是前段时间没来论坛吧,2楼的帖子以前没见过,不过标题诱惑性很大啊,自己DIY一个收发邮件的P肯定爽,有空拜读下那个帖子。

2007-1-29 05:13
查看资料  发短消息 网志   编辑帖子
redtek
金牌会员





积分 2902
发帖 1147
注册 2006-9-21
状态 离线
『第 5 楼』:  

超级顶~~~
兄代码以及实现的意义已经划时代了~:)))



    Redtek,一个永远在网上流浪的人……

_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._
2007-1-29 05:13
查看资料  发送邮件  发短消息 网志   编辑帖子
0401
中级用户

带走



积分 435
发帖 88
注册 2005-9-24
状态 离线
『第 6 楼』:  



  Quote:
Originally posted by redtek at 2007-1-29 05:13:
超级顶~~~
兄代码以及实现的意义已经划时代了~:)))

轻轻地划了一下吧?^_^

2007-1-29 05:21
查看资料  发短消息 网志   编辑帖子
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 7 楼』:  

将帮助部分稍作改动

主要是为了方便那些不爱敲键盘的朋友
:help
for /f "delims=:" %%i in ('findstr /n /x :helpdoc "%~f0"') do (
    more +%%i "%~f0">con
    if "%~0"=="%~f0" pause
)
goto :eof

:helpdoc
Base64 Encode n Decode Beta By 0401

Usage:
Base64 [/e] filename1 [filename2]
       [/d filename1] [filename2]
       [/h]
    /e    Base64 编码操作,处理文件大小上限 64KB
    /d    Base64 解码操作
    filename1 输入文件名
    filename2 输出文件名
        /e 缺省输出文件名为 B64ENC
        /d 缺省输出文件名为 B64DEC
    直接将输入文件拖动到批处理中执行时,缺省进行编码,得到B64ENC   
    /h    显示本文档


2007-1-29 06:40
查看资料  发短消息 网志   编辑帖子
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 8 楼』:  

如果改一改

能够生成带有自解码代码的批处理

这就基本可以实现编码文档的独立流通了

从而实现另一种形式的加密/解密

2007-1-29 06:49
查看资料  发短消息 网志   编辑帖子
0401
中级用户

带走



积分 435
发帖 88
注册 2005-9-24
状态 离线
『第 9 楼』:  

那些不爱敲键盘的朋友是qzwqzw兄吧 :)
生成自解码代码的批处理是可行的,不过每个人都可以通过运行批处理得到解码后的文件,那用这种方式来实现文档的加密/解密也就没什么意义了。

2007-1-29 07:34
查看资料  发短消息 网志   编辑帖子
electronixtar
铂金会员





积分 7493
发帖 2672
注册 2005-9-2
状态 离线
『第 10 楼』:  

一个崭新的 exe2bat 诞生了!




C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
2007-1-29 07:48
查看资料  发送邮件  发短消息 网志   编辑帖子
vkill
金牌会员





积分 4103
发帖 1744
注册 2006-1-20
来自 甘肃.临泽
状态 离线
『第 11 楼』:  

这个要好好研究下了

2007-1-29 09:14
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子
0401
中级用户

带走



积分 435
发帖 88
注册 2005-9-24
状态 离线
『第 12 楼』:  

原来的文件中这段代码
set/p=编码初始化中,请稍等。<nul
set of=B64ENC
set/p=<nul>%of%
这句set/p有个错误,就是如果是直接拖动文件到该批处理文件上,会在%userprofile%路径下生成一个文件:B64ENC。这不是我本意,我疏忽了,大家改为:
set/p=<nul>"%~dp0%of%"
虽然问题不大,但发现了还是要改的。
__________________________________

又发现个bug,CMD下直接使用文件名但不带扩展名执行会出错。:help下一行%0替换为"%~f0"。

[ Last edited by 0401 on 2007-1-30 at 01:55 PM ]

2007-1-29 10:43
查看资料  发短消息 网志   编辑帖子
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 13 楼』:  

兄乃高人,特奉上我能加的最高分,并请兄有空到水区支持一下我的帖子。^_^



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2007-1-29 20:59
查看资料  发送邮件  发短消息 网志   编辑帖子
Michael
钻石会员





积分 10046
发帖 3039
注册 2002-11-11
状态 离线
『第 14 楼』:  

base64,比较喜欢。



简单就是美
2007-1-30 11:01
查看资料  发短消息 网志   编辑帖子
0401
中级用户

带走



积分 435
发帖 88
注册 2005-9-24
状态 离线
『第 15 楼』:  



  Quote:
Originally posted by electronixtar at 2007-1-29 07:48:
一个崭新的 exe2bat 诞生了!

我有个想法,如果只是单纯地要 any2bat 可以采用更为直接的方法,直接提取文件每个字节的值,转为十六进制。解码时使用 debug 来还原文件。

  Quote:
Originally posted by qzwqzw at 2007-1-29 06:49:
如果改一改

能够生成带有自解码代码的批处理

这就基本可以实现编码文档的独立流通了

从而实现另一种形式的加密/解密

不好意思,我说没有意义其实是我自己没开窍,只要改变批处理文件中的 Key 值就行了,并且在自解码的时候提供给批处理。这样就可以达到简单的加解密了。

2007-1-30 15:56
查看资料  发短消息 网志   编辑帖子
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: