如何缩短 UUID V4 而不使其不唯一/可猜测

use*_*521 5 postgresql uuid cryptography probability node.js

我必须生成独特的 URL 部分,该部分将“无法猜测”和“抵抗”蛮力攻击。它也必须尽可能短:)并且所有生成的值必须具有相同的长度。我正在考虑使用 UUID V4,它可以用 32 个(不带连字符)十六进制字符表示,de305d5475b4431badb2eb6b9e546014但它有点太长了。所以我的问题是如何生成一些unqiue,可以用每个生成的值长度相同且短于 32 个字符的url字符来表示。(在 node.js 或 pgpsql 中)

Kee*_*ker 8

v4()将生成一个转换为十六进制字符串的大量数字。在 Node.js 中,您可以使用Buffer将字符串转换为更小的 base64 编码:

import { v4 } from 'uuid';

function getRandomName() {

    let hexString = v4();
    console.log("hex:   ", hexString);
    
    // remove decoration
    hexString = hexString.replace(/-/g, "");
    
    let base64String = Buffer.from(hexString, 'hex').toString('base64')
    console.log("base64:", base64String);
    
    return base64String;
}
Run Code Online (Sandbox Code Playgroud)

其中产生:

hex:    6fa1ca99-a92b-4d2a-aac2-7c7977119ebc
base64: b6HKmakr

hex:    bd23c8fd-0f62-49f4-9e51-8b5c97601a16
base64: vSPI/Q9i
Run Code Online (Sandbox Code Playgroud)

  • `hexString.replace("-", "")` 上面的代码中有一个错误,它没有正确删除连字符,因此 `Buffer.From` 函数会截断输出,你会得到一些奇怪的缩短的 base64。应该使用`uuid.replace(/-/g, '');` (2认同)
  • `6fa1ca99-a92b-4d2a-aac2-7c7977119ebc` 生成 `b6HKmakrTSqqwnx5dxGevA==` (2认同)

ral*_*alh 5

UUID v4 本身并不能真正保证唯一性。两个随机生成的 UUID 发生冲突的可能性非常非常小。这就是为什么它们需要这么长——这减少了冲突的机会。所以你可以让它更短,但你做得越短,它实际上就越有可能不是唯一的。UUID v4 的长度为 128 位,因为这通常被认为“足够唯一”。