我正在寻找一种方法来将磁盘上文件的路径缩短为固定长度的字符串,这样我就可以通过它的绝对路径或通过这个别名来访问它。
我一直在研究使用UUID作为字典的键,所有路径都有别名,但我发现它们太长了,并希望它在5-10个字符之间。我也一直在寻找哈希,并考虑将实际路径哈希到一些有用的字符串,我可以直接用作别名,然后将值存储在磁盘上的表中。我在散列方面非常新鲜,但据我所知,然后可以通过简单地重新移动路径来获取密钥,然后将密钥输入到表中将为我提供值而不需要将其完全加载到内存中或者从磁盘上完全读取。
最终目标是,在我的自定义浏览器中,可以使用以下命令指向同一文件:
"/root/folder1/folder2/folder3/file.png" and e.g. "MTEzNDUy"
可能的字典看起来像这样,注意固定长度键。
{"MSFjak5m": "/root/folder1/folder2/file.png",
"sofkAkfg": "/root/file.exe",
"ASg5OFA3": "/root/file2.so",
"fFAgeEGH": "/root/file5.so"}
在磁盘上有一个查找表是可以接受的,但更好的是如果我可以简单地将路径压缩成这样的别名。最好的解决方案是让表能够直接使用散列来查找值,而不是必须存储键/值对,因为它似乎意味着我要做一个哈希来获取别名,然后字典与执行另一个基于该键的哈希值来查找值..如果我错了请纠正我。
条目数量约为10万,所有操作最好保留在Python下。
由于
修改
通过编码MD5哈希并将结果的一部分用作键来执行一些测试。我发现使用前4个字符给出了每600个条目大约1个的碰撞率。使用前5个使我的碰撞率为1/40 000。
这些条目将一次创建一个,正常运行时的速率约为5 /天,高峰时段的最高速率为100 /天,永远不会超过最多1 000 000个条目。
考虑到这一点,我很可能通过将它与已经存储的内容进行比较来检查我得到的哈希的唯一性,并且只需通过它们来处理它,A:警告用户不能创建路径和他必须选择另一个名称,或者B:增加哈希中允许的字符数,直到找到唯一的哈希值。其中任何一个在这一点上都是可以接受的。
(旁注,正在检查存储哈希表的哈希值是否违反了使用哈希函数的目的?)
Windows上的测试代码。仅针对文件夹进行测试,我的驱动器上大约有5万个。
import hashlib
from random import shuffle
def shuffle_string(word):
word = list(word)
shuffle(word)
return ''.join(word)
tests = 10
chars = 5
_entries = 0
_hashes = {}
for test in xrange(tests):
for path, _d, _f in os.walk('c:/'):
unique_path = "%s%i" % (path, test)
key = hashlib.md5(unique_path).digest().encode('base64').strip()[:chars]
_hashes[key] = unique_path
_entries += 1
total_collisions = _entries-len(_hashes)
print "%s Entries \nTests: %s\nChars: %s" % (_entries, tests, chars)
if total_collisions:
average_collisions = total_collisions / float(tests)
odds = _entries / float(average_collisions)
print "%s collisions per %s entries" % (average_collisions, _entries)
print "odds: 1 in %s" % odds
if odds:
print "chance: %s%%" % (1 / (_entries / float(average_collisions)))
else:
print "No collisions occured"