我需要在ubuntu上的bash脚本中使用300万个字符串的MD5总和。 300万字符串 - > 300万个MD5哈希值。每个字符串实现大约需要0.005秒。那是4个多小时。有哪些更快的替代品?有没有办法将字符串组泵入md5sum?
#time md5sum running 100 times on short strings
#each iteration is ~0.494s/100 = 0.005s
time (for i in {0..99}; do md5sum <(echo $i); done) > /dev/null
real 0m0.494s
user 0m0.120s
sys 0m0.356s
一个好的解决方案将包括一个bash / Perl脚本,它从stdin中获取一个字符串列表并输出一个MD5哈希值列表。
答案 0 :(得分:6)
使用许多md5实现中的任何一个在C(或Perl或Python)中做起来并不困难 - 其核心md5是一个从字符向量到字符向量的散列函数。
所以只需编写一个读取300万字符串的外部程序,然后逐个将它们提供给您选择的md5实现。这样你就有一个程序启动而不是300万个程序,只有这样才能节省你的时间。
一个项目中的FWIW我使用了Christophe Devine的md5实现(在C中),还有OpenSSL,我相信CPAN也会有一些用于Perl的。 编辑:好的,无法抗拒。我提到的md5实现是例如在small tarball内。获取文件md5.c
并使用此
main()
int main( int argc, char *argv[] ) {
FILE *f;
int j;
md5_context ctx;
unsigned char buf[1000];
unsigned char md5sum[16];
if( ! ( f = fopen( argv[1], "rb" ) ) ) {
perror( "fopen" );
return( 1 );
}
while( fscanf(f, "%s", buf) == 1 ) {
md5_starts( &ctx );
md5_update( &ctx, buf, (uint32) strlen((char*)buf) );
md5_finish( &ctx, md5sum );
for( j = 0; j < 16; j++ ) {
printf( "%02x", md5sum[j] );
}
printf( " <- %s\n", buf );
}
return( 0 );
}
构建一个简单的独立程序,例如,在
/tmp$ gcc -Wall -O3 -o simple_md5 simple_md5.c
然后你明白了:
# first, generate 300,000 numbers in a file (using 'little r', an R variant)
/tmp$ r -e'for (i in 1:300000) cat(i,"\n")' > foo.txt
# illustrate the output
/tmp$ ./simple_md5 foo.txt | head
c4ca4238a0b923820dcc509a6f75849b <- 1
c81e728d9d4c2f636f067f89cc14862c <- 2
eccbc87e4b5ce2fe28308fd9f2a7baf3 <- 3
a87ff679a2f3e71d9181a67b7542122c <- 4
e4da3b7fbbce2345d7772b0674a318d5 <- 5
1679091c5a880faf6fb5e6087eb1b2dc <- 6
8f14e45fceea167a5a36dedd4bea2543 <- 7
c9f0f895fb98ab9159f51fd0297e236d <- 8
45c48cce2e2d7fbdea1afc51c7c6ad26 <- 9
d3d9446802a44259755d38e6d163e820 <- 10
# let the program rip over it, suppressing stdout
/tmp$ time (./simple_md5 foo.txt > /dev/null)
real 0m1.023s
user 0m1.008s
sys 0m0.012s
/tmp$
因此,对于300,000(短)字符串,大约需要一秒钟。
答案 1 :(得分:4)
perl -MDigest::MD5=md5_hex -lpe '$_ = md5_hex $_'
答案 2 :(得分:4)
#~/sw/md5$ time (for i in {0..99}; do md5sum <(echo $i); done) > /dev/null
real 0m0.220s
user 0m0.084s
sys 0m0.160s
#~/sw/md5$ time (python test.py `for i in {0..99}; do echo $i; done`) > /dev/null
real 0m0.041s
user 0m0.024s
sys 0m0.012s
对于这个小样本,python代码的速度是这个小样本的五倍,对于较大的样本,由于缺少生成,差异会大得多。 1k样品是0.033s到2.3s :) 脚本是:
#!/usr/bin/env python
import hashlib, sys
for arg in sys.argv[1:]:
print hashlib.md5(arg).hexdigest()
答案 3 :(得分:3)
我现在没有机器来测试它,但md5sum <<< "$i"
比md5sum <(echo $i)
更快? <<<
语法可以避免为echo
分支子流程的开销,并在标准输入上将$i
直接传递给md5sum
。
答案 4 :(得分:1)
为了获得更好的性能,您可能需要使用不同的程序,或创建一个调用其中一个公开可用的md5哈希API的C程序。
另一种选择是一次产生多个md5调用以利用多个内核。通过你的每个循环可以产生8个调用,前7个使用&amp;最后(表示异步)。如果你有4-8个核心可用,这可以将它加速8倍。