├── .gitignore ├── README.md ├── go.mod ├── go.sum ├── zconv ├── int.go ├── string.go └── struct.go ├── zcrypto ├── md5.go ├── md5_test.go └── uuid.go ├── zos ├── dir.go ├── file.go └── os.go ├── zrand └── string.go ├── zregex └── rule.go └── zslice ├── chunk.go ├── chunk_test.go ├── clone.go ├── clone_test.go ├── equal.go ├── remove.go ├── slice.go └── slice_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Z! 2 | 3 | code fast and reuse! 4 | 5 | ```go 6 | import "github.com/aizk/z" 7 | ``` 8 | # zconv 9 | 10 | type trans tools. 11 | 12 | - Int64ToString 13 | - IntToString 14 | 15 | # zslice 16 | 17 | wrap of slice。 18 | 19 | - `Clone()` 克隆一个 slice 20 | - 删除某个位置的元素 21 | - 查找某个元素的位置 22 | - 复制一份 slice 23 | - 泛型操作... 24 | - map、reduce... 25 | - filter... 26 | 27 | ## Chunk(slice, num) slice 28 | 29 | ```go 30 | s := []int{1, 2, 3, 4, 5} 31 | n := Chunk(s, 2) // [[1, 2], [3, 4], [5]] 32 | ``` 33 | 34 | # zos 35 | 36 | - `Exist(path string)` 判断文件或目录是否存在 37 | - `IsDir(path string)` 判断是否是目录 38 | - `OpenFile(path string, perm 0777)` 打开文件 39 | - `WorkDIR` 返回工作目录 40 | 41 | # rand 42 | 43 | - String() 随机生成字符串 44 | - StringWithType() 可以选择生成的字符串中有哪些类型的字符 45 | 46 | # crypto 47 | 48 | - MD5() md5 加密函数 49 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aizk/z 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/satori/go.uuid v1.2.0 7 | github.com/stretchr/testify v1.7.0 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= 6 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 9 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 10 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 11 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 12 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 13 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 14 | -------------------------------------------------------------------------------- /zconv/int.go: -------------------------------------------------------------------------------- 1 | package zconv 2 | 3 | import "strconv" 4 | 5 | func Int64ToString(i int64) string { 6 | return strconv.FormatInt(i, 10) 7 | } 8 | 9 | func IntToString(i int) string { 10 | return strconv.Itoa(i) 11 | } 12 | -------------------------------------------------------------------------------- /zconv/string.go: -------------------------------------------------------------------------------- 1 | package zconv 2 | 3 | 4 | -------------------------------------------------------------------------------- /zconv/struct.go: -------------------------------------------------------------------------------- 1 | package zconv 2 | 3 | 4 | -------------------------------------------------------------------------------- /zcrypto/md5.go: -------------------------------------------------------------------------------- 1 | package zcrypto 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "strings" 7 | ) 8 | 9 | func MD5(args ...string) string { 10 | h := md5.New() 11 | h.Write([]byte(strings.Join(args, ""))) 12 | return hex.EncodeToString(h.Sum(nil)) 13 | } 14 | -------------------------------------------------------------------------------- /zcrypto/md5_test.go: -------------------------------------------------------------------------------- 1 | package zcrypto 2 | 3 | import "testing" 4 | 5 | func TestMD5(t *testing.T) { 6 | type args struct { 7 | args []string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want string 13 | }{ 14 | // TODO: Add test cases. 15 | { 16 | name: "case1", 17 | args: args{ 18 | args: []string{"end_time=1639482800pn=1room_id=5050143952start_time=1639480600status=user_id=5339842638tiebaclient!!!"}, 19 | }, 20 | want: "", 21 | }, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := MD5(tt.args.args...); got != tt.want { 26 | t.Errorf("MD5() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /zcrypto/uuid.go: -------------------------------------------------------------------------------- 1 | package zcrypto 2 | 3 | //func GetUUID() string { 4 | // return uuid.Must(uuid.NewV4()).String() 5 | //} 6 | // 7 | //func GetUUIDWithoutRail() string { 8 | // return strings.Replace(uuid.Must(uuid.NewV4()).String(), "-", "", -1) 9 | //} 10 | -------------------------------------------------------------------------------- /zos/dir.go: -------------------------------------------------------------------------------- 1 | package zos 2 | 3 | import "os" 4 | 5 | // IsDir returns true if the given path is a directory. 6 | func IsDir(path string) bool { 7 | f, err := os.Stat(path) 8 | if err != nil { 9 | return false 10 | } 11 | return f.Mode().IsDir() 12 | } 13 | 14 | // WorkDIR returns the current working directory. 15 | func WorkDIR() string { 16 | w, _ := os.Getwd() 17 | return w 18 | } -------------------------------------------------------------------------------- /zos/file.go: -------------------------------------------------------------------------------- 1 | package zos 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | ) 7 | 8 | // OpenFile opens a file if it exists, otherwise creates it and directory. 9 | func OpenFile(path string, perm os.FileMode) (*os.File, error) { 10 | dir, _ := filepath.Split(path) 11 | if !Exist(dir) { 12 | os.MkdirAll(dir, perm) 13 | } 14 | f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, perm) 15 | return f, err 16 | } -------------------------------------------------------------------------------- /zos/os.go: -------------------------------------------------------------------------------- 1 | package zos 2 | 3 | import "os" 4 | 5 | // Exist checks if a file or directory exists 6 | func Exist(file string) bool { 7 | _, err := os.Stat(file) 8 | return !os.IsNotExist(err) 9 | } -------------------------------------------------------------------------------- /zrand/string.go: -------------------------------------------------------------------------------- 1 | package zrand 2 | 3 | import ( 4 | "math/rand" 5 | "bytes" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | 11 | const ( 12 | letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // 用掩码进行替换 13 | letterIdxBits = 6 // 6 bits to represent a letter index 14 | letterIdxMask = 1<= 0; { 24 | if remain == 0 { 25 | cache, remain = rand.Int63(), letterIdxMax 26 | } 27 | if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 28 | b[i] = letterBytes[idx] 29 | i-- 30 | } 31 | cache >>= letterIdxBits 32 | remain-- 33 | } 34 | 35 | return string(b) 36 | } 37 | 38 | var num = "0123456789" 39 | var lower = "abcdefghijklmnopqrstuvwxyz" 40 | var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 41 | 42 | // type is 0、a、A 43 | // like StringWithType(64, "0aA") 44 | func RandStringWithLengthAndType(length int, type_ string) (result string) { 45 | b := bytes.Buffer{} 46 | if strings.Contains(type_, "0") { 47 | b.WriteString(num) 48 | } 49 | if strings.Contains(type_, "a") { 50 | b.WriteString(lower) 51 | } 52 | if strings.Contains(type_, "A") { 53 | b.WriteString(upper) 54 | } 55 | var str = b.String() 56 | var strLen = len(str) 57 | if strLen == 0 { 58 | result = "" 59 | return 60 | } 61 | 62 | rand.Seed(time.Now().UnixNano()) 63 | b = bytes.Buffer{} 64 | for i := 0; i < length; i++ { 65 | b.WriteByte(str[rand.Intn(strLen)]) 66 | } 67 | return b.String() 68 | } 69 | -------------------------------------------------------------------------------- /zregex/rule.go: -------------------------------------------------------------------------------- 1 | package zregex 2 | 3 | import ( 4 | "regexp" 5 | ) 6 | 7 | func commonValid(regular string, target string) bool { 8 | rgx := regexp.MustCompile(regular) 9 | return rgx.MatchString(target) 10 | } 11 | 12 | // 验证手机号 13 | func ValidTelephone(tel string) bool { 14 | return commonValid("^1[3456789]\\d{9}$", tel) 15 | } 16 | 17 | // 验证QQ 18 | func ValidQQ(qq string) bool { 19 | return commonValid("^\\d{5,}$", qq) 20 | } 21 | 22 | // 检测验证码 6 位数字 23 | func ValidCode(code string) bool { 24 | return commonValid("^\\d{6,}$", code) 25 | } 26 | -------------------------------------------------------------------------------- /zslice/chunk.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | func Chunk[T any](r []T, n int) (s [][]T) { 4 | l := len(r) 5 | if l == 0 || n == 0 { 6 | return nil 7 | } 8 | 9 | if l < n { 10 | s = [][]T{r} 11 | return 12 | } 13 | 14 | // c round 15 | c := l / n 16 | if l %n != 0 { 17 | c += 1 18 | } 19 | 20 | s = make([][]T, c) 21 | 22 | i := 0 23 | j := 0 24 | k := n 25 | // build chunk 26 | for i < c { 27 | s[i] = r[j:k] 28 | i += 1 29 | j += n 30 | k += n 31 | if k >= l { 32 | k = l 33 | } 34 | } 35 | 36 | return 37 | } 38 | -------------------------------------------------------------------------------- /zslice/chunk_test.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestChunk(t *testing.T) { 9 | type args struct { 10 | r []int 11 | n int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | wantS [][]int 17 | }{ 18 | { 19 | name: "success", 20 | args: args{ 21 | r: []int{1, 2, 3, 4, 5}, 22 | n: 2, 23 | }, 24 | wantS: [][]int{{1, 2}, {3, 4}, {5}}, 25 | }, 26 | { 27 | name: "success", 28 | args: args{ 29 | r: []int{1, 2, 3, 4}, 30 | n: 2, 31 | }, 32 | wantS: [][]int{{1, 2}, {3, 4}}, 33 | }, 34 | { 35 | name: "success", 36 | args: args{ 37 | r: []int{1, 2, 3, 4, 5}, 38 | n: 100, 39 | }, 40 | wantS: [][]int{{1, 2, 3, 4, 5}}, 41 | }, 42 | { 43 | name: "success", 44 | args: args{ 45 | r: []int{1, 2, 3, 4, 5}, 46 | n: 0, 47 | }, 48 | wantS: nil, 49 | }, 50 | } 51 | for _, tt := range tests { 52 | t.Run(tt.name, func(t *testing.T) { 53 | if gotS := Chunk[int](tt.args.r, tt.args.n); !reflect.DeepEqual(gotS, tt.wantS) { 54 | t.Errorf("Chunk() = %v, want %v", gotS, tt.wantS) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /zslice/clone.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | import "reflect" 4 | 5 | // Clone will clone slice 6 | func Clone(src interface{}) (dst interface{}) { 7 | v := reflect.ValueOf(src) 8 | if v.Kind() != reflect.Slice { 9 | return 10 | } 11 | 12 | // copy v slice with value 13 | vn := reflect.MakeSlice(v.Type(), v.Len(), v.Cap()) 14 | reflect.Copy(vn, v) 15 | return vn.Interface() 16 | } 17 | 18 | // Up to the official Go SDK 1.11, the simplest way to clone a slice is: 19 | func CloneInt2(s []int) []int { 20 | return append(s[:0:0], s...) 21 | } 22 | 23 | func CloneInt(s []int) []int { 24 | clone := make([]int, len(s)) 25 | copy(clone, s) 26 | return clone 27 | } 28 | 29 | -------------------------------------------------------------------------------- /zslice/clone_test.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestClone(t *testing.T) { 9 | type args struct { 10 | src interface{} 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | wantDst interface{} 16 | }{ 17 | { 18 | name: "[]int copy", 19 | args: args{ 20 | src: []int{1, 2, 3}, 21 | }, 22 | wantDst: []int{1, 2, 3}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | dst := Clone(tt.args.src); 28 | 29 | if !reflect.DeepEqual(dst, tt.wantDst) { 30 | t.Errorf("Clone() = %v, want %v", dst, tt.wantDst) 31 | } 32 | 33 | // assert dst is clone 34 | if reflect.ValueOf(dst).Pointer() == reflect.ValueOf(tt.args.src).Pointer() { 35 | t.Errorf("Clone() = %v, want %v", dst, tt.wantDst) 36 | } 37 | }) 38 | } 39 | } -------------------------------------------------------------------------------- /zslice/equal.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | func EqualSlice(x, y []interface{}) bool { 4 | if len(x) != len(y) { 5 | return false 6 | } 7 | 8 | for _, v1 := range x { 9 | find := false 10 | for _, v2 := range y { 11 | if v1 == v2 { 12 | find = true 13 | break 14 | } 15 | } 16 | if !find { 17 | return false 18 | } 19 | } 20 | return true 21 | } 22 | -------------------------------------------------------------------------------- /zslice/remove.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | import ( 4 | "unsafe" 5 | "reflect" 6 | ) 7 | 8 | func Remove(s interface{}, index ...int) interface{} { 9 | switch v := s.(type) { 10 | case []int: 11 | return RemoveInts(v, index...) 12 | case []string: 13 | RemoveStrings(v, index...) 14 | } 15 | panic("error type") 16 | } 17 | 18 | func RemoveStrings(s []string, index ...int) []string { 19 | for _, i := range index { 20 | s = append(s[:i], s[i + 1:]...) 21 | } 22 | return s 23 | } 24 | 25 | func RemoveInts(s []int, index ...int) []int { 26 | for _, i := range index { 27 | s = RemoveInt(s, i) 28 | } 29 | return s 30 | } 31 | 32 | func RemoveInt(s []int, index int) []int { 33 | return append(s[:index], s[index + 1:]...) 34 | } 35 | 36 | // s 值拷贝 37 | // 传递指针时传递的也是原有指针的拷贝 38 | // 思路: 39 | // 传递指向原有值的指针 40 | // 取得对应的 slice 进行 append 操作 41 | // 产生新的 slice 42 | // 将新的和旧的都转化成 SliceHeader 43 | // 将新的值赋给旧的内存 44 | func RemoveInt2(s *[]int, index int) { 45 | // 产生新的值 46 | v := *s 47 | // 共享底层数组 48 | newSlice := append(v[:index], v[index + 1:]...) 49 | // 修改不了 s 指针指向的位置? 50 | // 只修改了指针拷贝的值! 51 | //s = &v 52 | ns := (*reflect.SliceHeader)(unsafe.Pointer(&newSlice)) 53 | os := (*reflect.SliceHeader)(unsafe.Pointer(s)) 54 | os.Data = ns.Data 55 | os.Len = ns.Len 56 | os.Cap = ns.Cap 57 | } 58 | 59 | func RemoveInt3(s []int, index int) { 60 | copy(s[index:], s[index + 1:]) 61 | s[len(s) - 1] = 0 62 | s = s[:len(s) - 1] 63 | } 64 | 65 | // Delete without preserving order 删除不保留顺序 66 | func RemoveWithoutOrder(s []int, index int) []int { 67 | // 将最后一个元素赋值给当前元素 68 | s[index] = s[len(s) - 1] 69 | // 删除最后一个元素 70 | s = s[:len(s) - 1] 71 | return s 72 | } 73 | -------------------------------------------------------------------------------- /zslice/slice.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | import ( 4 | "math/rand" 5 | ) 6 | 7 | // Append 8 | func Append(s, t []int) { 9 | s = append(s, t...) 10 | } 11 | 12 | // Copy 13 | func Copy(s []int) []int { 14 | t := make([]int, len(s)) 15 | copy(t, s) 16 | // or 17 | t1 := append([]int{}, s...) 18 | return t1 19 | } 20 | 21 | // Cut 22 | func Cut(s []int, i, j int) []int { 23 | s = append(s[:i], s[j:]...) 24 | return s 25 | } 26 | 27 | // Expand 在中间扩展 28 | func Expand(s []int, index, num int) { 29 | s = append(s[:index], append(make([]int, num), s[index:]...)...) 30 | } 31 | 32 | // Extend 在后面增加 33 | func Extend(s []int, num int) { 34 | s = append(s, make([]int, num)...) 35 | } 36 | 37 | // Insert 插入一个数据 38 | func Insert(s []int, index, data int) { 39 | s = append(s[:index], append([]int{data}, s[index:]...)...) 40 | } 41 | 42 | // InsertVector in index 43 | func InsertVector(s, t []int, index int) { 44 | s = append(s[:index], append(t, s[index:]...)...) 45 | } 46 | 47 | // 弹出首个元素 48 | func POPShift(s []int) int { 49 | x, s := s[0], s[1:] 50 | return x 51 | } 52 | 53 | // POPBack 54 | func POPBack(s []int) int { 55 | x, s := s[len(s) - 1], s[:len(s) - 1] 56 | return x 57 | } 58 | 59 | // PUSH 60 | func PUSH(s []int, x int) { 61 | s = append(s, x) 62 | } 63 | 64 | // PUSH FRONT 65 | func PUSHFront(s []int, x int) { 66 | s = append([]int{x}, s...) 67 | } 68 | 69 | // Filtering without allocating 70 | // 不分配新内存过滤 71 | func Filter(s []int) { 72 | t := s[:0] 73 | for _, value := range s { 74 | // 条件过滤参数 75 | if true { 76 | t = append(t, value) 77 | } 78 | } 79 | } 80 | 81 | // Reversing 82 | // To replace the contents of a slice with the same elements but in reverse order: 83 | func Reversing(s []int) { 84 | for i := len(s)/2 - 1 ; i >= 0; i-- { 85 | t := len(s) - 1 - i 86 | s[i], s[t] = s[t], s[i] 87 | } 88 | 89 | for left, right := 0, len(s) - 1; left < right; left, right = left + 1, right - 1 { 90 | s[left], s[right] = s[right], s[left] 91 | } 92 | } 93 | 94 | // Shuffling 95 | // 洗牌 打乱顺序 96 | func Shuffling(s []int) { 97 | for i := len(s) - 1; i > 0; i-- { 98 | j := rand.Intn(i + 1) 99 | s[i], s[j] = s[j], s[i] 100 | } 101 | } -------------------------------------------------------------------------------- /zslice/slice_test.go: -------------------------------------------------------------------------------- 1 | package zslice 2 | 3 | import "testing" 4 | 5 | func TestRemove(t *testing.T) { 6 | x := []int{1, 2, 3} 7 | x = Remove(x, 1).([]int) 8 | 9 | //x = RemoveInt(x, 1) 10 | t.Log(x) 11 | 12 | //Remove(x, 1) 13 | //t.Log(x) 14 | //Remove(x, 1) 15 | //t.Log(x) 16 | t.Log(append(x[:1], x[2:]...)) 17 | } 18 | --------------------------------------------------------------------------------