• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

earthnutDev / a-js-tools / 14013421607

22 Mar 2025 11:41PM UTC coverage: 90.722% (+0.1%) from 90.625%
14013421607

push

github

lmssee
version: 0.1.1 2025-03-23 07:41:28 - There are no feature updates

78 of 89 branches covered (87.64%)

Branch coverage included in aggregate %.

24 of 25 new or added lines in 4 files covered. (96.0%)

3 existing lines in 1 file now uncovered.

98 of 105 relevant lines covered (93.33%)

6.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.95
/src/getRandomString.ts
1
/**
2
 *
1✔
3
 *
1✔
4
 * @packageDocumentation
5
 * @module @a-js-tools/get-random-string
6
 * @license MIT
7
 */
8
import { isNaN, isNumber, isPlainObject } from 'a-type-of-js';
9
import { randomBytes } from 'crypto';
10

11
/**
1✔
12
 *
1✔
13
 *  Random string generation function
14
 *
15
 *
16
 *
17
 */
18
export type RandomStringOptions = {
19
  /**
20
   * string length
21
   * @default 32
22
   */
23
  length?: number;
24
  /**
11✔
25
   * String optional characters
26
   * @default '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
100✔
27
   */
28
  chars?: string;
29
  /**
30
   * Whether or not to include numbers
31
   * @default false
32
   */
33
  includeNumbers?: boolean;
34
  /**
35
   * Whether or not to include capital letters
36
   * @default false
37
   */
38
  includeUppercaseLetters?: boolean;
5✔
39
  /**
40
   * Whether or not it contains special characters
6✔
41
   * @default false
42
   */
43
  includeSpecial?: boolean;
44
  /**
45
   * String type
46
   * @default 'string''
47
   */
48
  type?: 'string' | 'uuid';
49
};
50

51
/**
6!
NEW
52
 *
×
53
 *  Random string generation
54
 *
6✔
55
 *  @param   length - string length
56
 *  @returns  - A random string of characters generated
1✔
57
 *
58
 *
6✔
59
 */
5✔
60
export function getRandomString(length?: RandomStringOptions | number): string {
5!
61
  //   验证输入参数
62
  if (
63
    // 参数类型错误
6✔
64
    (!isPlainObject(length) && !isNumber(length)) ||
65
    // 参数为 NaN
6✔
66
    (isNumber(length) && isNaN(length)) ||
2✔
67
    // 参数为数字时为无穷大
68
    (isNumber(length) && !isFinite(length)) ||
69
    // 参数为数字时为非整数
6✔
70
    (isNumber(length) && !Number.isInteger(length)) ||
2✔
71
    // 参数为数字时为负数
72
    (isNumber(length) && Number.isInteger(length) && length < 1) ||
73
    // 参数为数值然而却小于 1
6✔
74
    (isNumber(length) && length < 1) ||
2✔
75
    (isPlainObject(length) && isNumber(length.length) && length.length < 1)
76
  ) {
77
    throw new TypeError('Invalid argument type (getRandomString)');
6✔
78
  }
6✔
79

80
  const initOptions: RandomStringOptions & {
6✔
81
    length: number;
82
    chars: string;
20✔
83
    chars2: string;
84
    chars3: string;
85
  } = {
86
    length: 32,
87
    chars: 'abcdefghijklmnopqrstuvwxyz',
88
    chars2: '0123456789',
89
    chars3: '!@#$%^&*()_+~`|}{[]:;?><,./-=',
90
    type: 'string',
91
    includeUppercaseLetters: false,
92
    includeNumbers: false,
93
    includeSpecial: false,
94
  };
95

96
  /// 生成 UUID
97
  if (initOptions.type === 'uuid') {
98
    return crypto.randomUUID();
6✔
99
  }
6✔
100

6✔
101
  if (isNumber(length) && Number.isInteger(length) && length > 0) {
162✔
102
    // 验证输入参数
124✔
103
    Object.assign(initOptions, { length });
104
  }
38✔
105

6✔
106
  if (isPlainObject(length)) {
107
    Object.assign(initOptions, length);
108
    initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
109
  }
5✔
110
  /**  生成随机字符串  */
111
  const templateCharsArr: string[] = initOptions.chars.split('');
112
  // 添加大写字母
113
  if (initOptions.includeUppercaseLetters) {
114
    interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
115
  }
116
  // 添加数字
117
  if (initOptions.includeNumbers) {
118
    interleaveString(templateCharsArr, initOptions.chars2);
119
  }
120
  // 添加特殊字符
121
  if (initOptions.includeSpecial) {
122
    interleaveString(templateCharsArr, initOptions.chars3);
123
  }
124

125
  // 使用密码学安全的随机数生成器
126
  const bytes = randomBytes(initOptions.length);
127
  let result = '';
128
  /**  获取最后的 chars 数据  */
129
  const chars = templateCharsArr.join('');
130

131
  // 循环遍历
132
  bytes.forEach(byte => (result += chars.charAt(byte % chars.length)));
133

134
  /**
135
   *
136
   *  字符串交叉函数
137
   *
138
   *  非线形串交叉,对相交叉
139
   *
140
   *  @param  str1 - 字符串1
141
   *  @param  str2 - 字符串2
142
   *  @returns - 交叉后的字符串
143
   *  @example
144
   *  ```ts
145
   *  interleaveString('abc', '123') // 'a1b2c3'
146
   *  ```
147
   */
148
  function interleaveString(str1: string[], str2: string) {
149
    const str1Length = str1.length,
150
      str2Length = str2.length;
151
    const maxLength = Math.max(str1Length, str2Length);
152

153
    for (let i = 0; i < maxLength; i++) {
154
      if (i < str1Length && str2[i] !== undefined) {
155
        str1[i] += str2[i];
156
      } else if (i < str2Length) {
157
        str1[i] = str2[i];
158
      }
159
    }
160
  }
161
  return result;
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc