0
# rstr - Random String Generator
1
2
A comprehensive Python library for generating random strings from various alphabets and regular expressions. rstr provides both simple random string generation and advanced pattern-based string creation, supporting both secure (SystemRandom) and fast (Mersenne Twister) random number generation for different use cases from development testing to cryptographic applications.
3
4
## Package Information
5
6
- **Package Name**: rstr
7
- **Language**: Python
8
- **Installation**: `pip install rstr`
9
- **Python Compatibility**: 3.7+
10
11
## Core Imports
12
13
```python
14
import rstr
15
```
16
17
For class-based usage:
18
19
```python
20
from rstr import Rstr, RstrBase, SameCharacterError
21
# Note: Rstr is an alias for Xeger class
22
```
23
24
For direct imports:
25
26
```python
27
from rstr import rstr, xeger, letters, digits, uppercase, lowercase
28
# All alphabet functions are available for direct import
29
```
30
31
Complete available imports:
32
33
```python
34
from rstr import (
35
# Classes
36
Rstr, # Main class (alias for Xeger)
37
RstrBase, # Base class
38
SameCharacterError, # Exception class
39
40
# Core functions
41
rstr, xeger,
42
43
# Alphabet functions
44
printable, letters, uppercase, lowercase, digits, punctuation,
45
nondigits, nonletters, whitespace, nonwhitespace, normal, word,
46
nonword, unambiguous, postalsafe, urlsafe, domainsafe
47
)
48
```
49
50
## Basic Usage
51
52
Simple random string generation:
53
54
```python
55
import rstr
56
57
# Generate random string from custom alphabet
58
result = rstr.rstr('ABC') # Returns string like 'AACAACCB'
59
60
# Generate exact length
61
result = rstr.rstr('ABC', 4) # Returns 4-character string like 'ACBC'
62
63
# Generate regex-based string
64
postal_code = rstr.xeger(r'[A-Z]\d[A-Z] \d[A-Z]\d') # Returns 'R6M 1W5'
65
```
66
67
## Core Random String Generation
68
69
### Primary Function
70
71
```python { .api }
72
def rstr(
73
alphabet: Iterable[str],
74
start_range: Optional[int] = None,
75
end_range: Optional[int] = None,
76
include: Sequence[str] = '',
77
exclude: Sequence[str] = ''
78
) -> str
79
```
80
81
Generates random strings from the specified alphabet.
82
83
**Parameters:**
84
- `alphabet`: Characters to choose from (string, list, or tuple)
85
- `start_range`: Minimum length (default: 1, or exact length if end_range not specified)
86
- `end_range`: Maximum length (default: 10 if start_range not specified)
87
- `include`: Characters that must appear in the result
88
- `exclude`: Characters to exclude from alphabet
89
90
**Returns:** Random string meeting the specified criteria
91
92
**Example:**
93
```python
94
# Range of lengths
95
rstr.rstr('ABC', 5, 10) # 5-10 character string
96
97
# Include specific characters
98
rstr.rstr('ABC', include='&') # Will contain '&'
99
100
# Exclude characters
101
rstr.rstr(string.digits, exclude='5') # Digits except '5'
102
```
103
104
### Regex-based String Generation
105
106
```python { .api }
107
def xeger(string_or_regex: Union[str, Pattern[str]]) -> str
108
```
109
110
Generates random strings matching a regular expression pattern.
111
112
**Parameters:**
113
- `string_or_regex`: Regular expression pattern (string or compiled Pattern)
114
115
**Returns:** Random string matching the pattern
116
117
**Example:**
118
```python
119
# Canadian postal code
120
rstr.xeger(r'[A-Z]\d[A-Z] \d[A-Z]\d')
121
122
# Email-like pattern
123
rstr.xeger(r'[a-z]{3,8}@[a-z]{3,8}\.(com|org|net)')
124
```
125
126
## Predefined Alphabet Functions
127
128
All alphabet functions accept the same parameters as `rstr()`:
129
130
```python { .api }
131
def printable(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
132
def letters(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
133
def uppercase(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
134
def lowercase(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
135
def digits(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
136
def punctuation(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
137
def nondigits(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
138
def nonletters(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
139
def whitespace(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
140
def nonwhitespace(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
141
def normal(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
142
def word(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
143
def nonword(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
144
def unambiguous(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
145
def postalsafe(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
146
def urlsafe(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
147
def domainsafe(start_range: Optional[int] = None, end_range: Optional[int] = None, include: Sequence[str] = '', exclude: Sequence[str] = '') -> str
148
```
149
150
### Alphabet Descriptions
151
152
- **printable**: All printable characters (string.printable)
153
- **letters**: ASCII letters (a-z, A-Z)
154
- **uppercase**: Uppercase letters (A-Z)
155
- **lowercase**: Lowercase letters (a-z)
156
- **digits**: Numeric digits (0-9)
157
- **punctuation**: Punctuation marks (string.punctuation)
158
- **nondigits**: Letters + punctuation (excludes digits)
159
- **nonletters**: Digits + punctuation (excludes letters)
160
- **whitespace**: Whitespace characters (space, tab, newline, etc.)
161
- **nonwhitespace**: Printable characters except whitespace
162
- **normal**: Letters + digits + space
163
- **word**: Letters + digits + underscore (regex \\w equivalent)
164
- **nonword**: Characters not in word set (regex \\W equivalent)
165
- **unambiguous**: Letters + digits excluding similar characters (0, O, 1, l, I)
166
- **postalsafe**: Characters safe for postal addresses (letters, digits, space, ., #, -, /)
167
- **urlsafe**: URL-safe unreserved characters (letters, digits, -, ., _, ~)
168
- **domainsafe**: Domain name safe characters (letters, digits, -)
169
170
**Example:**
171
```python
172
# Generate random email username
173
username = rstr.letters(5, 12)
174
175
# Generate unambiguous identifier
176
id_code = rstr.unambiguous(8)
177
178
# Generate domain-safe string
179
domain = rstr.domainsafe(3, 15)
180
```
181
182
## Class-based Usage
183
184
### RstrBase Class
185
186
```python { .api }
187
class RstrBase:
188
def __init__(self, _random: Random, **custom_alphabets: str) -> None
189
```
190
191
Base class for random string generation functionality.
192
193
**Parameters:**
194
- `_random`: Random number generator instance (required)
195
- `**custom_alphabets`: Custom alphabet definitions as keyword arguments
196
197
### Xeger Class
198
199
```python { .api }
200
class Xeger(RstrBase):
201
def __init__(self, _random: Random = random, **custom_alphabets: str) -> None
202
```
203
204
Main class implementing random string generation from regular expressions and alphabets.
205
206
**Parameters:**
207
- `_random`: Random number generator instance (default: standard random module)
208
- `**custom_alphabets`: Custom alphabet definitions as keyword arguments
209
210
### Rstr Class
211
212
```python { .api }
213
Rstr = Xeger # Alias for Xeger class
214
```
215
216
`Rstr` is an alias for the `Xeger` class. Use either name interchangeably.
217
218
**Parameters:**
219
- `_random`: Random number generator instance (default: standard random module)
220
- `**custom_alphabets`: Custom alphabet definitions as keyword arguments
221
222
**Examples:**
223
224
```python
225
from random import SystemRandom
226
from rstr import Rstr, RstrBase
227
228
# Using RstrBase (requires explicit random instance)
229
base_rstr = RstrBase(SystemRandom())
230
231
# Using Xeger/Rstr with default random
232
default_rstr = Rstr() # Uses standard random module
233
234
# Cryptographically secure instance
235
secure_rstr = Rstr(SystemRandom())
236
237
# Instance with custom alphabets
238
custom_rstr = Rstr(vowels='AEIOU', consonants='BCDFGHJKLMNPQRSTVWXYZ')
239
240
# RstrBase with custom alphabets (explicit random required)
241
secure_base = RstrBase(SystemRandom(), hex_chars='0123456789abcdef')
242
```
243
244
### Class Methods
245
246
```python { .api }
247
def add_alphabet(self, alpha_name: str, characters: str) -> None
248
```
249
250
Adds a custom alphabet to the instance and makes it available as a method.
251
252
**Parameters:**
253
- `alpha_name`: Name for the new alphabet method
254
- `characters`: String of characters for the alphabet
255
256
**Implementation Note:**
257
The `add_alphabet` method works with the class's `__getattr__` implementation to dynamically create methods. When you call a method name that matches an alphabet name, it automatically calls `rstr()` with that alphabet.
258
259
**Example:**
260
```python
261
rs = Rstr()
262
rs.add_alphabet('odds', '13579')
263
result = rs.odds(5) # 5-character string from odd digits
264
265
# This is equivalent to:
266
result = rs.rstr('13579', 5)
267
268
# You can also add alphabets during instantiation:
269
rs = Rstr(evens='02468', odds='13579')
270
even_result = rs.evens(3) # Uses '02468' alphabet
271
```
272
273
```python { .api }
274
def sample_wr(self, population: Sequence[str], k: int) -> List[str]
275
```
276
277
Samples k random elements with replacement from a population.
278
279
**Parameters:**
280
- `population`: Sequence of strings to sample from
281
- `k`: Number of elements to sample
282
283
**Returns:** List of k randomly selected elements (with replacement)
284
285
**Example:**
286
```python
287
rs = Rstr()
288
samples = rs.sample_wr(['A', 'B', 'C'], 5) # e.g., ['A', 'C', 'A', 'B', 'A']
289
```
290
291
All alphabet methods are available on class instances with the same signatures as package-level functions.
292
293
### Module-Level Functions Implementation
294
295
All module-level functions (`rstr`, `xeger`, alphabet functions) are actually methods of a default `Rstr()` instance:
296
297
```python { .api }
298
# Internal implementation (from rstr.__init__)
299
_default_instance = Rstr()
300
rstr = _default_instance.rstr
301
xeger = _default_instance.xeger
302
letters = _default_instance.letters
303
# ... all other alphabet functions
304
```
305
306
This means that all module-level functions share the same random state and use the standard `random` module by default.
307
308
### Exception Handling
309
310
```python { .api }
311
class SameCharacterError(ValueError):
312
pass
313
```
314
315
Raised when `include` and `exclude` parameters contain the same character(s) in any `rstr()` call.
316
317
**When raised:**
318
- Calling `rstr()` or any alphabet function with overlapping `include` and `exclude` characters
319
- Error message includes the conflicting character(s)
320
- Inherits from `ValueError` for standard exception handling patterns
321
322
**Examples:**
323
```python
324
import rstr
325
326
try:
327
# Single conflicting character
328
result = rstr.rstr('ABC', include='A', exclude='A')
329
except rstr.SameCharacterError as e:
330
print(f"Error: {e}")
331
# Output: "include and exclude parameters contain same character (A)"
332
333
try:
334
# Multiple conflicting characters
335
result = rstr.letters(include='XY', exclude='YZ')
336
except rstr.SameCharacterError as e:
337
print(f"Error: {e}")
338
# Output: "include and exclude parameters contain same characters (Y)"
339
```
340
341
## Advanced Usage Examples
342
343
### Secure Random Strings
344
345
For cryptographic applications, use SystemRandom:
346
347
```python
348
from random import SystemRandom
349
from rstr import Rstr
350
351
# Create secure instance
352
secure_rstr = Rstr(SystemRandom())
353
354
# Generate secure password
355
password = secure_rstr.unambiguous(16)
356
```
357
358
### Complex String Templates
359
360
Combine rstr with string formatting:
361
362
```python
363
# Generate email address
364
email = '{0}@{1}.{2}'.format(
365
rstr.nonwhitespace(exclude='@'),
366
rstr.domainsafe(),
367
rstr.letters(3)
368
)
369
370
# Generate URL
371
url = 'https://{0}.{1}/{2}?{3}'.format(
372
rstr.domainsafe(),
373
rstr.letters(3),
374
rstr.urlsafe(),
375
rstr.urlsafe()
376
)
377
378
# Generate postal address
379
address = """{0} {1}
380
{2} {3}
381
{4}, {5} {6}""".format(
382
rstr.letters(4, 8).title(),
383
rstr.letters(4, 8).title(),
384
rstr.digits(3, 5),
385
rstr.letters(4, 10).title(),
386
rstr.letters(4, 15).title(),
387
rstr.uppercase(2),
388
rstr.digits(5)
389
)
390
```
391
392
### Custom Alphabets
393
394
```python
395
# Instance with custom alphabets
396
rs = Rstr(
397
vowels='AEIOU',
398
consonants='BCDFGHJKLMNPQRSTVWXYZ',
399
hex_lower='0123456789abcdef'
400
)
401
402
# Use custom alphabets
403
vowel_string = rs.vowels(5)
404
consonant_string = rs.consonants(10)
405
hex_id = rs.hex_lower(8)
406
```
407
408
## Type Definitions
409
410
```python { .api }
411
from typing import Iterable, List, Mapping, Optional, Sequence, Union, Pattern
412
from random import Random
413
414
# Core function signature types
415
AlphabetType = Iterable[str]
416
IncludeExcludeType = Sequence[str]
417
RegexInputType = Union[str, Pattern[str]]
418
419
# Internal type definitions (available but not typically needed)
420
from typing import TypeVar, Protocol
421
_T = TypeVar('_T')
422
423
class _PartialRstrFunc(Protocol):
424
"""Type definition for dynamically created alphabet methods"""
425
def __call__(
426
self,
427
start_range: Optional[int] = ...,
428
end_range: Optional[int] = ...,
429
include: str = ...,
430
exclude: str = ...,
431
) -> str: ...
432
```
433
434
## Constants
435
436
```python { .api }
437
# From rstr.rstr_base
438
from rstr.rstr_base import ALPHABETS
439
ALPHABETS: Mapping[str, str] # Predefined alphabet mappings
440
441
# From rstr.xeger
442
from rstr.xeger import STAR_PLUS_LIMIT
443
STAR_PLUS_LIMIT: int = 100 # Maximum repeats for regex * and +
444
```
445
446
## Installation and Requirements
447
448
```bash
449
pip install rstr
450
```
451
452
- **Python**: 3.7+
453
- **Dependencies**: None (standard library only)
454
- **Optional**: SystemRandom for cryptographic applications
455
456
## Common Patterns
457
458
### Testing and Fuzz Testing
459
460
```python
461
# Generate test data with specific constraints
462
test_usernames = [rstr.letters(3, 20) for _ in range(100)]
463
test_emails = [f"{rstr.letters(5)}@{rstr.domainsafe()}.com" for _ in range(50)]
464
465
# Fuzz testing with problematic characters
466
fuzz_inputs = [rstr.rstr(string.printable, include=char) for char in '<>&"\'']
467
```
468
469
### Dummy Data Generation
470
471
```python
472
# Generate realistic-looking dummy data
473
names = [rstr.letters(4, 12).title() for _ in range(100)]
474
phone_numbers = [rstr.xeger(r'\(\d{3}\) \d{3}-\d{4}') for _ in range(50)]
475
social_security = [rstr.xeger(r'\d{3}-\d{2}-\d{4}') for _ in range(25)]
476
```