
标题: [文本处理] 求助批处理base64合成文件 [打印本页]
作者: 304802301 时间: 7 天前 18:46 标题: 求助批处理base64合成文件
1、我提供了3个示例,在文件夹“1合并前”里面
2、有一个文件夹“01”,把里面的所有文件使用7zip压缩------------并设置密码,密码取值自文件名为“01.H”里面的UniqueCode字段的值--------------再把加了密的压缩包文件base64成字符串----------------------再写入“01.H”文件里面的Value字段的值
3、上述的文件夹“01”和文件“01.H”是搭配的。文件名字和文件夹名字一致的才搭配
4、上述过程中如果没有UniqueCode字段,则表示没有密码,就不用设置密码
5、需要批量处理,有上万个需要处理,感谢各位!
6、示例上传了百度网盘,合成后的效果文件在“2合并结果”文件夹里,可以提供参考https://pan.baidu.com/s/1gtrPhHRZLNEqYtCQcoUeNg 提取码: i8ze

作者: Five66 时间: 7 天前 20:49
为啥示例里的文件名一个.H 一个.ZBS 一个.TBS ? 这有啥规律不? 还是都这样? 名字会重复不? 会的话要如何处理?
为啥示例里的文件内容一个是BidFileTable的value 一个是FileTable的value? 会出现其他的不? 还是都这样? 会出现多个的value不? 会的话要如何处理?
为啥示例文件的合并结果value值解码后开头是PK? 所有文件使用7zip压缩 ,是指用7zip压缩成zip不?
作者: 304802301 时间: 7 天前 21:03
本帖最后由 304802301 于 2025-3-26 22:58 编辑
回复 2# Five66
为啥示例里的文件名一个.H 一个.ZBS 一个.TBS ? 这有啥规律不? 还是都这样? 名字会重复不? 会的话要如何处理?
答:文件格式是随机的,没有规律(或者我可以先批量获取所有文件格式,再自行写入到bat指定的地方,也行的),文件名之间不会重复,文件夹名之间不会重复,格式会重复。不考虑重复的情况或者重复的情况下你觉得怎么处理合适就怎么处理。
为啥示例里的文件内容一个是BidFileTable的value 一个是FileTable的value? 会出现其他的不? 还是都这样? 会出现多个的value不? 会的话要如何处理?
答:目前只有BidFileTable的value和FileTable的value,暂时不会出现其他的value(如果后期冒出了其他,希望我可以自行编辑bat来增加)。一个文件里只有唯一的value,不会出现多个(示例文件中也没有出现多个),不考虑重复的情况或者重复的情况下你觉得怎么处理合适就怎么处理。
为啥示例文件的合并结果value值解码后开头是PK? 所有文件使用7zip压缩 ,是指用7zip压缩成zip不?
答:为啥示例文件的合并结果value值解码后开头是PK?【有论坛大哥回复这个是zip的文件头,查了下确实是。另外如果反向操作,把加密后的base64字符串进行解密,再转换成文件的话,是可以转换成一个zip压缩包,带密码(或无密码),解压后就是对应文件夹里那些文件了】,所有文件使用7zip压缩 ,是指用7zip压缩成zip不?【是的,因为密码很长很长,目前只有7zip支持这么长的密码】
另外再补充下:
1、如果有一个文件名是“jkj.aaa”,那一定会有一个文件夹名字叫“jkj”搭配的。
2、最好可以一个一个的处理,就是处理好一个后接着处理下一个。如果多个一起处理担心文件乱了或者密码乱了之类的问题。
3、有时候文件很大,考虑可以生成一个临时的缓存文件。
作者: buyiyang 时间: 7 天前 21:43
回复 2# Five66
因为zip压缩包文件头标记就是PK吧
作者: 304802301 时间: 7 天前 21:47
回复 4# buyiyang
查了下,确实是的。从百度查询到的:
zip压缩包的文件头标记确实是“PK”。
zip文件头标记由四个字节组成,具体为0x04034b50,通常以“PK”表示
1
。这个标记用于在解压时判断文件是否为zip格式的压缩包
作者: wanghan519 时间: 6 天前 05:09
写了个粗糙的- #ANSI编码&cls&powershell -Version 5.1 -NoLogo -NoProfile "gc '%~0'|out-string|iex"&pause&exit
- dir -Directory | %{
- $n = (dir ($_.Name + '.*'))[0]
- $f = gc -Encoding UTF8 $n | Out-String
- cd $_
- if ($f -match 'UniqueCode="(.*?)"') {
- ..\7za.exe a ..\tmp.zip ('-p' + $Matches[1]) * | Out-Null
- } else {
- ..\7za.exe a ..\tmp.zip * | Out-Null
- }
- cd ..
- $b = [System.Convert]::ToBase64String((gc .\tmp.zip -Encoding Byte -Raw))
- $utf8NoBom = New-Object System.Text.UTF8Encoding($false)
- [System.IO.File]::WriteAllText($n, ($f -replace 'Value=""', ('Value="{0}"' -f $b)), $utf8NoBom)
- rm .\tmp.zip
- }
复制代码
作者: Five66 时间: 6 天前 07:30
这样行不?
保存ansi或gbk编码的bat ,然后放到包含需要处理的文件夹下运行
7z.exe所在路径和输出路径自行设置- @{}#? 2>nul&powershell -c "type -literalpath '%~f0'|out-string|iex"&exit/b
-
- $nanaz='Z:\Program Files\7-Zip\7z.exe'
- $outpath='Z:\Users\foobar\Desktop'
-
- $p=new-object System.Diagnostics.Process
- $p.StartInfo.UseShellExecute=$false
- $p.StartInfo.RedirectStandardOutput=$true
- $p.StartInfo.FileName=$nanaz
- $pargs='a -tzip {0} -so (-_-) "{1}"'
- $bf=new-object 'byte[]' (4*1024*1024)
-
- $files=gci -file
- foreach($file in $files){
- $dir=$file.basename
- if([io.directory]::exists($pwd.path+"\$dir")){
- $coding='default'
- $str=gc -LiteralPath ($file.fullname) -raw
- if($str -Match 'encoding *= *"utf-?8"'){
- $coding='utf8';$str=gc -LiteralPath ($file.fullname) -raw -encoding $coding
- }
- $pw="";if($str -match '(?<=uniquecode=")[^"]*(?=")'){$pw='-p'+$matches[0]}
- $p.StartInfo.Arguments=$pargs -f $pw,($dir+"\*")
- $p.start()
- $ms=new-object 'system.io.memorystream'
- $done=$false;while(-not $done){
- $c=$p.StandardOutput.BaseStream.read($bf,0,$bf.length)
- if($c){$ms.write($bf,0,$c)}else{$done=$true}
- }
- if($str -match '<..*? value="'){
- $v=$matches[0]
- $t=$str -split '<..*? value="',2
- }else{
- write-host "未找到value ,自动添加" -ForegroundColor yellow
- $v='<qwertyuiop Value="'
- $t=@($str,'" />')
- }
- $p.WaitForExit()
- $ms.capacity=$ms.length
- write-host ("保存到文件:"+$outpath+"\已合并_"+$file.name) -ForegroundColor green
- set-content -LiteralPath ($outpath+"\已合并_"+$file.name) -encoding $coding -value @(
- $t[0],$v,[convert]::ToBase64String($ms.getbuffer(),0,$ms.length),$t[1]) -nonewline
- }else{
- write-host "找不到文件夹: $dir" -ForegroundColor red
- }}
- "`ndone"
- cmd /c pause
复制代码
作者: 304802301 时间: 6 天前 11:06
回复 7# Five66
感谢大哥!但是感觉和我提供的示例结果里的bae64字符串不一样。。。你看下截图。
[img]
[/img]
作者: 304802301 时间: 6 天前 11:11
回复 6# wanghan519
感谢大哥!但是有点问题哦,他提示这个,你看下截图
[img]
[/img]
作者: wanghan519 时间: 6 天前 11:19
回复 9# 304802301
把../7za.exe改成字符串以后,需要在开头加上&复制代码
另外,压缩率或其他地方不一样,生成的base6就不一样
作者: Five66 时间: 6 天前 18:57
回复 8# 304802301
正常 ,压缩时使用的算法 ,算法版本 ,压缩参数 ,写入方式之类的都会影响压缩出来的数据 ,只要压缩出来的数据不同base64的结果就不同
7楼代码由于写入方式跟常规不一样 ,所以压缩后的base64跟常规的不一样 ,虽然base64不同 ,但是base64解码还原后的压缩包应该是能正常解压的 ,并且解压后跟原来的一样的
总之 ,没啥特别要求的话 ,应该测试看看base64解码还原后的压缩包能不能正常解压 ,解压后跟原来是否一样
作者: aloha20200628 时间: 6 天前 19:46
回复 1# 304802301
很好奇楼主为何选用一个笨重的 base64 字符串码流(要比源压缩包尺寸大1.33倍)而非一个轻巧的 MD5 校验码?
作者: buyiyang 时间: 6 天前 21:02
回复 12# aloha20200628
因为其目的大概是传输而不是校验
作者: 304802301 时间: 6 天前 21:13
本帖最后由 304802301 于 2025-3-27 21:16 编辑
回复 11# Five66
大哥不好意思。。。我前面应该是搞错了,UniqueCode不是明文的密码,是base64之后的内容。意思就是要把UniqueCoded的值base64解密后,才是真正的密码,再去压缩。麻烦再改下批处理哈,感谢感谢
比如示例01.H中,UniqueCode的值是MGVkNjA5OWRlNDFkNGQ5YTk3YjE2ZmY3MDQ4YmQ4ODEwOWM5ZWZiNzdkZTg0YWExODE5ZWI0ZDgxYzQwZjNlODMxOWRkZmNkMDdmYjQxY2RiMjZkM2FkNjE0OGQ0YzJkZTBmMWJiMTkzZmQxNDI0ZDg4YzVmOWJmNGVkNDRmOWU=,base64解密后是0ed6099de41d4d9a97b16ff7048bd88109c9efb77de84aa1819eb4d81c40f3e8319ddfcd07fb41cdb26d3ad6148d4c2de0f1bb193fd1424d88c5f9bf4ed44f9e,这就是真正的密码,去压缩文件
作者: 304802301 时间: 6 天前 21:13
本帖最后由 304802301 于 2025-3-27 21:16 编辑
回复 6# wanghan519
大哥不好意思。。。我前面应该是搞错了,UniqueCode不是明文的密码,是base64之后的内容。意思就是要把UniqueCoded的值base64解密后,才是真正的密码,再去压缩。麻烦再改下批处理哈,感谢感谢
比如示例01.H中,UniqueCode的值是MGVkNjA5OWRlNDFkNGQ5YTk3YjE2ZmY3MDQ4YmQ4ODEwOWM5ZWZiNzdkZTg0YWExODE5ZWI0ZDgxYzQwZjNlODMxOWRkZmNkMDdmYjQxY2RiMjZkM2FkNjE0OGQ0YzJkZTBmMWJiMTkzZmQxNDI0ZDg4YzVmOWJmNGVkNDRmOWU=,base64解密后是0ed6099de41d4d9a97b16ff7048bd88109c9efb77de84aa1819eb4d81c40f3e8319ddfcd07fb41cdb26d3ad6148d4c2de0f1bb193fd1424d88c5f9bf4ed44f9e,这就是真正的密码,去压缩文件
作者: Five66 时间: 5 天前 00:32
回复 14# 304802301
将7楼代码第22行换成下面的 ,因为使用的是字符串 ,base64解码后涉及字符串编码问题 ,简单的判断了下编码- $pw="";if($str -match '(?<=uniquecode=")[^"]*(?=")'){
- if($Matches[0]){$pw=$matches[0];$o=$pw.Length%4
- if($o){$pw=$pw+'===='.Substring(0,4-$o)}
- $pwdc=[text.encoding]::utf8.getstring([convert]::FromBase64String($pw))
- if($pwdc -match '\?'){
- write-host "密码的编码可能不是utf8 ,将使用默认编码" -ForegroundColor yellow
- $pwdc=[text.encoding]::default.getstring([convert]::FromBase64String($pw))}
- $pw='-p"'+$pwdc+'"'
- }}
复制代码
作者: Five66 时间: 5 天前 00:46
啊 ,代码没有排除bat本身 ,bat的名字最好取个唯一的名字 ,也就是说不要有跟bat对应的文件夹
作者: wanghan519 时间: 5 天前 04:13
- #ANSI编码&cls&powershell -Version 5.1 -NoLogo -NoProfile -Command "gc -Encoding Oem -ReadCount 0 -LiteralPath '%~f0'|out-string|iex"&pause&exit/b
- dir -Directory | %{
- $n = (dir -File ($_.Name + '.*'))[0]
- $f = gc -Encoding UTF8 -Raw $n
- cd $_
- if ($f -match 'UniqueCode="(.*?)"') {
- $p = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Matches[1]))
- & "D:\7za.exe" a ..\tmp.zip ('-p' + $p) * | Out-Null
- } else {
- & "D:\7za.exe" a ..\tmp.zip * | Out-Null
- }
- cd ..
- $b = [System.Convert]::ToBase64String((gc .\tmp.zip -Encoding Byte -Raw))
- $utf8NoBom = New-Object System.Text.UTF8Encoding($false)
- [System.IO.File]::WriteAllText($n, ($f -replace 'Value=""', ('Value="{0}"' -f $b)), $utf8NoBom)
- rm .\tmp.zip
- }
复制代码
楼上大佬写的更好,我抄了一点
,密码改用了解码后的
作者: Five66 时间: 5 天前 06:45
回复 16# Five66
改一下 ,加上了密码base64解码后包含英文双引号时的处理
将7楼代码第22行换成下面的 ,因为使用的是字符串 ,密码base64解码后可能涉及字符串编码问题 ,简单的判断了下编码
代码没有排除bat本身 ,bat的名字最好取个唯一的名字 ,也就是说最好不要有跟bat对应的文件夹 ,不然对应的文件夹也会压缩处理- $pw="";if($str -match '(?<=uniquecode=")[^"]*(?=")'){
- if($Matches[0]){$pw=$matches[0];$o=$pw.Length%4
- if($o){$pw=$pw+'===='.Substring(0,4-$o)}
- $pwdc=[text.encoding]::utf8.getstring([convert]::FromBase64String($pw))
- if($pwdc -match '\?'){
- write-host "密码的编码可能不是utf8 ,将使用默认编码" -ForegroundColor yellow
- $pwdc=[text.encoding]::default.getstring([convert]::FromBase64String($pw))}
- $pwdc=[regex]::replace($pwdc,'\\+"|""+|"',[scriptblock]::create('"\"+($args[0].value.tochararray() -join "\")'))
- $pw='-p"'+$pwdc+'"'
- }}
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |