如何进一步缩短十六进制字符串?

时间:2018-08-08 20:22:26

标签: node.js mongodb encoding

我正在使用MongoDB的内置id字段来标记产品,并且为了易于使用/易于使用,我想将_id字段从看起来像5b69c35ac2cc78c8979a8a9b的十六进制字符串压缩为更短的字符串,并包含所有字母字母(大写和小写)和数字的组合。最好不超过10或12个字符。在Node.JS / MongoDB中是否有实现此目的的常用方法?

2 个答案:

答案 0 :(得分:1)

您可以将它们转换为base64,这会使它们长16个字符。

示例:

Buffer.from('5b69c35ac2cc78c8979a8a9b', 'hex').toString('base64') // W2nDWsLMeMiXmoqb

最好直接访问Buffer-从字符串转换许多ObjectId可能会很昂贵。

答案 1 :(得分:0)

代码5b69c35ac2cc78c8979a8a9b的长度为24个字节(十六进制),这表示在不丢失信息的情况下表示该值所需的绝对最小字节数为12,范围是0-255,这不是我们想要的。

如果我们看看ObjectId,我们可以(也许)消除一些字节:

  • 一个4字节的值,表示自Unix时代以来的秒数,
  • 3字节机器标识符,
  • 2字节的进程ID,和
  • 3字节计数器,以随机值开头。

删除machine identifierprocess id(如果所有ID是由同一进程生成的)将给我们留下7个字节(0-255),这对于在base64甚至base32中进行编码仍然不理想

因此,最好对产品代码使用32位无符号整数,并使用8个字节将其显示为十六进制(可以删除前导零)。

在base64中对这4个字节进行编码无济于事(每3个字节变为4个字节),个人而言,我更喜欢在URL中使用不区分大小写的ID,这只会使我们使用base32

与十六进制相比,为了更好地使用/具有典型性,可以使用z-base-32来编码这4个字节,并且可以填充7个字节而无需填充(7 * 5位= 35位)。