JS中实现获取唯一值uuid

1,196 阅读1分钟

项目中一直遇到需要设定唯一值的情况,之前要求不高的时候,使用timestamp就够用了,但是很多时候这个值也不够用,就需要一套比较完整的实现方案。 参考:stack overflow

1. RFC4122定义规范

                       UUID  = time-low "-" time-mid "-"
                               time-high-and-version "-"
                               clock-seq-and-reserved
                               clock-seq-low "-" node
      time-low               = 4hexOctet
      time-mid               = 2hexOctet
      time-high-and-version  = 2hexOctet
      clock-seq-and-reserved = hexOctet
      clock-seq-low          = hexOctet
      node                   = 6hexOctet
      hexOctet               = hexDigit hexDigit
      hexDigit =
            "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
            "a" / "b" / "c" / "d" / "e" / "f" /
            "A" / "B" / "C" / "D" / "E" / "F"

2. 简化规范

  "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx", 
  // where x is one of [0-9, a-f, A-F] M is one of [1-5], and N is [8, 9, a, or b]

3. 代码实现

export default function uuidV4() {// 默认M为4
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0; // 取整
    const v = c === "x" ? r : (r & 0x3 | 0x8);  
    return v.toString();
  });
}

位运算解析

r
------
& 0011  <--- (0x3).toString(2)
------
| 1000  <--- (0x8).toString(2)

(r & 0x3 | 0x8)确保数据在[1000-1011][8-b]