有没有什么广泛使用的算法将 16 进制数据缩短(用于压缩哈希值)?

2019-11-23 14:42:31 +08:00
 nyse

需求是这样的,有个数据表,存放大量哈希值。

无论是 md5 还是 sha1 的长度都比较长,而且他们的取值范围都是 16 进制数( 0-9,a-f )

有没有什么广泛使用的算法,用( 0-9,a-z,A-Z )来表示他们,从而缩短他们的长度。

注:

  1. 之所以要这样缩短的主要原因是为了减少数据库空间占用;

  2. 这个算法最好是使用的比较广泛的,因为这个需求自己写一个程序映射应该也可以,但还是希望能找到一个更加广泛通用的解决方案;

  3. 这个算法要能互逆

6031 次点击
所在节点    算法
28 条回复
wlh233
2019-11-23 17:53:11 +08:00
@also24 虽然结论是对的,你这两次都没算对啊,不用 +2 了,已经补过了,就是 24
xmadi
2019-11-23 18:01:36 +08:00
使用 36 进制(0-9,a-z,不区分大小写) 或者 base64 如果觉得 base64 的两个符号太麻烦 可以使用 base62 ( 0-9,a-z,A-Z ) 就是楼主想要的东西
imn1
2019-11-23 18:08:53 +08:00
难道是彩虹表?
keepeye
2019-11-23 18:13:44 +08:00
import string
digs = string.digits + string.ascii_letters + '!@#$%^&*()_+:;<>,.?/[]{}'
def int2base(x, base):
if x < 0:
sign = -1
elif x == 0:
return digs[0]
else:
sign = 1

x *= sign
digits = []

while x:
digits.append(digs[int(x % base)])
x = int(x / base)

if sign < 0:
digits.append('-')

digits.reverse()

return ''.join(digits)


def main():
src = b'test'
e = hashlib.md5(src).digest()
a1 = struct.unpack('q', a[0:8])
a2 = struct.unpack('q', a[8:])
print(int2base(a1[0], 86) + int2base(a2[0], 86)) # 最终输出 20 个字符
lululau
2019-11-23 18:47:58 +08:00
@hdbzsgm 你确定明白楼主说的问题?
also24
2019-11-23 23:01:52 +08:00
@wlh233 #21
前面补的两个 0 字节是为了凑够 3 的倍数
后面补的两个等号是代表前面补了两个字节
wlh233
2019-11-24 12:58:07 +08:00
@also24 https://tools.ietf.org/html/rfc3548#section-7 所以多算了啊,补齐之后没用上的零比特最后变成等号了,总字节数就是这么多了,不用再加了
also24
2019-11-24 22:59:59 +08:00
@wlh233 #27
确实我的错,我把两种思路混合理解了。

思路一:
先补 4 bit 『 0000 』,再补 2 byte 『==』,这种情况下是
(128+4) / 3 * 4 = 176bit
176 + 2*8 =192bit

思路二:
先补 16 bit 『 0000 000000 000000 』,转换出来末尾多了『 AA 』,替换为『==』,这种情况下是
(128+16) /3 * 4 = 192bit
192 - 2*8 + 2*8 = 192bit


我忽略了 『==』是由 『 AA 』 替换而来,而不是直接补上。

感谢指正

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/622413

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX