4 个版本

0.2.1 2024年1月28日
0.2.0 2021年6月6日
0.1.2 2020年11月24日
0.1.1 2020年11月24日
0.1.0 2020年11月14日

密码学 类别中排名第 111

MIT 许可证

270KB
6.5K SLoC

delsum

delsum 是一个用于查找文件中使用的校验和的 CLI 应用程序。

目前有三个子命令

  • check:给定校验和算法的规范和文件列表,该命令简单地输出这些文件的校验和。
  • part:给定校验和算法的规范和具有相应校验和的文件列表,该命令查找具有给定校验和的文件部分
  • reverse:给定具有相应校验和的文件列表,该命令查找使用的校验和参数

check

此子命令使用给定的算法计算校验和。

示例

$ delsum check -m 'crc width=32 poly=0x4c11db7 init=0xffffffff xorout=0xffffffff refin=true refout=true' file_a file_b file_c
700b14f5,e1207917,79741cb2

可以使用 -m 直接作为参数指定算法,也可以在文件中提供算法列表。

使用 -S-E 指定计算校验和的范围的开始或结束,也可以是负数以使其相对于结束。例如,要计算除最后两个字节之外的所有字节的校验和,可以指定 -S 0-E-3(它是包含的,因此 -3 仍然是总和的一部分)。

有关可用的算法及其指定方法,请参阅此处

part

此子命令查找所有文件列表,其中所有给定的校验和都匹配。匹配的文件部分必须在所有文件中相同。

示例

$ delsum part -m 'modsum width=16 module=ffff' -c 1234,5678,abcd file_a file_b file_c
modsum width=16 module=ffff:
    0x8:-0x3

在这种情况下,校验和匹配的部分是 0x8:-0x3,其中 -0x3 是从末尾开始计算的。这是一个包含的范围,意味着从起始到结束的校验和范围将是 0x0:-0x1。如果文件大小分别为15、16和18字节,则此输出意味着

  • file_a 的校验和为 1234,从字节8到13
  • file_b 的校验和为 5678,从字节8到14
  • file_c 的校验和为 abcd,从字节8到16

还可以使用 -s 标志使部分末尾相对于文件开头(而不是结尾)。此外,-S-E 允许通过指定范围来约束范围开始和结束的位置(也是包含的)。例如,当通常输出范围 0x1:0xa0x3:0x100x4:0xb 时,指定 -S0x0:0x3 只允许范围开始部分在0到3(包含)之间,因此不会打印 0x4。这有助于避免误报,也可以减少执行时间。

有很小几率会输出类似 0x1,0x6:0x5,0x10 的内容。这仅仅意味着每种组合都是可能的。在这种情况下,会有 0x1:0x50x1:0x100x6:0x10。虽然理论上 0x6:0x5 也是一个选择,但它是不合法的,因为它方向相反。

通过利用校验和的线性特性,整个过程可以在大约对数线性时间内完成,但请记住,它有大的(线性)空间开销,如果你在一批500MB的文件上运行它,可能会耗尽内存。

还可以将算法列表作为输入文件提供给 -M。这很有用,因为它允许简单地放入最常见的几个校验和算法,并检查文件任何部分的算法是否有所需的校验和。有关可用算法及其指定方法,请参阅 此处

reverse

此子命令用于查找校验和算法的参数。

给定文件和校验和,它搜索那些整个文件具有给定校验和的算法参数。

请注意,至少要指定基本算法和校验和的宽度(例如,crc width=32)。有关可用的算法及其指定方式,请参阅此处

示例

$ delsum reverse -m 'crc width=32' -c 700b14f5,e1207917,79741cb2 file_a file_b file_c
crc width=32 poly=0x4c11db7 init=0xffffffff xorout=0xffffffff refin=true refout=true

通常需要3个文件,并且对于除modsum之外的算法,至少有一个文件需要具有不同的长度。还可以指定算法的一些参数(例如使用-m 'crc width=32 init=0'),这需要更少的文件或产生更少的误报。

如果您只有特定长度的文件,但只关心该长度的校验和,对于非modsum算法,您可以直接设置init=0

它通常非常快;例如,CRC反转算法的运行时间在大多数情况下大约是O(n*log^2(n)*log(log(n))),其中n是文件大小,这要归功于NTL和gf2x库中实现的快速gcd算法。

