Alternative to bitwise operators in uuid creation
Asked Answered
K

2

6

I'm using the following typescript method to generate UUIDs. The code itself is basically the typescript version of this stackoverflow 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;
};

Our development team uses TSLint to keep the code clean and we have a rule that forbids to use bitwise operators. I have no idea how to rewrite this code without harming the cryptographic aspect of the UUID generator. How can this piece of code be rewritten or doesn't this make sense at all?

Kress answered 19/12, 2016 at 13:44 Comment(6)
Why on earth do you have a rule that forbids bitwise operators? That's weird.Unpolite
I think it is weird as well, but this was not my decision.Kress
The TSLint rule is the bug. Not the codeGauvin
Wrap it in: /* tslint:disable */ and /* tslint:enable */ (Or be more specific about the rule we are "accepting", see palantir.github.io/tslint/usage/rule-flags )Coalfield
To add a bit of background: The use of bitwise operators is often discouraged in javascript because they can be confused with logical operators. Consider 1 && 1 === 1 and 1 & 1 === 0.Profluent
@Profluent I think it is a good practive to forbid those bitwise operators because someone could really forget a character of some logical operator. It might seem best to deactivate the rule for the uuid code though?Kress
C
19

The reason TSLint highlights this is because it is more likely the bitwise operator has been used accidentally (for instance, in an if statement) than to have used it on purpose.

It should be quite acceptable to tell TSLint that you really meant to use a bitwise operator. Just wrap them in special TSLint comments. :

/* tslint:disable:no-bitwise */

// Your code...

/* tslint:enable:no-bitwise */
Coalfield answered 19/12, 2016 at 14:0 Comment(1)
you can put this comment just for the next line: // tslint:disable-next-line:no-bitwiseTedie
N
1
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();
    }
   }
Nostoc answered 18/12, 2018 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.