繁体   English   中英

JavaScript/TypeScript:将 UUID 从最高有效位 (MSB)/最低有效位 (LSB) 表示形式转换为字符串

[英]JavaScript/TypeScript: Convert UUID from most significant bits (MSB)/least significant bits (LSB) representation to string

为了在使用协议缓冲区传递 UUID 时节省空间,我们使用 MSB/LSB 表示形式发送它们,两个 64 位long值。

message Uuid {
  sfixed64 msb = 1;
  sfixed64 lsb = 2;
} 

这些是简单的 go 往返于 Java,

UUID id = UUID.fromString("eb66c416-4739-465b-9af3-9dc33ed8eef9");
long msb = id.getMostSignificantBits();
long lsb = id.getLeastSignificantBits();
System.out.println(msb + ", " + lsb);
  // -1484283427208739237, -7281302710629372167

System.out.println(new UUID(msb, lsb));
  // eb66c416-4739-465b-9af3-9dc33ed8eef9

但是,由于 JavaScript 的number只上升到 2 53 - 1,我无法在我的 TypeScript 客户端中将 MSB/LSB 格式转换回string 这可能吗?

查看 Java UUIDtoString()方法以获取灵感,

public String toString() {
  return (digits(mostSigBits >> 32, 8) + "-" +
    digits(mostSigBits >> 16, 4) + "-" +
    digits(mostSigBits, 4) + "-" +
    digits(leastSigBits >> 48, 4) + "-" +
    digits(leastSigBits, 12));
}

private static String digits(long val, int digits) {
  long hi = 1L << (digits * 4);
  return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}

我们可以使用BigInt来做同样的事情。 这假设 Node 10.8+(用 14.15.5 测试),TypeScript 面向 ES2020+,并且具有此浏览器兼容性

注意:如果你得到“BigInt literals are not available...”用BigInt包装所有以n结尾的文字(例如,使用BigInt(32)代替32n )。

export function toUuidString(lsb: bigint, msb: bigint): string {
  return `${digits(msb >> 32n, 8n)}-${digits(msb >> 16n, 4n)}-${digits(
    msb,
    4n
  )}-${digits(lsb >> 48n, 4n)}-${digits(lsb, 12n)}`;
}

function digits(val: bigint, ds: bigint): string {
  const hi = 1n << (ds * 4n);
  return (hi | (val & (hi - 1n))).toString(16).substring(1);
}

还有一个示例测试,注意 msb/lsb 作为string s 传递给BigInt

it('converts UUID from msb/lsb to string', () => {
  expect(
    toUuidString(
      BigInt('-1160168401362026442'),
      BigInt('-6694969989912915968')
    )
  ).toEqual('a316b044-0157-1000-efe6-40fc5d2f0036');
});

最后一块是协议缓冲区。 默认情况下, google-protobufnumber用于 64 位floatint值,这会导致Number.MAX_VALUE或 2 53 - 1 以上溢出。为避免这种情况,请在 64 位字段上使用jstype注释,

message Uuid {
    sfixed64 msb = 1 [jstype = JS_STRING];
    sfixed64 lsb = 2 [jstype = JS_STRING];
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM