Skip to content

Commit 5c7c8d6

Browse files
committed
feat: Add randomstring library with basic functionality
This commit adds the randomstring library, which provides functionality for generating random strings based on specific characteristics. The library allows for generating strings with alphanumeric characters, letters only, digits only, special characters, or a custom character set. It also provides options to disable uppercase, lowercase, or numeric characters, and supports using a custom character set. The library is added to the project to provide a convenient way to generate random strings for various purposes, such as generating passwords, tokens, or unique identifiers. The license file and readme file are also added to provide information about the library and its usage. The license chosen for the library is the MIT License, which grants permission to use, copy, modify, merge, publish, distribute, sublicense, and/or sell the software. Contributions to the library are welcome, and contributors are encouraged to open issues or pick up existing ones before making their contributions and submitting pull requests. This commit addresses the need for a random string generation library and provides a starting point for using and contributing to the library. test(randomstring): add unit tests for GenerateStringFromCharset and GenerateString functions The new file `randomstring_test.go` contains unit tests for the `GenerateStringFromCharset` and `GenerateString` functions in the `randomstring` package. The tests cover various scenarios, including different charsets, lengths, and options. The purpose of these tests is to ensure the correctness and reliability of the `GenerateStringFromCharset` and `GenerateString` functions.
0 parents  commit 5c7c8d6

File tree

5 files changed

+249
-0
lines changed

5 files changed

