• Python工具箱系列(四十二)


    rar文件操作

            rar是广受好评,使用广泛的压缩格式,开发者为尤金·罗谢尔(俄语:Евгений Лазаревич Рошал,拉丁转写:Yevgeny Lazarevich Roshal),RAR的全名是“Roshal ARchive”,即“罗谢尔的归档”之意。尤其是winrar一度成为windows上的必备软件。它的特点如下:

    • RAR通常情况比ZIP压缩比高,但压缩/解压缩速度较慢。

    • 分卷压缩:压缩后分割为多个文件。

    • 固实压缩:把要压缩的视为同一个文件以加大压缩比,代价是取用包中任何文件需解压整个压缩包。

    • 恢复记录:加入冗余数据用于修复,在压缩包本身损坏但恢复记录够多时可对损坏压缩包进行恢复。

    • 加密:RAR 2.0使用AES-128-cbc,(rar5.0以后为AES-256CBC)。之前RAR的加密算法为私有。目前均未被直接攻破(至少没有公开),没有密码时只有暴力破解

           rar解码器的源代码已经开放,RAR解码器许可证以不许发布编译RAR兼容编码器为条件,允许有条件自由发布与修改,而RAR编码器一直是有专利的。格式并不开放,所以python对于rar格式只能够是读取,不能够进行其它操作(创建与修改)。本文介绍如何使用第三方库来操作rar文件。安装过程很简单,使用以下命令安装。

    1. # 千万不能够用pip install rarfile安装最新版本(4.0)
    2. pip install rarfile==3.3

           rarfile 4.0版本的功能有问题,无法正确的解压加密的RAR文件。安装rarfile 3.x版本即可。基本功能的示例代码如下。

    1. import rarfile
    2. import os
    3. rar_file = r"d:\foobox-cn.rar"
    4. rar_file_passwd = r'd:\Imhex.rar'
    5. target_dir = r'd:\test'
    6. def rarinfo(filename):
    7. """
    8. 获得RAR文件中的文件列表
    9. Args:
    10. filename (string): 要打开的RAR文件
    11. """
    12. rf = rarfile.RarFile(filename)
    13. if rf.needs_password():
    14. print("RAR文件需要密码")
    15. # 输出文件名与大小
    16. for f in rf.infolist():
    17. print(f.filename, f.file_size)
    18. if "README.md" in f.filename:
    19. print(rf.read(f).decode('utf-8'))
    20. def unrar(filename, targetdir=None, password=None):
    21. """
    22. 解压RAR文件。winrar的路径要设置在WINDOWS的PATH环境变量中
    23. Args:
    24. filename (string): 要打开的RAR文件
    25. """
    26. rf = rarfile.RarFile(filename)
    27. if targetdir:
    28. if not os.path.exists(targetdir):
    29. os.mkdir(targetdir)
    30. rf.extractall(path=targetdir, pwd=password)
    31. else:
    32. rf.extractall(pwd=password)
    33. rarinfo(rar_file)
    34. rarinfo(rar_file_passwd)
    35. unrar(rar_file, target_dir)
    36. unrar(rar_file_passwd, target_dir, password='88488848')

            winrar产生以下2个目标文件。其中一个有密码,一个无。从互联网下载RAR文件,有可能由于时间久远,忘记当时的密码设置,需要对密码进行破解,其基本的思路是:

    • 利用人性的弱点,先使用常用密码进行尝试。可以建立自己的一个常用密码本,或者从互联网收集常用的密码

    • 暴力破解,组合各种可能性后,挨个试

           为了方便记忆,大部分人选择极为简单的密码,例如2016年全球最常用的密码就是:123456。笔者在国内酒店住宿,大部分WIFI密码是88888888,或者是房间号,相当于不设防,这就是人性的弱点。许多电影里神乎其神的黑客破解也无外于此。除了简单的密码外,还有些人使用出生年月、手机号码等也很容易猜。如果用户认真设置口令,则RAR在算法本身上没有缺陷,只能够暴力破解,也就是在所有可能的字母、符号与数字的海量组合中进行尝试,这个非常消耗时间。以下代码示例了这个过程。

    1. import itertools
    2. import rarfile
    3. import numba
    4. password_file = r'd:\password.txt'
    5. target_file = r'd:\ImHex.rar'
    6. target_dir = r'd:\test'
    7. full_pwdstr = 'abcdefghijklmnopqrstuvwxyz0123456789'
    8. digit_pwdstr = '0123456789'
    9. def get_passwd() -> str:
    10. for x in itertools.product(digit_pwdstr, repeat=8):
    11. yield ''.join(x)
    12. def cracker(filename):
    13. """
    14. 暴力破解RAR文件
    15. Args:
    16. filename (string): 要破解的RAR文件
    17. """
    18. rf = rarfile.RarFile(filename)
    19. crack_ok = False
    20. with open(password_file) as fpPwd:
    21. for pwd in fpPwd.readlines():
    22. pwd = pwd.rstrip()
    23. print(f"try password: {pwd}")
    24. try:
    25. rf.extractall(path=target_dir, pwd=pwd)
    26. print('Success! ====>'+pwd)
    27. crack_ok = True
    28. break
    29. except:
    30. pass
    31. if not crack_ok:
    32. # 暴力组合
    33. for pwd in get_passwd():
    34. try:
    35. rf.extractall(path=target_dir, pwd=pwd)
    36. print('Bingo! ====>'+pwd)
    37. crack_ok = True
    38. break
    39. except:
    40. pass
    41. cracker(target_file)

            虽然我们知道口令是88488848,但是程序必须遍历所有的组合才能够获得真正的密码,极为耗时。此时,python比较慢的特点就表现的淋漓尽致。如果想进一步提高效率,可以考虑以下路径:

    • PyPy

    • Cython

    • Numba

    以上三个方案选择时考虑:

    • 通用性:在三个方案中,Cython和Numba的兼容性都非常好,而Pypy对于部分库的支持较差(如Numpy,Scipy)。

    • 速度:这三种方案的速度相差不大。

    • 易用性:易用性最好的无疑是Pypy,Pypy是Python的解释器,我们针对纯Python使用Pypy,除了Pypy不支持的部分库外,不需要进行任何改动。然后是Numba,Numba使用装饰器来优化函数,易用性也很高,最后是Cython。

  • 相关阅读:
    解读意大利葡萄酒分类系统
    私有gitlab的搭建和配置教程
    Multi-Party Threshold Private Set Intersection with Sublinear Communication-2021:解读
    PC安装苹果虚拟机?VirtualBox 安装
    项目管理逻辑:老板为什么赔钱的项目也做?为什么害怕你闲着?
    Win10下pytorch环境搭建详细教程以及示例测试
    php基于PHP的汉服文化交流平台毕业设计源码240903
    瞎扯:修仙文明VS科技文明发展潜力
    Python爬虫实战:抓取和分析新闻数据与舆情分析
    IO进线程:信号灯
  • 原文地址:https://blog.csdn.net/shaanxihualu/article/details/132810810