对于某些参数,只搜索可能的组合

  • wordsize搜索8的倍数且小于或等于width的2的幂
  • refinrefout搜索为refin = refout

要搜索这些参数,可以手动指定它们或使用--extended-search CLI参数。

算法

目前有三种算法系列:modsumfletchercrc。它们的指定方式如下:algofamiliy width=123 para1=ff para2=true para3=10 name="algoname"。请注意,除了widthwordsize之外的所有数值参数都是十六进制。

常见值

目前,这些在所有求和类型中共享

  • width:校验和的位数宽度
  • out_endian:校验和的字节序,可以是littlebig
  • wordsize:输入文本中字的大小(位数)。必须是8的倍数,且介于8和64之间。例如,在简单的校验和中,使用wordsize=16会将文件分割成16位整数并求和,模module
  • in_endian:输入字的字节序,可以是littlebig

modsum

具有参数widthinitmodule的简单模数和。

对应于

sum = init
for byte in file:
    sum = (sum + byte) % module
return sum

注意,对于值为0的module,它等同于2^width

moduleinit的默认值都是0。

fletcher

具有参数 widthinitaddoutmoduleswap 的 Fletcher 类求和。

对应于

sum1 = init
sum2 = 0
for byte in file:
    sum1 = (sum1 + byte) % module
    sum2 = (sum2 + sum1) % module
sum1 = (sum1 + addout.sum1) % module
sum2 = (sum2 + addout.sum2) % module
if not swap:
    returm (sum2 << (width/2)) | sum1
else:
    returm (sum1 << (width/2)) | sum2

输出为“压缩”形式,其中 sum1 存储在低 width/2 位,sum2 存储在高 width/2 位(如果启用 swap,则相反)。参数如下:

  • width:整个压缩校验和的宽度。必填。
  • module:减去的值。`module = 0` 表示 `2^(width/2)`,这是默认值。
  • init:初始化常规校验和的值。默认为 0。
  • addout:在求和结束时添加的压缩值。高位总是添加到最终校验和的高位,无论是否启用 swap。默认为 0。
  • swap:布尔标志,表示常规求和应在压缩校验和的高半部分。默认为 `false`。

请注意,目前仅支持字节求和,因此尚不能指定 fletcher-32 求和。

crc

一个与 Rocksoft^TM 模型一致的 CRC 算法,如“CRC 错误检测轻松指南”中所述。

它具有以下参数

  • width:校验和(和多项式)的位宽。必填。
  • poly:生成多项式,使用正常符号。必填(除 reverse 外)。
  • init:crc 状态的初始值。默认为 0。
  • xorout:与求和进行异或运算的最终值。默认为 0。
  • refin:布尔标志,表示是否要反射输入字节的位。默认为 `false`。
  • refout:布尔标志,表示是否在添加 xorout 之前反射最终校验和的位。默认为 `false`。

请注意,对于 wordsize 的其他值,与 in_endian=little(标准)相同,即在计算 wordsize=8 校验和之前,交换每个 wordsize 位组中的字节。

工作原理

有关使用算法的一些(不完整)说明可以在 这里 找到。

安装

有一个带有 NTL 库编译的 Linux 版本,可以在 这里 找到,但请注意,它没有编译大多数现代 x86 扩展,因此无法利用 gf2x 中的某些优化例程,这使 CRC 反转速度更快。我也太笨了,无法进行 Windows 版本的编译,对此表示歉意。

此程序链接到 NTLgf2xgmp

如果您使用的是基于 Debian 的系统,可以使用以下命令安装它们:

apt-get install libgmp-dev libgf2x-dev libntl-dev

您也可以自己编译它们,请参阅 这里。这通常会产生最快的二进制文件,因为可以使用指令集扩展,还可以调整算法参数。

如果您已安装 cargo,则可以在项目目录根目录中使用以下命令编译:

cargo install --path .

或者,不下载仓库,使用

cargo install delsum

如果您想将 NTL 库静态链接,可以在运行 cargo 时设置环境变量 DELSUM_STATIC_LIBS=1

许可证

本项目的代码遵循 MIT 许可。

依赖项

~3–5MB
~91K SLoC