在Python中比较两个字符串

0 投票
3 回答
3259 浏览
提问于 2025-04-17 19:07

我需要比较两个字符串,或者至少从一个字符串中找到另一个字符串的字符序列。这两个字符串包含文件的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 个回答

0

给定的输入是:

原始的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)

或者你找到的任何最易读的等效方式。

0

看起来你遇到的问题是因为字母的大小写不匹配。你可以试试:

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()
0

基本上,你想要用这个方法: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!

撰写回答