[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 30# happy886rr

如果原始数据就是已经过高度压缩的, 我相信再经 BASE64 编码后也不会有大的压缩空间了, 换言之, 不会出现大量重复的 子串 (包括若干连续重复的 A 那种形式)
1

评分人数

TOP

本帖最后由 aa77dd@163.com 于 2016-10-7 14:56 编辑

提供一个先压缩后 BASE64 编码的样本

BASE64 编码文件大小 3,428 字节, 其中是包括 100+ 个非编码字节(如 CR, LF 以及首尾两个注释行)

处理流程:

    C 源码在 Code::Blocks 以 Release 方式编译(其它各种编译设置均默认)
   
     -> neoGetKey.exe  (6,144 字节)

    Windows 原生压缩工具 makecab 压缩  (Windows 也提供了原生的解压工具 expand,   makecab 和 expand 都是 XP 就有的, 经 makecab 打的包, expand 能很好的支持)

    makecab neoGetKey.exe  neoGetKey.exe.cab  (2,450 字节)

    Windows 原生 BASE64 编码器 certutil 编码

    certutil -encode neoGetKey.exe.cab neoGetKey.exe.cab.B64  (3,428 字节)
  1. -----BEGIN CERTIFICATE-----
  2. TVNDRgAAAACSCQAAAAAAACwAAAAAAAAAAwEBAAEAAAAAAAAASgAAAAEAAQAAGAAA
  3. AAAAAAAAR0krdCAAbmVvR2V0S2V5LmV4ZQDuJZB/QAkAGENL7RhtbFPX9dp5DEMT
  4. bDFnS1loH5IDASXBgawKbdI5OI+kkFAnwWMbBMckL4m1xLbsZ0hWKGaO1by+Wss2
  5. pCGNSfXYD6YhjUooDR/tDJlm0oGWMqSFUbWgwfZSR1q2RZn5GG/n3GcnjlHXTaum
  6. IXGVk3u+7jnnnnPuvbYbvzFEcgghDICiEDJC1GEhnz6CAMuePbuMnF5yZdWIpuHK
  7. qh3dLj/r9Xm6fM5ett3pdnsEdi/P+gJu1uVma19uYXs9HXxZXt5SU8qGjSOkQbOI
  8. nKr5+8603ZtEn/OURltJcoEwAmgJYZfDbABgU9EZVD7GrUnFT0ebSpyEOYcyWFUX
  9. /xlUFUPmJmxgLeff2OxnPMoEvk+AecfSVEC5mZuY20pbWYdTcKbrwap7XrgBKouV
  10. +VTFaWSYU3rLH9GzlO31+xE/9S+KHER7LtUezY0tFZvxUb//+8w9GZ/lsIt3QlMF
  11. YmtSsuvKb4iBB5K2fFYi1d+F2u63Vkdg8u16F09YnDHpYCqPibUmRr4NeCipEXrC
  12. MWFdSqSMn1NgiBMSmGlNilOtFxlS/X0wIbxTfQSncwtlkX2kehHwAzJYeAqNz4oC
  13. GH8tZbwCjF9JiZTxRDTl5xyGI+4GxT1AhmeFQTkMbUqdJw6n9M+gkhpPA2hWgObk
  14. XlTIG8ocsP+W0JQp0pqEdcRgIfJ76HyKkTeAyTiXxCSNEIuFROwz4NMg5RHWQjAH
  15. 4g6TDmznwkIG5LIGFkYNgEHUXztuAC0p39QE5FV9WAIroXs3BZYq4GppJcqkbWYx
  16. 1yQPLyYp5dC9mPAlaSXVgh1KeVSrySYaTfIQaMmvoOpKtC4WyHvglIduT8tbkInB
  17. 6KR8jBVCY6IYlMiY5J9itkbl5aAjFprkezhjANSftNmAOl+eC2DSDkmCwkTOr5nr
  18. Dx1sEdOp5BeChnzpoaIMRU6vXiDXzstPZMqlvArgiXdalVsRYTXSxWk6lf/WyR9A
  19. qtP1GMHLTbyz86tQliqpVYfbexuaRG4GD3rAzBZSrsS5cRkWhe5r3k1CvJ0iN6Ef
  20. XqQF2SD3e/13/ojpvq999QtSY65Uo9MPk6q2wYuHcoIX2cH3E4x+uPF68G6f/kgs
  21. eLdDf+TikvETmsH3Atryq4P261Lr+OD7ce4aRi/Zx8M3QG2T/Zr+GFUTDtLuSxhS
  22. +7Mevv8QpkOVEet0KKnd92dM8f7P0RbqDMf6Pwr9SidOiH/57c0l8dDDL776m+DB
  23. 6yTgiPAzYnLXHkfraFgJHEylV34Z9qlw18Cr1DgObQOOG9OOA69h1ANjgYoReKYJ
  24. GKDLJXuutJnBEv4YFovc+CSDLX/AxES4CWS/AuzEEF2DVU9xeeBSXmIYA9IPfDO9
  25. yj6BrcaBfHIn8Oxnps1YroQxMkwz0sRImtAFnebbeP8fvotS38etoxnn6cYf5skh
  26. tT+iLJ4GXXhMWJ11/hQ4UFTYxERqmOOIhq8GJsdG5/sLGoGJWlbA2UgqwtpwTBwV
  27. Pi/OpvpTMf4IRdsCs5DENiN03+v/UJRduyAzebUgKI+FxxJLLZIxjBSYnkm8o+4k
  28. 8otM+yw9t4HnqCP1glmJPPRZRH3qh7B/H/W34tP8XVhw30S9Ftr+Uj2j3BJn7Wc3
  29. 035v0b8dC0114J0SsZ+AmxhOMBRKyZ+xWcjZZ9MXWmgqF6JcnNiiGdvatyx4YN2J
  30. msDMkl8D1f/X0AtVgcVwwbY+GBs9UwF1OfsxmoYbCq1CuE7gjQTN6v0jfw/O08hJ
  31. oM7dVnsjFy4cXeJ3qcTPn384ioenLmPt8zB2KKIu3X1x7mgNjKgBzEQCR+PcMSTj
  32. 3Js4idxI1AiCOPcTlXtC5Z6PFlDuSZV7SuXGooWUe1olfxllMVDuUtRE58vRYjqP
  33. R0vofA2uAjNgePLFCsjTNOSJ5pCBaoVroXX14Rc09NmqwrN1HLaLddQPfB24D8S4
  34. RJXO6EH4t5/FrcybT1vUHMetOm++hUQtsNl4Di6W8msRtxZjRkSrMWrG67elQMqv
  35. QMRaGLVhUVvYuNVMXxxriZRfBaJoJVWspAUUrRXirDix6hI8bU/HTKxmjKkZHFhX
  36. Dwu29v+J5lAMdwNFsyaGexAtoKgX0UKKCojS3IT7EKXpCR9AVM1QMJWhgfkMDUbC
  37. 6IX2k0zzlMQ8KYHN5VehRZ/BO8sPW59LJEghl7IDWlscFVdi2SNW5ngbnXXHgzin
  38. WkBMypWgtmlCvBd4K/GWvE0zd5fjaBJvwW1RjR9ZfYbDkziHlpBSnBOTay8ALt4U
  39. L0s6ycIoN9P3RYHEGaEhDRJnwL6UuFyYdBKnw8aN0mcyZsFrDK/eTPpDrPQYyYhA
  40. KWJAPDSU/ryjFBVm0WwWbcyibVl0QRZdkkUbsuiGLLoyi67NouuzaHMWXZVFW7Lo
  41. 3Vl00raQnsqiZ7Lo6SxaXkDT97oO3tx0fmGYV6hfJBB/8on68RqP1CzrO6FtheUT
  42. 1zyp9+M/irLo0oaXNtdZrTs3bijl6ks3lLZsbdhaWrejvrm08aXtdcAGnf0bNzj8
  43. 3U4f3+EVfKUv+l3f4tnqahZnT2cx6Di4ekdLfU0zV7uWFPmfLwo8z3Y6XT18B+v0
  44. +3mf4PK42bYi/5qlhJSVrYe/rvZ2Cu0ed6era71rY+Vz68FLqeqlFNyUtRNSxws1
  45. gqd3u7OXr2GLnYCWsP6StF//2rXsqmrW/KSm/8nots3jsWZ4PYEeyOBdAx7TBA9q
  46. Bs/UQogBeB9k8CqAt7vpk/10gMwLEAR4A+BYhu75DPwS4BMAMkASIBf8FwCwACUA
  47. lQAWgAaAHQBtAD0AAkAQ4I3meVtHm/8//GtITUcHdm4NIT8kXJ9LsPk87Tz9Ie7n
  48. ZIvLnRJ+sKDDCflI28ILdne3090BZ4fra+e9eHS2uHoE3gdr64nD38PzXvSxhjgc
  49. XbzQ63S5nb4uP6kC2utw8O59Lp/HTciLKt2Jv7+qP3s6HH5ecDi9XofQ76W8fuJo
  50. 5yE6xCeJw+XZS8gejcPjTjEHNLhEtZCvde71+ARSqHUK6TXPAO5xEWLWdnb2BPzd
  51. yNuk7fT6XG6hE/CvaDt9PKz1aXudPT2edpQf0s6JyZDW7+pyO3sQ/5Dmwt/vbt/G
  52. 97cI4CT1O2QWbOOat3MNGzeUdfTQdUbg9fr3tfsElVNs++8h014V0PYWrnne4+M9
  53. /gk=
  54. -----END CERTIFICATE-----
复制代码
C 源码
  1. #include <Windows.h>
  2. #include <stdio.h>
  3. int main(int argc, char** argv) {
  4.     int i, t = 1000, r = 0, kshift = -8;
  5.     char show[3] = "%\0\0";
  6.     if (argc >= 2) t = atoi(argv[1]);
  7.     if (argc >= 3)
  8.         show[1] = (**(argv + 2) >= 'a') ? **(argv + 2) : **(argv + 2) + 'a' - 'A';
  9.     show[1] = ( show[1] == 'x' || show[1] == 'd') ? show[1] : '\0';
  10.     for (i = 0; t == 0 || i < t; i++) {
  11.         int x;
  12.         for (x = 1; x <= 0xFE; x++) {
  13.             if (x == VK_SHIFT || x == VK_CONTROL || x == VK_MENU)
  14.                 continue;
  15.             if (GetAsyncKeyState(x) & 0x8000) {
  16.                 r |= x << (kshift += 8);
  17.                 if (kshift >= 24) {
  18.                     if (show[1]) printf(show, r);
  19.                     return r;
  20.                 }
  21.             }
  22.         }
  23.         if (r != 0) {
  24.             if (show[1]) printf(show, r);
  25.             return r;
  26.         }
  27.         sleep(1);
  28.     }
  29.     if (show[1]) printf(show, 0xFF);
  30.     return 0xFF;
  31. }
复制代码

TOP

回复 31# aa77dd@163.com

原始数据的熵(信息量)经过base64编码后,熵不会变
理论上极限压缩体积 base64字符集是rar这种通用压缩工具选择的扩展ascii字符集的4/3 (64^x = 256^y => x/y=log(256)/log(64))

TOP

回复 23# CrLf
那个js对单纯的A压缩的不够好,还是你的那条数据,例如 576 字节长的编码js版压缩为345 字节,但我用批能压缩到243字节,远超rar和7z
Base64压缩机
  1. @echo off
  2. REM 原始数据
  3. set "LINE=TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAEFAJOHz1cAAAAAAAAAAOAADwMLAQI4AAwAAAAUAAAAAgAAIBIAAAAQAAAAIAAAAABAAAAQAAAAAgAABAAAAAEAAAAEAAAAAAAAAABgAAAABAAAUV0AAAMAAAAAACAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAABQAABAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC50ZXh0AAAAFAoAAAAQAAAADAAAAAQAAAAAAAAAAAAAAAAAAGAAAGAuZGF0YQAAAEAAAAAAIAAA"
  4. REM 压缩数据
  5. setlocal enabledelayedexpansion
  6. for /l %%i in (1,1,10000) do (
  7. if "!LINE:~0,1!"=="A" (
  8. set/a i+=1
  9. ) else (
  10. if !i! neq 0 (
  11. set M=512
  12. for %%Z in (@,-,#,$,_,},{,],[,A) do (
  13.     if !i! geq !M! (
  14. set "S=!S!%%Z"
  15. set/a "i-=M"
  16. )
  17. set/a "M>>=1"
  18. )
  19. )
  20. if "!LINE!"=="" (echo !S!>压缩.txt&exit) else (set "S=!S!!LINE:~0,1!")
  21. )
  22. set "LINE=!LINE:~1!"
  23. )
复制代码
Base64解压机
  1. REM 解压数据
  2. set/p LINE=<压缩.txt
  3. setlocal enabledelayedexpansion
  4. set "Z=A"&(for %%Z in ([,],{,},_,$,#,-,@) do (set "Z=!Z!!Z!"&for %%S in (!Z!) do (set "LINE=!LINE:%%Z=%%S!")))&echo !LINE!>解压.txt
复制代码

TOP

回复 33# plp626
base64会增加一些数据,用6位来表示一个字节,也就是6x=8y。故信息量比为x/y=8/6=4/3,也就是体积涨到133%,所以只能从转码前压缩入手。

TOP

回复 35# happy886rr


    要不要用批处理实现一个 base92
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

回复 33# plp626

BASE64 取 64 个字符, 而不取 其它数字:

1. ASCII 码值 0x80 ~ 0xFF 最高位都是 1, 将与多字节编码冲突 (比如汉字编码), 所以这个范围内的字符都不好用, 最好不用

2. 0x0 ~ 0x7F 共 128 个字符 有好几十个是控制字符, 所以 128 (= 2 ^ 7) 字符也不成

3. 好吧, 2 的幂 比 128 小的 又最大的就是 64 (= 2 ^ 6),  也能找到 64 个 不关控制字符事的可打印字符, 64 就能定了.

4. 64 = 2 ^ 6, 也就是只有 6 个二进位的信息容量, 而任何字符都是要占 8 位的, 也就是信息位利用率只有 6/8 = 3/4,  倒过来, 我们就必须最少要用 4/3 的体积才能编码原始的数据

6 位 X 4 字节 = 8 位 X 3 字节,  整整好, 实现最大化利用, 位数不多不少, 编码解码也方便


BASE64 编码增长率 4/3 - 1 = 33%


而 Ascii85 和 basE91 利用更多的字符来编码, 但因为字符总数 在 2^6 ~ 2^7 之间, 编码解码就没有 2^6=64 个字符的便利了, 程序自然就复杂了.

Ascii85 可以将编码增长率降到 25%
https://en.wikipedia.org/wiki/Ascii85


basE91 encoding 可以将编码增长率降到 23%
http://base91.sourceforge.net/

TOP

回复 36# codegay
批处理局限性太大,我采取的是用C语言来实现压缩,压缩好的数据用批处理解压,再用那个证书管理certutil变成二进制文件。
压缩费时费力,但解压批处理就能胜任。str=!str:*=*!,效率是很高的。

TOP

回复 34# happy886rr


    Nice

我发现自己那个算法压缩的结果有问题,无法解码,回头检查下是什么毛病

TOP

回复 39# CrLf
大师,如果只用可打印字符来压缩的话,压缩比始终上不去。即便再添加新的符号,都不可能比base64划算。只能去寻找重复的节点。

TOP

本帖最后由 523066680 于 2016-10-7 20:31 编辑

回复 40# happy886rr


假设有一个非常mini的函数,它所生成的某一段数据,刚好和这一段数据相同。
然后只要直接计算那一段出来就可以了。(我就是瞎扯扯)
这个图像看起来和原不等式一样的不等式是怎么发现的?

TOP

回复 41# 523066680
哈哈,原来是mod原理,数学无处不在。

TOP

本帖最后由 happy886rr 于 2016-10-7 23:26 编辑

回复 39# CrLf
大师,比如如下的数据:
  1. TVqQAAMAAAAEQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAAQAAMAAAA
复制代码
分别用@,-,#,$,_,},{,],[,.表示512个A、256个A、128个A、、、、、1个A,则化为:
  1. TVqQ[M]EQ[M]Q[M]Q[M]Q[M]Q[M]Q[M]Q[M]Q[M]Q[M]Q[M]Q[M]Q[M]
复制代码
然后继续迭代 用@,-,#,$,_,},{,],[,.表示512个、256个、128个、、、、、1个Q[M]则化为:
  1. TVq.E{]
复制代码
用:冒号表示标签切换。化为可解码的格式
  1. TVq.E{]:Q[M]:A
复制代码
如此就实现了用14个字符去表示108个字符的base64字符串。我发现没有任何算法有这个压缩率高。
我正在思考如何用批处理实现,当然用C实现起来会更容易,但是那样就得带个exe。

当然也许有可能产生歧义,不过只要加上层号即可。
如对字串AAAAAAAAAAAAAAAAAAEFAAABAAACAAADAAAEFAAAGAAAHHAAAAI压缩为
  1. }[EF.B.C.D.EF.G.HH]I:[.;1:A
复制代码
其中:[.;1中:[.表示要替换为的标签,分号;1表示只替换一级权签,也就是只替换.,之后的:A表示在上次替换完后再次替换所有权签为A。
基本可以实现可见字符内的最大压缩化。
2

评分人数

TOP

本帖最后由 aa77dd@163.com 于 2016-10-9 11:40 编辑

happy886rr  的二进制权值去 0 表达法


对给定整数范围 [1,63335] (16位二进制能表达的所有正整数),
如果用 16 进制表达这全部 65535 个数,
编码后不要最高位的 0, 比如:        001F 就是 31(十进制), 我们只取 1F 这两个字符,
但编码中间出现 0 仍保留, 比如:  10B 是 267(十进制), 这里中间的 0 仍保留

以此方式将 [1,63335] 范围内所有的整数全部编码, 然后把所有编码全排在一起, 总长将达到

257775 = 16/4 * (2^16 - 2^12) + 12/4 * (2^12 - 2^8) +  8/4 * (2^8 - 2^4) + 4/4*(2^4 - 2^0)


如果我们同样也只用 16 个字符来对此范围内整数编码, 但这 16 个字符全部取 2 的幂的意义:

为免混淆, 我们全部用字母:

ABCDEFGHIJKLNMOP

上面 16 个字母分别表示 2^0, 2^1, 2^2, 2^3, 2^4, ... 2^14, 2^15, 这些 2 的幂

对一个整数编码时, 我们只把这个整数的二进制形式里的所有的 1 提出, 转换成对应权值的字母, 如下:

9   转二进制 -> 1001        -> 2^3 + 2^0 -> DA

359 转二进制 -> 1 0110 0111 -> 2^8 + 2^6 + 2^5 + 2^2 + 2^1 + 2^0 -> IGFCBA

以此方式将 [1,63335] 范围内所有的整数全部编码, 然后把所有编码全排在一起, 总长将达到

65535 = 2^16 - 1 =
C[16, 1] + C[16, 2] + C[16, 3] + C[16, 4] + C[16, 5] + C[16, 6] + C[16, 7] + C[16, 8]
+ C[16, 9] + C[16, 10] + C[16, 11] + C[16, 12] + C[16, 13] + C[16, 14] + C[16, 15] + C[16, 16]

C[m, n] 是组合数, 比如 C[5, 2] = 5*4 / (2*1) = 10


65535 大概只有 257775 的 1/4, 这种编码方式比普通 16 进制编码在空间上节省很多, 关键在于权值舍 0 的方式
  1. @echo off & setlocal enableDelayedExpansion
  2. >AllHexCode.txt (
  3. for %%a in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do ^
  4. for %%b in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do ^
  5. for %%c in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do ^
  6. for %%d in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do (
  7.     set "HEX=##%%a%%b%%c%%d"
  8.     set "HEX=!HEX:#0000=!"
  9.     set "HEX=!HEX:#000=!"
  10.     set "HEX=!HEX:#00=!"
  11.     set "HEX=!HEX:#0=!"
  12.     set "HEX=!HEX:#=!"
  13.     title !HEX! / FFFF
  14.     <nul set /p "=!HEX!"
  15. )
  16. )
  17. for %%a in (AllHexCode.txt) do echo;[1,63335]范围内所有整数HEX编码总长:%%~za
  18. pause
  19. exit /b
复制代码

TOP

返回列表