将 SHA-1 存储在数据库中少于 space 的 40 个十六进制数字
Store SHA-1 in database in less space than the 40 hex digits
我正在使用哈希算法为数据库创建主键 table。我使用的 SHA-1 算法非常适合我的目的。该数据库甚至提供了 SHA-1 的实现。计算散列的函数返回一个 40 个字符的十六进制值。因此,我将十六进制字符存储在 char(40)
列中。
table 会有很多行,>= 200 Mio。行,这就是为什么我正在寻找存储哈希的数据密集度较低的方法。 40 个字符乘以 ~200 Mio。行将需要一些 GB 的存储空间...因为十六进制是 base16 我想我可以尝试将它存储在 base 256 中希望将所需的字符数量减少到大约 20 个字符。您有关于使用 base 256 进行压缩的技巧或论文吗?
- 将其存储为 blob:每个字符存储 8 位数据而不是 4 位是 2 倍压缩(不过您需要一些方法来转换它),
- 删掉一些字符:你有 160 位,但 128 位对于唯一密钥就足够了,即使宇宙结束了,而且对于大多数用途来说,80 位甚至就足够了(你不需要密码保护)。如果你有 anti-collision 算法,使用 36 或 40 位就足够了。
SHA-1 值是 20 个字节。这 20 个字节中的所有位都是有效的,无法压缩它们。通过以十六进制表示法存储字节,您浪费了一半 space — 存储一个字节恰好需要两个十六进制数字。所以你不能压缩底层值,但是你可以使用比十六进制更好的编码。
是正确答案。那是 base 256。您将每个字节存储为该字节,没有编码会产生一些开销。浪费space:0.
如果由于某种原因您不能这样做并且您需要使用可打印的字符串,那么您可以通过使用更紧凑的编码比十六进制更好。对于十六进制,存储要求是最小值的两倍(假设每个字符存储为一个字节)。您可以使用 Base64 将存储要求提高到每 3 个字节 4 个字符,即您需要 28 个字符来存储该值。事实上,假设你知道长度是 20 个字节而不是 21 个字节,base64 编码总是以 =
结尾,所以你只需要存储 27 个字符 和解码前恢复尾部 =
。
您可以通过使用更多字符来进一步改进编码。 Base64 使用可用的 256 字节值中的 64 个代码点。 ASCII(事实上的便携式)有 95 个可打印字符(包括 space),但没有通用的“base95”编码,您必须自己编写。 Base85 是一个中间选择,它在实践中确实有一些用处,可以让您将 20 字节的值存储在 25 个可打印的 ASCII 字符中。
我正在使用哈希算法为数据库创建主键 table。我使用的 SHA-1 算法非常适合我的目的。该数据库甚至提供了 SHA-1 的实现。计算散列的函数返回一个 40 个字符的十六进制值。因此,我将十六进制字符存储在 char(40)
列中。
table 会有很多行,>= 200 Mio。行,这就是为什么我正在寻找存储哈希的数据密集度较低的方法。 40 个字符乘以 ~200 Mio。行将需要一些 GB 的存储空间...因为十六进制是 base16 我想我可以尝试将它存储在 base 256 中希望将所需的字符数量减少到大约 20 个字符。您有关于使用 base 256 进行压缩的技巧或论文吗?
- 将其存储为 blob:每个字符存储 8 位数据而不是 4 位是 2 倍压缩(不过您需要一些方法来转换它),
- 删掉一些字符:你有 160 位,但 128 位对于唯一密钥就足够了,即使宇宙结束了,而且对于大多数用途来说,80 位甚至就足够了(你不需要密码保护)。如果你有 anti-collision 算法,使用 36 或 40 位就足够了。
SHA-1 值是 20 个字节。这 20 个字节中的所有位都是有效的,无法压缩它们。通过以十六进制表示法存储字节,您浪费了一半 space — 存储一个字节恰好需要两个十六进制数字。所以你不能压缩底层值,但是你可以使用比十六进制更好的编码。
如果由于某种原因您不能这样做并且您需要使用可打印的字符串,那么您可以通过使用更紧凑的编码比十六进制更好。对于十六进制,存储要求是最小值的两倍(假设每个字符存储为一个字节)。您可以使用 Base64 将存储要求提高到每 3 个字节 4 个字符,即您需要 28 个字符来存储该值。事实上,假设你知道长度是 20 个字节而不是 21 个字节,base64 编码总是以 =
结尾,所以你只需要存储 27 个字符 和解码前恢复尾部 =
。
您可以通过使用更多字符来进一步改进编码。 Base64 使用可用的 256 字节值中的 64 个代码点。 ASCII(事实上的便携式)有 95 个可打印字符(包括 space),但没有通用的“base95”编码,您必须自己编写。 Base85 是一个中间选择,它在实践中确实有一些用处,可以让您将 20 字节的值存储在 25 个可打印的 ASCII 字符中。