uuid 创建中按位运算符的替代方案

Posted

技术标签:

【中文标题】uuid 创建中按位运算符的替代方案【英文标题】:Alternative to bitwise operators in uuid creation 【发布时间】:2017-05-04 14:01:42 【问题描述】:

我正在使用以下打字稿方法来生成UUIDs。代码本身基本上就是这个*** answer的打字稿版本。

generateUUID(): string 
    let date = new Date().getTime();
    if (window.performance && typeof window.performance.now === 'function') 
        date += performance.now();
    
    let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) 
        let r = (date + Math.random() * 16) % 16 | 0;
        date = Math.floor(date / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    );
    return uuid;
;

我们的开发团队使用TSLint 来保持代码干净,并且我们有一条规则禁止使用bitwise operators。我不知道如何在不损害 UUID 生成器的加密方面的情况下重写此代码。这段代码怎么可能改写,或者这根本没有意义?

【问题讨论】:

为什么你有一个禁止按位运算符的规则?这很奇怪。 我也觉得这很奇怪,但这不是我的决定。 TSLint 规则是错误。不是代码 将其包装在:/* tslint:disable *//* tslint:enable */(或者更具体地了解我们“接受”的规则,请参阅 palantir.github.io/tslint/usage/rule-flags) 添加一点背景知识:在 javascript 中通常不鼓励使用位运算符,因为它们可能与逻辑运算符混淆。考虑1 && 1 === 11 & 1 === 0 【参考方案1】:

TSLint 强调这一点的原因是,位运算符更有可能被意外使用(例如,在 if 语句中)而不是故意使用它。

告诉 TSLint 你真的打算使用位运算符应该是完全可以接受的。只需将它们包装在特殊的 TSLint cmets 中即可。 :

/* tslint:disable:no-bitwise */

// Your code...

/* tslint:enable:no-bitwise */

【讨论】:

你可以把这个注释放在下一行: // tslint:disable-next-line:no-bitwise【参考方案2】:
export abstract class SystemGuid
    constructor() 
      // no-op
    
    public static UUID(): string 
      if (typeof window !== 'undefined' && typeof window.crypto !== 'undefined' 
      && typeof window.crypto.getRandomValues !== 'undefined') 
        const buf: Uint16Array = new Uint16Array(8);
        window.crypto.getRandomValues(buf);
        return (
          this.pad4(buf[0]) +
          this.pad4(buf[1]) +
          '-' +
          this.pad4(buf[2]) +
          '-' +
          this.pad4(buf[3]) +
          '-' +
          this.pad4(buf[4]) +
          '-' +
          this.pad4(buf[5]) +
          this.pad4(buf[6]) +
          this.pad4(buf[7])
        );
       else 
        return (
          this.random4() +
          this.random4() +
          '-' +
          this.random4() +
          '-' +
          this.random4() +
          '-' +
          this.random4() +
          '-' +
          this.random4() +
          this.random4() +
          this.random4()
        );
      
    
    private static pad4(num: number): string 
      let ret: string = num.toString(16);
      while (ret.length < 4) 
        ret = '0' + ret;
      
      return ret;
    
    private static random4(): string 
      return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    
    public static generate(): string 
      return SystemGuid.UUID();
    
   

【讨论】:

以上是关于uuid 创建中按位运算符的替代方案的主要内容,如果未能解决你的问题,请参考以下文章

c语言中按位逻辑运算符位移运算符

c语言中按位逻辑运算符位移运算符

如何在 VB.NET 中按位移位?

仅使用按位运算反转数字

为啥 tslint 中不允许按位运算符?

非数字的按位运算