shasum --check 表示可以使用多种算法吗?
shasum --check says ok for multiple algorithms?
我想要一个简单的一行命令来检查我下载的软件是否与校验和匹配。我找到这个命令 here:
echo "68001338a60fca58e60e3f8dcff122954443afa984a0d766eea9c3b9b9b151d3783e7fd5e3fd8794c5839d7dc8d457e62057b009fc27d76b97d957903ef8641a clonezilla-live-3.0.0-26-amd64.zip" | shasum --check -a 512
这会产生一个 OK 结果。但如果我将算法更改为 256,它也说可以。这是为什么?我用的是 clonezilla checksums provided,256 的校验和显然和 512 不一样。但它仍然说 OK。如果我手动更改命令中的校验和,它将失败,所以看起来它应该可以工作。即使我指定了不同的算法,shasum 是否会在幕后施展魔法来选择正确的算法?
是的。它实际上是一个 perl 脚本,因此您可以轻松地自己查看。在 sub verify
中,经过一些设置后,对于每一行,它开始执行:
if (/^[ \t]*\?SHA/) {
$modesym = '*';
($bslash, $alg, $fname, $sum) =
/^[ \t]*(\?)SHA(\S+) \((.+)\) = ([\da-fA-F]+)/;
$alg =~ tr{/}{}d if defined $alg;
}
else {
($bslash, $sum, $modesym, $fname) =
/^[ \t]*(\?)([\da-fA-F]+)[ \t]([ *^U])(.+)/;
$alg = defined $sum ? $len2alg{length($sum)} : undef;
}
如果您不了解 perl,变量名通常以 $
开头,但在某些情况下 @
或 %
,并且 /.../
包含一个正则表达式当在 if( )
中使用时,如果当前数据项(这里是校验和文件中的一行)匹配,则简单地 returns true ,并且当在 ($a,$b,$c,$d) = /.../
之类的赋值中使用时,它解析所述数据项和 returns 正则表达式中用非反斜杠括号标记的 'capture groups',用于分配给相应的变量。
第一个分支处理 BSD cksum/md5/sha1/etc 使用的格式,其中说明算法名称,然后是括号中的文件名(在正则表达式中,反斜杠括号是数据字符)、间隔等号和哈希价值。第二个分支处理 GNU 格式,这是你的情况,它使用 map* len2alg
根据值的长度确定哈希算法,定义为:
my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
$len2alg{56} = 512224 if $alg == 512224;
$len2alg{64} = 512256 if $alg == 512256;
即它根据哈希值的长度来确定算法,只是SHA-224和SHA-256对应的长度分别是'shared'和SHA-512/224和SHA-512/256所以默认前者和对于后者,您必须使用之前处理过的 -a
来设置 $alg
。这在手册页上有说明:
When verifying SHA-512/224 or SHA-512/256 checksums, indicate the
algorithm explicitly using the -a option, e.g.
shasum -a 512224 -c checksumfile
(尽管它并没有说这仅适用于 GNU 格式,而不是 BSD 格式),exceptio probat 暗示要验证哈希值 other 而不是那些你不知道的不需要 -a
.
* 实际上 perl 通常调用 @x = (1,2,3)
数组和 %y = (1=>9, 2=>8, 3=>7)
散列,但我们在这里使用散列的其他含义,我想避免增加混乱。
我想要一个简单的一行命令来检查我下载的软件是否与校验和匹配。我找到这个命令 here:
echo "68001338a60fca58e60e3f8dcff122954443afa984a0d766eea9c3b9b9b151d3783e7fd5e3fd8794c5839d7dc8d457e62057b009fc27d76b97d957903ef8641a clonezilla-live-3.0.0-26-amd64.zip" | shasum --check -a 512
这会产生一个 OK 结果。但如果我将算法更改为 256,它也说可以。这是为什么?我用的是 clonezilla checksums provided,256 的校验和显然和 512 不一样。但它仍然说 OK。如果我手动更改命令中的校验和,它将失败,所以看起来它应该可以工作。即使我指定了不同的算法,shasum 是否会在幕后施展魔法来选择正确的算法?
是的。它实际上是一个 perl 脚本,因此您可以轻松地自己查看。在 sub verify
中,经过一些设置后,对于每一行,它开始执行:
if (/^[ \t]*\?SHA/) {
$modesym = '*';
($bslash, $alg, $fname, $sum) =
/^[ \t]*(\?)SHA(\S+) \((.+)\) = ([\da-fA-F]+)/;
$alg =~ tr{/}{}d if defined $alg;
}
else {
($bslash, $sum, $modesym, $fname) =
/^[ \t]*(\?)([\da-fA-F]+)[ \t]([ *^U])(.+)/;
$alg = defined $sum ? $len2alg{length($sum)} : undef;
}
如果您不了解 perl,变量名通常以 $
开头,但在某些情况下 @
或 %
,并且 /.../
包含一个正则表达式当在 if( )
中使用时,如果当前数据项(这里是校验和文件中的一行)匹配,则简单地 returns true ,并且当在 ($a,$b,$c,$d) = /.../
之类的赋值中使用时,它解析所述数据项和 returns 正则表达式中用非反斜杠括号标记的 'capture groups',用于分配给相应的变量。
第一个分支处理 BSD cksum/md5/sha1/etc 使用的格式,其中说明算法名称,然后是括号中的文件名(在正则表达式中,反斜杠括号是数据字符)、间隔等号和哈希价值。第二个分支处理 GNU 格式,这是你的情况,它使用 map* len2alg
根据值的长度确定哈希算法,定义为:
my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
$len2alg{56} = 512224 if $alg == 512224;
$len2alg{64} = 512256 if $alg == 512256;
即它根据哈希值的长度来确定算法,只是SHA-224和SHA-256对应的长度分别是'shared'和SHA-512/224和SHA-512/256所以默认前者和对于后者,您必须使用之前处理过的 -a
来设置 $alg
。这在手册页上有说明:
When verifying SHA-512/224 or SHA-512/256 checksums, indicate the
algorithm explicitly using the -a option, e.g.
shasum -a 512224 -c checksumfile
(尽管它并没有说这仅适用于 GNU 格式,而不是 BSD 格式),exceptio probat 暗示要验证哈希值 other 而不是那些你不知道的不需要 -a
.
* 实际上 perl 通常调用 @x = (1,2,3)
数组和 %y = (1=>9, 2=>8, 3=>7)
散列,但我们在这里使用散列的其他含义,我想避免增加混乱。