• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import {randomBytes} from 'crypto';
17
18import type {INameGenerator, NameGeneratorOptions} from './INameGenerator';
19
20/**
21 * @Desc: a name generator which used given length to generate random length-limiting name
22 */
23export class HexNameGenerator implements INameGenerator {
24  private readonly mHexLength: number;
25  private readonly mReservedNames: Set<string>;
26  private readonly mWithPrefixSuffix: boolean;
27
28  private readonly mHexPrefix: string;
29  private readonly mHexSuffix: string;
30
31  private mHistoryNameList: string[];
32
33  /**
34   * constructor for hex name generator
35   * @param options: {hexLength: number}
36   */
37  constructor(options?: NameGeneratorOptions) {
38    this.mHexLength = 4;
39    if (options && options.hexLength) {
40      this.mHexLength = options.hexLength;
41    }
42
43    this.mWithPrefixSuffix = options && options.hexWithPrefixSuffix;
44    this.mReservedNames = options?.reservedNames;
45
46    this.mHexPrefix = '_0x';
47    this.mHexSuffix = '_';
48
49    this.mHistoryNameList = [];
50  }
51
52  private generateName(): string {
53    let buffer: Buffer = randomBytes(this.mHexLength);
54    let generatedName: string = buffer.toString('hex');
55    if (this.mWithPrefixSuffix) {
56      return this.mHexPrefix + generatedName + this.mHexSuffix;
57    }
58
59    return generatedName;
60  }
61
62  /**
63   * @return: null for end
64   */
65  public getName(): string {
66    while (true) {
67      let generatedName: string = this.generateName();
68      if (!this.mHistoryNameList.includes(generatedName) && !this.mReservedNames?.has(generatedName)) {
69        this.mHistoryNameList.push(generatedName);
70        return generatedName;
71      }
72      const baseHex: number = 16;
73      if (this.mHistoryNameList.length >= Math.pow(baseHex, this.mHexLength)) {
74        return null;
75      }
76    }
77  }
78
79  public reset(): void {
80    this.mHistoryNameList.length = 0;
81  }
82}
83