返回 32(或 64)位的 python 哈希函数

Rap*_*ael 5 python

我正在寻找一个返回 32(或 64)位的哈希函数。我尝试了 hashlib 中的 md5。例如:

import hashlib
hashlib.md5(b"H").hexdigest()
Run Code Online (Sandbox Code Playgroud)

给出

c1d9f50f86825a1a2302ec2449c17196

如果没有这样的哈希函数,是否可以从哈希中提取前32位?我试过:

st = hashlib.md5(b"H").hexdigest()
' '.join(format(x, 'b') for x in bytearray(st, 'utf-8'))
Run Code Online (Sandbox Code Playgroud)

将哈希转换为二进制,但它给出:

'1100011 110001 1100100 111001 1100110 110101 110000 1100110 111000 110110 111000 110010 110101 1100001 110001 1100001 110010 110011 110000 110010 1100101 1100011 110010 110100 110100 111001 1100011 110001 110111 110001 111001 110110'
Run Code Online (Sandbox Code Playgroud)

这不可能是正确的,因为它们都是以两个开始的。

Art*_*oul 5

下面我提供了四种获取 32/64 位哈希值的解决方案:整数、字节、十六进制、位(二进制字符串)。

\n

作为十进制整数(大端):

\n

在线尝试一下!

\n
import hashlib\nprint(int.from_bytes(hashlib.sha256(b"H").digest()[:4], \'little\')) # 32-bit int\nprint(int.from_bytes(hashlib.sha256(b"H").digest()[:8], \'little\')) # 64-bit int\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
3866803524\n12578350417885969732\n
Run Code Online (Sandbox Code Playgroud)\n
\n

不使用整数来获取小端顺序的字节,而是执行以下操作:

\n

在线尝试一下!

\n
import hashlib\nprint(hashlib.sha256(b"H").digest()[:4]) # 32-bit, 4 bytes\nprint(hashlib.sha256(b"H").digest()[:8]) # 64-bit, 8 bytes\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
b\'D\\xbdz\\xe6\'\nb\'D\\xbdz\\xe6\\x0fG\\x8f\\xae\'\n
Run Code Online (Sandbox Code Playgroud)\n
\n

也可以获得 32/64 位十六进制值。第一个变体为小端十六进制字节:

\n

在线尝试一下!

\n
import hashlib\nprint(hashlib.sha256(b"H").hexdigest()[:8 ]) # 32-bit, 8  hex chars\nprint(hashlib.sha256(b"H").hexdigest()[:16]) # 64-bit, 16 hex chars\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
44bd7ae6\n44bd7ae60f478fae\n
Run Code Online (Sandbox Code Playgroud)\n

第二个变体为十六进制数字(大端):

\n

在线尝试一下!

\n
import hashlib\nprint(hex(int.from_bytes(hashlib.sha256(b"H").digest()[:4], \'little\'))) # 32-bit int\nprint(hex(int.from_bytes(hashlib.sha256(b"H").digest()[:8], \'little\'))) # 64-bit int\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
0xe67abd44\n0xae8f470fe67abd44\n
Run Code Online (Sandbox Code Playgroud)\n
\n

如果需要,您甚至可以获得位(二进制字符串)。这里的位的计数正好是 32 和 64,并以大端顺序表示。

\n

在线尝试一下!

\n
import hashlib\nprint(bin(int.from_bytes(hashlib.sha256(b"H").digest(), \'little\'))[-32:]) # 32-bit\nprint(bin(int.from_bytes(hashlib.sha256(b"H").digest(), \'little\'))[-64:]) # 64-bit\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
11100110011110101011110101000100\n1010111010001111010001110000111111100110011110101011110101000100\n
Run Code Online (Sandbox Code Playgroud)\n
\n

如果你想计算二进制表示中前导零的数量,那么你可以这样做:

\n

在线尝试一下!

\n
s = \'000010110100101100\'\nprint(next(i for i, e in enumerate(s + \'1\') if e == \'1\'))\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
4\n
Run Code Online (Sandbox Code Playgroud)\n

不要忘记上面哈希的二进制表示是按大端顺序计算的,这意味着最高有效位位于最左边。如果您需要计算最低有效位侧的零位计数,请首先反转字符串,如下所示:

\n

在线尝试一下!

\n
s = \'000010110100101100\'\nprint(s[::-1])\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
001101001011010000\n
Run Code Online (Sandbox Code Playgroud)\n