可能重复:
如何使用 Python 制作唯一的短 URL?
我正在寻找一种方法,将磁盘上文件的路径缩短为固定长度的字符串,以便我可以通过它的绝对路径或通过这个别名来访问它。
我一直在研究使用 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"}
在磁盘上有一个查找表是可以接受的,但如果我可以简单地将路径压缩成这样的别名,那就更好了。最好的解决方案是让表能够直接使用散列来查找一个值,而不是必须存储键/值对,因为这似乎意味着我会做一个散列来获取别名,然后字典基于该键执行另一个哈希以查找值..如果我错了,请纠正我。
条目数约为 100 000,所有操作最好保留在 Python 下。
谢谢
编辑
使用 MD5 哈希编码并使用部分结果作为键执行了一些测试。我发现使用前 4 个字符给我每 600 个条目大约 1 个的碰撞率。使用前 5 个给我的碰撞率为 1/40 000。
这些条目将一次创建一个,在正常操作下以大约 5 个/天的速率创建,在高峰时段的最大速率为 100 个/天,永远不会超过最多 1 000 000 个条目。
考虑到这一点,我很可能会通过将它与已经存储的内容进行比较来检查我得到的哈希的唯一性,然后简单地处理它,A:警告用户无法创建路径并且他必须选择另一个名称,或 B:增加散列中允许的字符数,直到找到唯一的散列。在这一点上,其中任何一个似乎都可以接受。
(旁注,根据存储的哈希表检查哈希是否违背了使用哈希函数的目的?)
Windows 上的测试代码。仅针对文件夹进行测试,我的驱动器上有大约 50 000 个。
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"