+249
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Necmettin
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# RandomString Generator
2+
3+
This library assists in generating random strings based on specific characteristics. You can create random strings consisting of alphanumeric characters, letters only, digits only, special characters, or even a custom character set.
4+
5+
## Features
6+
7+
- Generate strings with alphanumeric, letters only, digits only, or special characters.
8+
- Ability to disable uppercase, lowercase, or numeric characters.
9+
- Option to use a custom character set.
10+
11+
## Installation
12+
13+
\```bash
14+
go get -u github.com/necmettindev/randomstring
15+
\```
16+
17+
## Usage
18+
19+
Below are different scenarios demonstrating how to use the `randomstring` package:
20+
21+
### Basic Usage
22+
23+
Generate a string of length 10 using the default alphanumeric characters:
24+
25+
\```go
26+
package main
27+
28+
import (
29+
"fmt"
30+
"github.com/necmettindev/randomstring"
31+
)
32+
33+
func main() {
34+
result, \_ := randomstring.GenerateString(randomstring.GenerationOptions{Length: 10})
35+
fmt.Println(result)
36+
}
37+
\```
38+
39+
### Disabling Features
40+
41+
For instance, to generate a string containing letters only:
42+
43+
\```go
44+
opts := randomstring.GenerationOptions{
45+
Length: 10,
46+
DisableNumeric: true,
47+
}
48+
result, \_ := randomstring.GenerateString(opts)
49+
fmt.Println(result)
50+
\```
51+
52+
### Using Special Characters
53+
54+
Generate a string with enabled special characters:
55+
56+
\```go
57+
opts := randomstring.GenerationOptions{
58+
Length: 15,
59+
EnableSpecialCharacter: true,
60+
}
61+
result, \_ := randomstring.GenerateString(opts)
62+
fmt.Println(result)
63+
\```
64+
65+
### Using a Custom Character Set
66+
67+
Generate a string with your own custom character set:
68+
69+
\```go
70+
opts := randomstring.GenerationOptions{
71+
Length: 12,
72+
CustomCharset: "abcXYZ789",
73+
}
74+
result, \_ := randomstring.GenerateString(opts)
75+
fmt.Println(result) // Produces a string consisting only of 'a', 'b', 'c', 'X', 'Y', 'Z', '7', '8', '9'.
76+
\```
77+
78+
## Contributing
79+
80+
If you wish to contribute to this project, please first open an issue or pick up an existing one. Then make your contribution and submit a pull request.
81+
82+
## License
83+
84+
This project is licensed under the MIT License.

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/necmettindev/randomstring
2+
3+
go 1.21.0

randomstring.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package randomstring
2+
3+
import (
4+
"crypto/rand"
5+
"errors"
6+
"math/big"
7+
"strings"
8+
)
9+
10+
type Charset string
11+
12+
const (
13+
Alphanumeric = Charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
14+
Lowercase = Charset("abcdefghijklmnopqrstuvwxyz")
15+
Uppercase = Charset("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
16+
Numeric = Charset("0123456789")
17+
SpecialCharacters = Charset("!@#$%^&*()-_=+[]{}|;:'<>,.?/~")
18+
)
19+
20+
var (
21+
GenerateString = generateString
22+
)
23+
24+
type GenerationOptions struct {
25+
Length int
26+
DisableNumeric bool
27+
DisableLowercase bool
28+
DisableUppercase bool
29+
EnableSpecialCharacter bool
30+
CustomCharset Charset // Yeni eklenen alan: kullanıcı tanımlı karakter seti
31+
}
32+
33+
func generateStringFromCharset(charset Charset, length int) (string, error) {
34+
if len(charset) == 0 || length <= 0 {
35+
return "", errors.New("invalid charset or length")
36+
}
37+
38+
result := make([]byte, length)
39+
charsetLen := big.NewInt(int64(len(charset)))
40+
for i := 0; i < length; i++ {
41+
randomIndex, err := rand.Int(rand.Reader, charsetLen)
42+
if err != nil {
43+
return "", err
44+
}
45+
result[i] = charset[randomIndex.Int64()]
46+
}
47+
48+
return string(result), nil
49+
}
50+
func modifyCharset(opts GenerationOptions, charsetMappings map[string]Charset, charset Charset) Charset {
51+
if opts.DisableNumeric {
52+
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["numeric"]), ""))
53+
}
54+
if opts.DisableLowercase {
55+
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["lowercase"]), ""))
56+
}
57+
if opts.DisableUppercase {
58+
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["uppercase"]), ""))
59+
}
60+
if opts.EnableSpecialCharacter {
61+
charset += charsetMappings["specialCharater"]
62+
}
63+
return charset
64+
}
65+
66+
func generateString(opts GenerationOptions) (string, error) {
67+
charsetMappings := map[string]Charset{
68+
"numeric": Numeric,
69+
"lowercase": Lowercase,
70+
"uppercase": Uppercase,
71+
"specialCharater": SpecialCharacters,
72+
}
73+
74+
charset := Alphanumeric
75+
if opts.CustomCharset != "" {
76+
charset = opts.CustomCharset
77+
} else {
78+
charset = modifyCharset(opts, charsetMappings, charset)
79+
}
80+
81+
if len(charset) == 0 {
82+
return "", errors.New("resulting charset is empty. adjust your options")
83+
}
84+
85+
return generateStringFromCharset(charset, opts.Length)
86+
}

randomstring_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package randomstring
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestGenerateStringFromCharset(t *testing.T) {
8+
tests := []struct {
9+
charset Charset
10+
length int
11+
err bool
12+
}{
13+
{Alphanumeric, 10, false},
14+
{Lowercase, 5, false},
15+
{Uppercase, 5, false},
16+
{Numeric, 5, false},
17+
{SpecialCharacters, 5, false},
18+
{Charset(""), 5, true},
19+
{Alphanumeric, -5, true},
20+
}
21+
22+
for _, tt := range tests {
23+
result, err := generateStringFromCharset(tt.charset, tt.length)
24+
if (err != nil) != tt.err {
25+
t.Errorf("for charset %v and length %d, expected error: %v, got: %v", tt.charset, tt.length, tt.err, (err != nil))
26+
}
27+
if !tt.err && len(result) != tt.length {
28+
t.Errorf("expected length %d, got %d", tt.length, len(result))
29+
}
30+
}
31+
}
32+
33+
func TestGenerateString(t *testing.T) {
34+
tests := []struct {
35+
opts GenerationOptions
36+
err bool
37+
}{
38+
{GenerationOptions{Length: 10}, false},
39+
{GenerationOptions{Length: 10, DisableNumeric: true, DisableLowercase: true, DisableUppercase: true}, true},
40+
{GenerationOptions{Length: 10, DisableNumeric: true}, false},
41+
{GenerationOptions{Length: 10, EnableSpecialCharacter: true}, false},
42+
{GenerationOptions{Length: 10, CustomCharset: "abc123"}, false},
43+
{GenerationOptions{Length: 0}, true},
44+
}
45+
46+
for _, tt := range tests {
47+
result, err := GenerateString(tt.opts)
48+
if (err != nil) != tt.err {
49+
t.Errorf("for options %+v, expected error: %v, got: %v", tt.opts, tt.err, (err != nil))
50+
}
51+
if !tt.err && len(result) != tt.opts.Length {
52+
t.Errorf("expected length %d, got %d", tt.opts.Length, len(result))
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)