在Python中比较两个字符串
我需要比较两个字符串,或者至少从一个字符串中找到另一个字符串的字符序列。这两个字符串包含文件的md5
值,我必须比较它们,看看是否有匹配的结果。
我现在的代码是:
def comparemd5():
origmd5=getreferrerurl()
dlmd5=md5_for_file(file_name)
print "original md5 is",origmd5
print "downloader file md5 is",dlmd5
s = difflib.SequenceMatcher(None, origmd5, dlmd5)
print "ratio is:",s.ratio()
我得到的输出是:
original md5 is ['0430f244a18146a0815aa1dd4012db46', '0430f244a18146a0815aa1dd40
12db46', '59739CCDA2F15D5AC16DB6695CAE3378']
downloader file md5 is 59739ccda2f15d5ac16db6695cae3378
ratio is : 0.0
所以!我在origmd5
中找到了dlmd5
的匹配,但不知为什么它没有找到...我在某个地方做错了...请帮帮我 :/
3 个回答
给定的输入是:
原始的MD5是 ['0430f244a18146a0815aa1dd4012db46', '0430f244a18146a0815aa1dd40 12db46', '59739CCDA2F15D5AC16DB6695CAE3378']
下载器文件的MD5是 59739ccda2f15d5ac16db6695cae3378
你有两个问题。
首先,第一个值不仅仅是一个MD5,它还包含其他两个东西。
要解决这个问题:如果你知道 origmd5
总是这个格式,那就直接用 origmd5[2]
来代替 origmd5
。如果你不知道 origmd5
是什么,只知道里面有一个是实际的MD5,那你就得对比所有的元素。
第二,实际的MD5值都是十六进制字符串,表示相同的二进制数据,但它们是不同的十六进制字符串(因为一个是大写,另一个是小写)。你可以通过不区分大小写的比较来解决这个问题,但更稳妥的方法是 将它们转换为二进制 后再进行比较。
实际上,如果你正确复制并粘贴了输出,至少有一个十六进制字符串中间有个空格,所以你需要处理带有可选空格的十六进制字符串。根据我所知,标准库中没有这样的函数,但你可以自己写一个,步骤很简单:
def unhexlify(s):
return binascii.unhexlify(s.replace(' ', ''))
同时,我不太明白你为什么要使用 difflib.SequenceMatcher
。两个稍微不同的MD5哈希值指向完全不同的原始数据;这正是MD5和加密哈希函数的意义所在。没有什么是95%的匹配;要么匹配,要么不匹配。
所以,如果你知道 origmd5
中的第三个值是你想要的,那就这样做:
s = unhexlify(origmd5[2]) == unhexlify(dlmd5)
否则,就这样做:
s = any(unhexlify(origthingy) == unhexlify(dlmd5) for origthingy in origmd5)
或者,换个方式让它更简单:
s = unhexlify(dlmd5) in map(unhexlify, origthingy)
或者你找到的任何最易读的等效方式。
看起来你遇到的问题是因为字母的大小写不匹配。你可以试试:
def comparemd5():
origmd5=[item.lower() for item in getreferrerurl()]
dlmd5=md5_for_file(file_name)
print "original md5 is",origmd5
print "downloader file md5 is",dlmd5
s = difflib.SequenceMatcher(None, origmd5, dlmd5)
print "ratio is:",s.ratio()
基本上,你想要用这个方法:if test_string in list_of_strings
。看起来你不需要区分大小写,所以你可能想要这样做:
if test_string.lower() in (s.lower() for s in list_of_strings)
在你的情况下:
>>> originals = ['0430f244a18146a0815aa1dd4012db46', '0430f244a18146a0815aa1dd40 12db46', '59739CCDA2F15D5AC16DB6695CAE3378']
>>> test = '59739ccda2f15d5ac16db6695cae3378'
>>> if test.lower() in (s.lower() for s in originals):
... print '%s is match, yeih!' % test
...
59739ccda2f15d5ac16db6695cae3378 is match, yeih!