1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-23 13:52:26 +08:00

Compare commits

...

52 Commits

Author SHA1 Message Date
dudaodong
c5297ec329 fix: fix failed unit test 2023-12-11 15:04:54 +08:00
dudaodong
aa4b61ff85 release v2.2.8 2023-12-11 14:59:20 +08:00
dudaodong
7dbd7002a3 doc: update doc for new release 2023-12-11 14:58:28 +08:00
dudaodong
a995db445a doc: update doc for random package 2023-12-08 11:57:39 +08:00
dudaodong
6e5b67bee7 feat: add RandFloat and RandFloats 2023-12-07 19:41:45 +08:00
dudaodong
52b8ea8166 doc: update doc for random package 2023-12-07 19:13:05 +08:00
dudaodong
6fe8a9efe7 feat: add RandSymbolChar 2023-12-07 17:56:12 +08:00
dudaodong
dcef06e9da fix: fix dns regex matcher 2023-12-07 09:54:03 +08:00
dudaodong
8f410bf9cb Merge branch 'main' into v2 2023-12-01 16:43:36 +08:00
dengrandpa
9cd6eb4ddf fix(validator): [IsChineseIdNum] fix 身份证效验 新增 省份、生日、效验码效验,修改ContainLower/IsNumber 注释错误 (#149)
* fix: 修改 README_zh-CN.md datetime 重复 IsLeapYear问题

* fix: 修改 README_zh-CN.md 18. slice 回到目录

* fix(validator): [IsChineseIdNum] fix 身份证效验 新增 省份、生日、效验码效验,修改ContainLower/IsNumber 注释错误

* fix(validator): [IsChineseIdNum] fix 修改测试

---------

Co-authored-by: dengjiaxiang <19181730103@189.cn>
Co-authored-by: dengrandpa <dengrandpapa@outlook.com>
2023-12-01 16:42:35 +08:00
dudaodong
bf581162ee Merge branch 'main' into v2 2023-11-29 11:46:09 +08:00
dengrandpa
bd984fa378 fix: 修改 README_zh-CN.md 文档错误 (#147)
* fix: 修改 README_zh-CN.md datetime 重复 IsLeapYear问题

* fix: 修改 README_zh-CN.md 18. slice 回到目录

---------

Co-authored-by: dengjiaxiang <19181730103@189.cn>
2023-11-29 11:43:54 +08:00
dudaodong
d7f23e2dee Merge branch 'main' into v2 2023-11-22 17:20:17 +08:00
o98k
3802c715c3 [feature]<slice>: support random item (#146)
Signed-off-by: o98k-ok <hggend@gmail.com>
2023-11-22 16:51:37 +08:00
dudaodong
4b12173f24 Merge branch 'main' into v2 2023-11-16 15:28:34 +08:00
guangwu
31c618c187 chore: use bytes.Equal instead (#144) 2023-11-16 15:26:20 +08:00
dudaodong
6497b321b0 refactor: clean code 2023-10-30 17:55:18 +08:00
dudaodong
bda78201f5 doc: update readme file 2023-10-28 17:02:24 +08:00
dudaodong
0753ea2801 feat: add context for httpClient SendRequest function 2023-10-18 19:13:34 +08:00
dudaodong
e25b53712b doc: add play ground demo 2023-10-08 11:19:44 +08:00
dudaodong
56c9327a86 release v2.2.7 2023-10-07 11:40:38 +08:00
dudaodong
11eb559998 update readme file 2023-10-07 11:15:14 +08:00
dudaodong
61a612a06a update: update Enqueue and Dequeue 2023-10-07 10:53:45 +08:00
dudaodong
2351ab4714 Merge branch 'v2' of github.com:duke-git/lancet into v2 2023-09-24 19:09:31 +08:00
dudaodong
88eec858b4 test: add test file 2023-09-24 19:09:19 +08:00
dudaodong
14c37b5a5f Merge branch 'v2' of github.com:duke-git/lancet into v2 2023-09-23 13:48:40 +08:00
dudaodong
ad8b1d424c Merge branch 'main' into v2 2023-09-23 13:48:25 +08:00
flytutu
a9f01d8a69 [opt] currentPath support windows and linux (#139)
Co-authored-by: hesu <hesu@eacomp.com>
2023-09-23 13:45:21 +08:00
o98k
781b89d51a feat(fileutil): add ReadFile func (#140) 2023-09-23 13:45:02 +08:00
dudaodong
073c77e751 refactor: remove unused code 2023-09-19 17:44:49 +08:00
dudaodong
91a0d3077d doc: update cryptor doc 2023-09-17 16:22:47 +08:00
dudaodong
17b34f8f19 doc: add doc for GenerateRsaKeyPair, RsaEncryptOAEP, RsaDecryptOAEP 2023-09-14 14:15:10 +08:00
dudaodong
8ff37f0eff feat: add GenerateRsaKeyPair, RsaEncryptOAEP, RsaDecryptOAEP 2023-09-14 14:06:54 +08:00
elza
f445ecbaf8 feat: add IsNotBlank func (#132)
Co-authored-by: yuanyou <yuanyou@kezaihui.com>
2023-09-13 15:29:26 +08:00
dudaodong
b698fec50f doc: add go playground demo 2023-09-11 15:59:35 +08:00
dudaodong
b38bb66b34 doc: update readme file 2023-09-11 11:51:45 +08:00
dudaodong
bdfdeaf496 merge branch 'main' into v2 2023-09-11 11:40:46 +08:00
dudaodong
172c44c07a doc: update doc site 2023-09-11 11:39:21 +08:00
dudaodong
534263eb08 release v2.2.6 2023-09-11 11:38:45 +08:00
dudaodong
a25b1ac7e3 doc: update doc site 2023-09-11 11:35:37 +08:00
dudaodong
d84f9777ea doc: update doc site 2023-09-11 11:33:39 +08:00
dudaodong
f198711d1c doc: add doc for new functions 2023-09-07 16:03:08 +08:00
dudaodong
19378ca4d1 feat: add IsVisa, IsMasterCard, IsAmericanExpress, IsUnionPay, IsChinaUnionPay 2023-09-06 18:05:15 +08:00
dudaodong
71c7733eb0 feat: add IsBin, IsHex, IsBase64URL, IsJWT 2023-09-06 17:42:31 +08:00
dudaodong
20786c360b test: add cases for TestIsIpV4 and TestIsIpV6 2023-09-06 16:27:14 +08:00
dudaodong
51fafa110e merge main 2023-09-06 16:19:11 +08:00
dudaodong
b309044981 doc: add doc for Partition 2023-09-04 16:23:23 +08:00
dudaodong
541e6d4ea3 feat: add Partition for slice 2023-09-04 11:30:50 +08:00
dudaodong
4037b96cc4 refactor: update SortByField 2023-09-04 11:03:22 +08:00
dudaodong
8e484c4a6f doc: update doc site 2023-09-04 10:31:02 +08:00
dudaodong
dd339563bc doc: add contribution and contributors to doc site 2023-09-01 16:47:33 +08:00
dudaodong
9567dcc57f doc: update doc site 2023-09-01 16:01:17 +08:00
52 changed files with 2615 additions and 266 deletions

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.2.5-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.2.8-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -19,9 +19,9 @@
Lancet is a comprehensive, efficient, and reusable util function library of go. Inspired by the java apache common package and lodash.js.
</p>
English | [简体中文](./README_zh-CN.md)
## <a href="https://www.golancet.cn/en/" target="_blank"> Website</a> | [简体中文](./README_zh-CN.md)
## Feature
## Features
- 👏 Comprehensive, efficient and reusable.
- 💪 600+ go util functions, support string, slice, datetime, net, crypt...
@@ -38,7 +38,7 @@ English | [简体中文](./README_zh-CN.md)
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
```
2. <b>For users who use version below go1.18, you should install v1.x.x. The latest of v1.x.x is v1.4.1. </b>
2. <b>For users who use version below go1.18, you should install v1.x.x. The latest of v1.x.x is v1.4.2. </b>
```go
go get github.com/duke-git/lancet // below go1.18, install latest version of v1.x.x
@@ -451,6 +451,16 @@ import "github.com/duke-git/lancet/v2/cryptor"
- **<big>RsaDecrypt</big>** : decrypt data with ras algorithm.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaDecrypt)]
[[play](https://go.dev/play/p/uef0q1fz53I)]
- **<big>GenerateRsaKeyPair</big>** : creates rsa private and public key.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#GenerateRsaKeyPair)]
[[play](https://go.dev/play/p/sSVmkfENKMz)]
- **<big>RsaEncryptOAEP</big>** : encrypts the given data with RSA-OAEP.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaEncryptOAEP)]
[[play](https://go.dev/play/p/sSVmkfENKMz)]
- **<big>RsaDecryptOAEP</big>** : decrypts the data with RSA-OAEP
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/cryptor.md#RsaDecryptOAEP)]
[[play](https://go.dev/play/p/sSVmkfENKMz)]
<h3 id="datetime"> 7. Datetime package supports date and time format and compare. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -703,6 +713,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
- **<big>WriteStringToFile</big>** : write string to target file.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteStringToFile)]
[[play](https://go.dev/play/p/GhLS6d8lH_g)]
- **<big>ReadFile</big>** : read file or url.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#ReadFile)]
<h3 id="formatter"> 10. Formatter contains some functions for data formatting. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1085,6 +1097,12 @@ import "github.com/duke-git/lancet/v2/random"
- **<big>RandUniqueIntSlice</big>** : generate a slice of random int of length n that do not repeat.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandUniqueIntSlice)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
- **<big>RandSymbolChar</big>** : Generate a random symbol char of specified length.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandSymbolChar)]
- **<big>RandFloat</big>** : Generate a random float64 number between [min, max) with specific precision.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandFloat)]
- **<big>RandFloats</big>** : Generate a slice of random float64 numbers of length n that do not repeat.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandFloats)]
<h3 id="retry"> 17. Retry package is for executing a function repeatedly until it was successful or canceled by the context. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1325,6 +1343,11 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>Join</big>** : join the slice item with specify separator.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Join)]
[[play](https://go.dev/play/p/huKzqwNDD7V)]
- **<big>Partition</big>** : partition all slice elements with the evaluation of the given predicate functions.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Partition)]
[[play](https://go.dev/play/p/lkQ3Ri2NQhV)]
- **<big>Random</big>** : get a random item of slice, return its index, when slice is empty, return -1.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Random)]
<h3 id="stream"> 19. Stream package implements a sequence of elements supporting sequential and operations. this package is an experiment to explore if stream in go can work as the way java does. its function is very limited. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1540,6 +1563,9 @@ import "github.com/duke-git/lancet/v2/strutil"
- **<big>IsBlank</big>** : checks if a string is whitespace or empty.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#IsBlank)]
[[play](https://go.dev/play/p/6zXRH_c0Qd3)]
- **<big>IsNotBlank</big>** : checks if a string is not whitespace or not empty.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#IsNotBlank)]
[[play](https://go.dev/play/p/e_oJW0RAquA)]
- **<big>HasPrefixAny</big>** : checks if a string starts with any of an array of specified strings.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#HasPrefixAny)]
[[play](https://go.dev/play/p/8UUTl2C5slo)]
@@ -1826,6 +1852,33 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsPrintable</big>** : checks if string is all printable chars.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsPrintable)]
[[play](https://go.dev/play/p/Pe1FE2gdtTP)]
- **<big>IsBin</big>** : check if a give string is a valid binary value or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsBin)]
[[play](https://go.dev/play/p/ogPeg2XJH4P)]
- **<big>IsHex</big>** : check if a give string is a valid hexadecimal value or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsHex)]
[[play](https://go.dev/play/p/M2qpHbEwmm7)]
- **<big>IsBase64URL</big>** : check if a give string is a valid URL-safe Base64 encoded string.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsBase64URL)]
[[play](https://go.dev/play/p/vhl4mr8GZ6S)]
- **<big>IsJWT</big>** : check if a give string is a valid JSON Web Token (JWT).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsJWT)]
[[play](https://go.dev/play/p/R6Op7heJbKI)]
- **<big>IsVisa</big>** : check if a give string is a valid visa card nubmer or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsVisa)]
[[play](https://go.dev/play/p/SdS2keOyJsl)]
- **<big>IsMasterCard</big>** : check if a give string is a valid master card nubmer or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsMasterCard)]
[[play](https://go.dev/play/p/CwWBFRrG27b)]
- **<big>IsAmericanExpress</big>** : check if a give string is a valid american expression card nubmer or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsAmericanExpress)]
[[play](https://go.dev/play/p/HIDFpcOdpkd)]
- **<big>IsUnionPay</big>** : check if a give string is a valid union pay nubmer or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsUnionPay)]
[[play](https://go.dev/play/p/CUHPEwEITDf)]
- **<big>IsChinaUnionPay</big>** : check if a give string is a valid china union pay nubmer or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsChinaUnionPay)]
[[play](https://go.dev/play/p/yafpdxLiymu)]
<h3 id="xerror"> 25. Xerror package implements helpers for errors. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
@@ -1892,7 +1945,7 @@ Hello, I am a software developer and have been engaged in development work for 1
<br/>
<br/>
*Donated funds will be used to maintain this website and pay for cloud server costs. Or just buy me a cup of ☕️ when I'm sleepy writing code.*
*Donated funds will be used to maintain [lancet](https://www.golancet.cn/en/) website and pay for cloud server costs. Or just buy me a cup of ☕️ when I'm sleepy writing code.*
## Contributors

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.2.5-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.2.8-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -18,7 +18,7 @@
lancet柳叶刀是一个全面、高效、可复用的go语言工具函数库。 lancet受到了java apache common包和lodash.js的启发。
</p>
简体中文 | [English](./README.md)
## <a href="https://www.golancet.cn/" target="_blank">官网</a> | [English](./README.md)
## 特性
@@ -37,7 +37,7 @@
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
```
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.4.1。</b>
2. <b>使用 go1.18 以下版本的用户,必须安装 v1.x.x。目前最新的 v1 版本是 v1.4.2。</b>
```go
go get github.com/duke-git/lancet// 使用go1.18以下版本, 必须安装v1.x.x版本
@@ -451,6 +451,16 @@ import "github.com/duke-git/lancet/v2/cryptor"
- **<big>RsaDecrypt</big>** : 用私钥文件 rsa 解密数据。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaDecrypt)]
[[play](https://go.dev/play/p/uef0q1fz53I)]
- **<big>GenerateRsaKeyPair</big>** : 创建rsa公钥私钥和key。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#GenerateRsaKeyPair)]
[[play](https://go.dev/play/p/sSVmkfENKMz)]
- **<big>RsaEncryptOAEP</big>** : rsa OAEP加密。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaEncryptOAEP)]
[[play](https://go.dev/play/p/sSVmkfENKMz)]
- **<big>RsaDecryptOAEP</big>** : rsa OAEP解密。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/cryptor.md#RsaDecryptOAEP)]
[[play](https://go.dev/play/p/sSVmkfENKMz)]
<h3 id="datetime"> 7. datetime 日期时间处理包,格式化日期,比较日期。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -562,9 +572,6 @@ import "github.com/duke-git/lancet/v2/datetime"
- **<big>IsLeapYear</big>** :验证是否是闰年。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#IsLeapYear)]
[[play](https://go.dev/play/p/xS1eS2ejGew)]
- **<big>IsLeapYear</big>** : check if param `year` is leap year or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#IsLeapYear)]
[[play](https://go.dev/play/p/xS1eS2ejGew)]
- **<big>BetweenSeconds</big>** : 返回两个时间的间隔秒数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#BetweenSeconds)]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/datetime.md#BetweenSeconds)]
@@ -707,6 +714,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
- **<big>WriteStringToFile</big>** : 将字符串写入文件。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteStringToFile)]
[[play](https://go.dev/play/p/GhLS6d8lH_g)]
- **<big>ReadFile</big>** : 读取文件或者URL。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadFile)]
<h3 id="formatter"> 10. formatter 格式化器包含一些数据格式化处理方法。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -1089,6 +1098,14 @@ import "github.com/duke-git/lancet/v2/random"
- **<big>RandUniqueIntSlice</big>** : 生成一个不重复的长度为 n 的随机 int 切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandUniqueIntSlice)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
- **<big>RandSymbolChar</big>** : 生成给定长度的随机符号字符串。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandSymbolChar)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
- **<big>RandFloat</big>** : 生成随机float64数字可以指定范围和精度。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandFloat)]
[[play](https://go.dev/play/p/uBkRSOz73Ec)]
- **<big>RandFloats</big>** : 生成随机float64数字切片可以指定长度范围和精度.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandFloats)]
<h3 id="retry"> 17. retry 重试执行函数直到函数运行成功或被 context cancel。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -1114,7 +1131,7 @@ import "github.com/duke-git/lancet/v2/retry"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/retry.md#RetryTimes)]
[[play](https://go.dev/play/p/ssfVeU2SwLO)]
<h3 id="slice"> 18. slice 包含操作切片的方法集合。&nbsp; &nbsp; &nbsp; &nbsp; [回到目录](#index)
<h3 id="slice"> 18. slice 包含操作切片的方法集合。&nbsp; &nbsp; &nbsp; &nbsp; <a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/slice"
@@ -1329,6 +1346,12 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>Join</big>** : 用指定的分隔符链接切片元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Join)]
[[play](https://go.dev/play/p/huKzqwNDD7V)]
- **<big>Partition</big>** : 根据给定的predicate判断函数分组切片元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Partition)]
[[play](https://go.dev/play/p/lkQ3Ri2NQhV)]
- **<big>Random</big>** : 随机返回切片中元素以及下标, 当切片长度为0时返回下标-1。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Random)]
<h3 id="stream"> 19. stream 流,该包仅验证简单的 stream 实现,功能有限。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -1547,6 +1570,9 @@ import "github.com/duke-git/lancet/v2/strutil"
- **<big>IsBlank</big>** : 检查字符串是否为空格或空。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#IsBlank)]
[[play](https://go.dev/play/p/6zXRH_c0Qd3)]
- **<big>IsNotBlank</big>** : 检查字符串是否不为空。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#IsNotBlank)]
[[play](https://go.dev/play/p/e_oJW0RAquA)]
- **<big>HasPrefixAny</big>** : 检查字符串是否以指定字符串数组中的任何一个开头。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#HasPrefixAny)]
[[play](https://go.dev/play/p/8UUTl2C5slo)]
@@ -1572,7 +1598,6 @@ import "github.com/duke-git/lancet/v2/strutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#RemoveWhiteSpace)]
[[play](https://go.dev/play/p/HzLC9vsTwkf)]
<h3 id="system"> 22. system 包含 os, runtime, shell command 的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
@@ -1833,6 +1858,33 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsPrintable</big>** : 检查字符串是否全部为可打印字符。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsPrintable)]
[[play](https://go.dev/play/p/Pe1FE2gdtTP)]
- **<big>IsBin</big>** : 检查字符串是否是有效的二进制数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsBin)]
[[play](https://go.dev/play/p/ogPeg2XJH4P)]
- **<big>IsHex</big>** : 检查字符串是否是有效的十六进制数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsHex)]
[[play](https://go.dev/play/p/M2qpHbEwmm7)]
- **<big>IsBase64URL</big>** : 检查字符串是否是有效的 base64 url。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsBase64URL)]
[[play](https://go.dev/play/p/vhl4mr8GZ6S)]
- **<big>IsJWT</big>** : 检查字符串是否是有效的 JSON Web Token (JWT)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsJWT)]
[[play](https://go.dev/play/p/R6Op7heJbKI)]
- **<big>IsVisa</big>** : 检查字符串是否是有效的 visa 卡号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsVisa)]
[[play](https://go.dev/play/p/SdS2keOyJsl)]
- **<big>IsMasterCard</big>** : 检查字符串是否是有效的 MasterCard 卡号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsMasterCard)]
[[play](https://go.dev/play/p/CwWBFRrG27b)]
- **<big>IsAmericanExpress</big>** : 检查字符串是否是有效的 American Express 卡号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsAmericanExpress)]
[[play](https://go.dev/play/p/HIDFpcOdpkd)]
- **<big>IsUnionPay</big>** : 检查字符串是否是有效的美国银联卡号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsUnionPay)]
[[play](https://go.dev/play/p/CUHPEwEITDf)]
- **<big>IsChinaUnionPay</big>** : 检查字符串是否是有效的中国银联卡号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsChinaUnionPay)]
[[play](https://go.dev/play/p/yafpdxLiymu)]
<h3 id="xerror"> 25. xerror 包实现一些错误处理函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
@@ -1855,7 +1907,7 @@ import "github.com/duke-git/lancet/v2/xerror"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/xerror.md#XError_Wrap)]
[[play](https://go.dev/play/p/RpjJ5u5sc97)]
- **<big>XError_Unwrap</big>** : 解构 XEerror 为 error 对象。适配 github.com/pkg/errors。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/xerror.md#XError_Unwrap)]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/xerror.md#XError_Unwrap)
[[play](https://go.dev/play/p/VUXJ8BST4c6)]
- **<big>XError_With</big>** : 添加与 XError 对象的键和值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/xerror.md#XError_With)]
@@ -1888,7 +1940,7 @@ import "github.com/duke-git/lancet/v2/xerror"
## 赞助
您好,我是一名软件开发者,从事开发工作 13 年。热爱软件开源。并愿意为此付出精力。是开源项目lancet的作者。Lancet 自两年前开源发布以来,已有超过 1000 个内外部项目使用。lancet一直会对所有用户免费。您的支持是对我继续奋斗的有力鼓励。谢谢! 微信扫描以下二维码或点击以下赞助按钮发起赞助。
您好,我是一名软件开发者,从事开发工作 13 年。热爱软件开源。并愿意为此付出精力。是开源项目 lancet 的作者。Lancet 自两年前开源发布以来,已有超过 1000 个内外部项目使用。lancet 一直会对所有用户免费。您的支持是对我继续奋斗的有力鼓励。谢谢! 微信扫描以下二维码或点击以下赞助按钮发起赞助。
<div style="position: relative;display: inline-block;">
<img src="./docs/public/wechat_pay.png" width="260" height="260"/>
@@ -1898,12 +1950,11 @@ import "github.com/duke-git/lancet/v2/xerror"
<br/>
<br/>
*捐赠的资金将用于后续lancet官网的维护和云服务器的费用支付。或者当我写代码困倦时给我买杯 ☕️。*
_捐赠的资金将用于后续[lancet](https://www.golancet.cn/)官网的维护和云服务器的费用支付。或者当我写代码困倦时,给我买杯 ☕️。_
## 贡献者
感谢所有为lancet贡献过代码的人
感谢所有为 lancet 贡献过代码的人!
<a href="https://github.com/duke-git/lancet/graphs/contributors">
<img src="https://contrib.rocks/image?repo=duke-git/lancet" />

View File

@@ -70,7 +70,7 @@ func compareRefValue(operator string, leftObj, rightObj any, kind reflect.Kind)
switch operator {
case equal:
if bytes.Compare(bytesObj1, bytesObj2) == 0 {
if bytes.Equal(bytesObj1, bytesObj2) {
return true
}
case lessThan:

View File

@@ -13,6 +13,7 @@ import (
"crypto/des"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"io"
@@ -505,3 +506,32 @@ func RsaDecrypt(data []byte, privateKeyFileName string) []byte {
}
return plainText
}
// GenerateRsaKeyPair create rsa private and public key.
// Play: https://go.dev/play/p/sSVmkfENKMz
func GenerateRsaKeyPair(keySize int) (*rsa.PrivateKey, *rsa.PublicKey) {
privateKey, _ := rsa.GenerateKey(rand.Reader, keySize)
return privateKey, &privateKey.PublicKey
}
// RsaEncryptOAEP encrypts the given data with RSA-OAEP.
// Play: https://go.dev/play/p/sSVmkfENKMz
func RsaEncryptOAEP(data []byte, label []byte, key rsa.PublicKey) ([]byte, error) {
encryptedBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, &key, data, label)
if err != nil {
return nil, err
}
return encryptedBytes, nil
}
// RsaDecryptOAEP decrypts the data with RSA-OAEP.
// Play: https://go.dev/play/p/sSVmkfENKMz
func RsaDecryptOAEP(ciphertext []byte, label []byte, key rsa.PrivateKey) ([]byte, error) {
decryptedBytes, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, &key, ciphertext, label)
if err != nil {
return nil, err
}
return decryptedBytes, nil
}

View File

@@ -1,6 +1,8 @@
package cryptor
import "fmt"
import (
"fmt"
)
func ExampleAesEcbEncrypt() {
data := "hello"
@@ -484,3 +486,25 @@ func ExampleSha512WithBase64() {
// Output:
// m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==
}
func ExampleRsaEncryptOAEP() {
pri, pub := GenerateRsaKeyPair(1024)
data := []byte("hello world")
label := []byte("123456")
encrypted, err := RsaEncryptOAEP(data, label, *pub)
if err != nil {
return
}
decrypted, err := RsaDecryptOAEP([]byte(encrypted), label, *pri)
if err != nil {
return
}
fmt.Println(string(decrypted))
// Output:
// hello world
}

View File

@@ -150,3 +150,21 @@ func TestRsaEncrypt(t *testing.T) {
assert := internal.NewAssert(t, "TestRsaEncrypt")
assert.Equal(string(data), string(decrypted))
}
func TestRsaEncryptOAEP(t *testing.T) {
assert := internal.NewAssert(t, "TestRsaEncrypt")
t.Parallel()
pri, pub := GenerateRsaKeyPair(1024)
data := []byte("hello world")
label := []byte("123456")
encrypted, err := RsaEncryptOAEP(data, label, *pub)
assert.IsNil(err)
decrypted, err := RsaDecryptOAEP([]byte(encrypted), label, *pri)
assert.IsNil(err)
assert.Equal("hello world", string(decrypted))
}

View File

@@ -12,7 +12,7 @@ import (
// ArrayQueue implements queue with slice
type ArrayQueue[T any] struct {
items []T
data []T
head int
tail int
capacity int
@@ -21,7 +21,7 @@ type ArrayQueue[T any] struct {
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
return &ArrayQueue[T]{
items: make([]T, 0, capacity),
data: make([]T, 0, capacity),
head: 0,
tail: 0,
capacity: capacity,
@@ -33,7 +33,7 @@ func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
func (q *ArrayQueue[T]) Data() []T {
items := []T{}
for i := q.head; i < q.tail; i++ {
items = append(items, q.items[i])
items = append(items, q.data[i])
}
return items
}
@@ -55,40 +55,71 @@ func (q *ArrayQueue[T]) IsFull() bool {
// Front return front value of queue
func (q *ArrayQueue[T]) Front() T {
return q.items[0]
return q.data[0]
}
// Back return back value of queue
func (q *ArrayQueue[T]) Back() T {
return q.items[q.size-1]
return q.data[q.size-1]
}
// EnQueue put element into queue
func (q *ArrayQueue[T]) Enqueue(item T) bool {
if q.head == 0 && q.tail == q.capacity {
return false
} else if q.head != 0 && q.tail == q.capacity {
for i := q.head; i < q.tail; i++ {
q.items[i-q.head] = q.items[i]
if q.tail < q.capacity {
q.data = append(q.data, item)
// q.tail++
q.data[q.tail] = item
} else {
//upgrade
if q.head > 0 {
for i := 0; i < q.tail-q.head; i++ {
q.data[i] = q.data[i+q.head]
}
q.tail -= q.head
q.head = 0
} else {
if q.capacity < 65536 {
if q.capacity == 0 {
q.capacity = 1
}
q.capacity *= 2
} else {
q.capacity += 2 ^ 16
}
tmp := make([]T, q.capacity, q.capacity)
copy(tmp, q.data)
q.data = tmp
}
q.tail = q.tail - q.head
q.head = 0
q.data[q.tail] = item
}
q.items = append(q.items, item)
q.tail++
q.size++
return true
}
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
var item T
if q.head == q.tail {
if q.size == 0 {
return item, false
}
item = q.items[q.head]
item = q.data[q.head]
q.head++
if q.head >= 1024 || q.head*2 > q.tail {
q.capacity -= q.head
q.tail -= q.head
tmp := make([]T, q.capacity, q.capacity)
copy(tmp, q.data[q.head:])
q.data = tmp
q.head = 0
}
q.size--
return item, true
}
@@ -96,7 +127,7 @@ func (q *ArrayQueue[T]) Dequeue() (T, bool) {
// Clear the queue data
func (q *ArrayQueue[T]) Clear() {
capacity := q.capacity
q.items = make([]T, 0, capacity)
q.data = make([]T, 0, capacity)
q.head = 0
q.tail = 0
q.size = 0
@@ -105,7 +136,7 @@ func (q *ArrayQueue[T]) Clear() {
// Contain checks if the value is in queue or not
func (q *ArrayQueue[T]) Contain(value T) bool {
for _, v := range q.items {
for _, v := range q.data {
if reflect.DeepEqual(v, value) {
return true
}
@@ -117,7 +148,7 @@ func (q *ArrayQueue[T]) Contain(value T) bool {
func (q *ArrayQueue[T]) Print() {
info := "["
for i := q.head; i < q.tail; i++ {
info += fmt.Sprintf("%+v, ", q.items[i])
info += fmt.Sprintf("%+v, ", q.data[i])
}
info += "]"
fmt.Println(info)

View File

@@ -11,7 +11,7 @@ func TestArrayQueue_Enqueue(t *testing.T) {
assert := internal.NewAssert(t, "TestArrayQueue_Enqueue")
queue := NewArrayQueue[int](5)
queue := NewArrayQueue[int](2)
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)

View File

@@ -39,7 +39,7 @@ export const slugify = (str: string): string =>
export const commonConfig = defineConfig({
title: 'Lancet',
appearance: 'dark',
appearance: true,
markdown: {
theme: {
@@ -83,7 +83,7 @@ export const commonConfig = defineConfig({
footer: {
copyright: 'Copyright © 2023-present Duke Du',
message: 'Released under the MIT License.',
message: '备案号: 京ICP备2023022770号',
},
},
})

View File

@@ -1,6 +1,6 @@
import type { DefaultTheme, LocaleSpecificConfig } from 'vitepress'
export const META_URL = 'https://golancet.cn'
export const META_URL = 'https://www.golancet.cn/en/'
export const META_TITLE = 'Lancet'
export const META_DESCRIPTION = 'A powerful util function library of Go'
@@ -49,7 +49,7 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
],
sidebar: {
'/en/': [
'/en/guide/': [
{
text: 'Introduction',
collapsed: false,
@@ -59,19 +59,37 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
link: '/en/guide/introduction',
},
{
text: 'getting started',
text: 'Getting started',
link: '/en/guide/getting_started',
},
],
},
{
text: 'Contribute Code',
collapsed: false,
items: [
{
text: 'Contribution guide',
link: '/en/guide/contribution_guide',
},
{
text: 'Contributors',
link: '/en/guide/contributors',
},
],
},
{
text: 'API Reference',
link: '/en/api/overview'
},
],
'/en/api/': [
{
text: 'overview',
items: [{ text: 'overview of API', link: '/en/api/overview' }],
text: 'Overview',
items: [{ text: 'API overview', link: '/en/api/overview' }],
},
{
text: 'packages',
text: 'Packages',
collapsed: false,
items: [
{ text: 'algorithm', link: '/en/api/packages/algorithm' },

View File

@@ -1,6 +1,6 @@
import type { DefaultTheme, LocaleSpecificConfig } from 'vitepress'
export const META_URL = 'https://golancet.cn'
export const META_URL = 'https://www.golancet.cn'
export const META_TITLE = 'Lancet'
export const META_DESCRIPTION = '一个强大的Go语言工具函数库'
@@ -58,10 +58,10 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
],
sidebar: {
'/': [
'/guide/': [
{
text: '介绍',
collapsed: true,
collapsed: false,
items: [
{
text: 'Lancet是什么',
@@ -73,6 +73,24 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
},
],
},
{
text: '贡献代码',
collapsed: false,
items: [
{
text: '贡献指南',
link: '/guide/contribution_guide',
},
{
text: '贡献者',
link: '/guide/contributors',
},
],
},
{
text: 'API手册',
link: '/api/overview'
},
],
'/api/': [

View File

@@ -27,7 +27,7 @@ outline: deep
display: inline-block;
vertical-align: middle;
line-height: 40px;
background: #ecefff;
background: #10b981;
border: 1px solid;
margin-right: 10px;
margin-bottom: 10px;

View File

@@ -1,6 +1,6 @@
# Cryptor
cryptor包包含数据加密和解密功能。支持 base64, md5, hmac, hash, aes, des, rsa。
cryptor 包包含数据加密和解密功能。支持 base64, md5, hmac, hash, aes, des, rsa。
<div STYLE="page-break-after: always;"></div>
@@ -65,6 +65,9 @@ import (
- [GenerateRsaKey](#GenerateRsaKey)
- [RsaEncrypt](#RsaEncrypt)
- [RsaDecrypt](#RsaDecrypt)
- [GenerateRsaKeyPair](#GenerateRsaKeyPair)
- [RsaEncryptOAEP](#RsaEncryptOAEP)
- [RsaDecryptOAEP](#RsaDecryptOAEP)
<div STYLE="page-break-after: always;"></div>
@@ -988,13 +991,13 @@ import (
func main() {
str := "hello"
key := "12345"
key := "12345"
hms := cryptor.HmacSha512WithBase64(str, key)
fmt.Println(hms)
hms := cryptor.HmacSha512WithBase64(str, key)
fmt.Println(hms)
// Output:
// 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A==
// Output:
// 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A==
}
```
@@ -1051,10 +1054,10 @@ import (
func main() {
md5Str := cryptor.Md5StringWithBase64("hello")
fmt.Println(md5Str)
fmt.Println(md5Str)
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
}
```
@@ -1080,10 +1083,10 @@ import (
func main() {
md5Str := cryptor.Md5Byte([]byte{'a'})
fmt.Println(md5Str)
fmt.Println(md5Str)
// Output:
// 0cc175b9c0f1b6a831c399e269772661
// Output:
// 0cc175b9c0f1b6a831c399e269772661
}
```
@@ -1109,10 +1112,10 @@ import (
func main() {
md5Str := cryptor.Md5ByteWithBase64([]byte("hello"))
fmt.Println(md5Str)
fmt.Println(md5Str)
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
}
```
@@ -1195,10 +1198,10 @@ import (
func main() {
result := cryptor.Sha1WithBase64("hello")
fmt.Println(result)
fmt.Println(result)
// Output:
// qvTGHdzF6KLavt4PO0gs2a6pQ00=
// Output:
// qvTGHdzF6KLavt4PO0gs2a6pQ00=
}
```
@@ -1255,10 +1258,10 @@ import (
func main() {
result := cryptor.Sha256WithBase64("hello")
fmt.Println(result)
fmt.Println(result)
// Output:
// LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
// Output:
// LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
}
```
@@ -1315,10 +1318,10 @@ import (
func main() {
result := cryptor.Sha512WithBase64("hello")
fmt.Println(result)
fmt.Println(result)
// Output:
// m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==
// Output:
// m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==
}
```
@@ -1423,3 +1426,114 @@ func main() {
// hello
}
```
### <span id="GenerateRsaKeyPair">GenerateRsaKeyPair</span>
<p>创建rsa公钥私钥和key。</p>
<b>函数签名:</b>
```go
func GenerateRsaKeyPair(keySize int) (*rsa.PrivateKey, *rsa.PublicKey)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/sSVmkfENKMz)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
pri, pub := cryptor.GenerateRsaKeyPair(1024)
}
```
### <span id="RsaEncryptOAEP">RsaEncryptOAEP</span>
<p>rsa OAEP加密。</p>
<b>函数签名:</b>
```go
func RsaEncryptOAEP(data []byte, label []byte, key rsa.PublicKey) ([]byte, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/sSVmkfENKMz)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
pri, pub := cryptor.GenerateRsaKeyPair(1024)
data := []byte("hello world")
label := []byte("123456")
encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub)
if err != nil {
return
}
decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri)
if err != nil {
return
}
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="RsaDecryptOAEP">RsaDecryptOAEP</span>
<p>rsa OAEP解密。</p>
<b>函数签名:</b>
```go
func RsaDecryptOAEP(ciphertext []byte, label []byte, key rsa.PrivateKey) ([]byte, error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/sSVmkfENKMz)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
pri, pub := cryptor.GenerateRsaKeyPair(1024)
data := []byte("hello world")
label := []byte("123456")
encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub)
if err != nil {
return
}
decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri)
if err != nil {
return
}
fmt.Println(string(decrypted))
// Output:
// hello world
}
```

View File

@@ -47,6 +47,7 @@ import (
- [WriteCsvFile](#WriteCsvFile)
- [WriteStringToFile](#WriteStringToFile)
- [WriteBytesToFile](#WriteBytesToFile)
- [ReadFile](#ReadFile)
<div STYLE="page-break-after: always;"></div>
@@ -839,3 +840,41 @@ func main() {
// hello
}
```
### <span id="ReadFile">ReadFile</span>
<p>读取文件或者URL。</p>
<b>函数签名:</b>
```go
func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/uNep3Tr8fqF)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/fileutil"
)
func main() {
reader, fn, err := fileutil.ReadFile("https://httpbin.org/robots.txt")
if err != nil {
return
}
defer fn()
dat, err := io.ReadAll(reader)
if err != nil {
return
}
fmt.Println(string(dat))
// Output:
// User-agent: *
// Disallow: /deny
}
```

View File

@@ -29,8 +29,11 @@ import (
- [RandLower](#RandLower)
- [RandNumeral](#RandNumeral)
- [RandNumeralOrLetter](#RandNumeralOrLetter)
- [RandSymbolChar](#RandSymbolChar)
- [UUIdV4](#UUIdV4)
- [RandUniqueIntSlice](#RandUniqueIntSlice)
- [RandFloat](#RandFloat)
- [RandFloats](#RandFloats)
<div STYLE="page-break-after: always;"></div>
@@ -46,7 +49,7 @@ import (
func RandBytes(length int) []byte
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/EkiLESeXf8d)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/EkiLESeXf8d)</span></b>
```go
package main
@@ -72,7 +75,7 @@ func main() {
func RandInt(min, max int) int
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/pXyyAAI5YxD)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/pXyyAAI5YxD)</span></b>
```go
package main
@@ -98,7 +101,7 @@ func main() {
func RandString(length int) string
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/W2xvRUXA7Mi)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/W2xvRUXA7Mi)</span></b>
```go
package main
@@ -124,7 +127,7 @@ func main() {
func RandUpper(length int) string
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/29QfOh0DVuh)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/29QfOh0DVuh)</span></b>
```go
package main
@@ -150,7 +153,7 @@ func main() {
func RandLower(length int) string
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/XJtZ471cmtI)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/XJtZ471cmtI)</span></b>
```go
package main
@@ -176,7 +179,7 @@ func main() {
func RandNumeral(length int) string
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/g4JWVpHsJcf)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/g4JWVpHsJcf)</span></b>
```go
package main
@@ -202,7 +205,7 @@ func main() {
func RandNumeralOrLetter(length int) string
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/19CEQvpx2jD)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/19CEQvpx2jD)</span></b>
```go
package main
@@ -218,6 +221,32 @@ func main() {
}
```
### <span id="RandSymbolChar">RandSymbolChar</span>
<p>生成给定长度的随机符号字符串. 符号字符包括: !@#$%^&*()_+-=[]{}|;':\",./<>?。</p>
<b>函数签名:</b>
```go
func RandSymbolChar(length int) string
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/random"
)
func main() {
randStr := random.RandSymbolChar(6)
fmt.Println(randStr) //@#(_")
}
```
### <span id="UUIdV4">UUIdV4</span>
<p>生成UUID v4字符串</p>
@@ -228,7 +257,7 @@ func main() {
func UUIdV4() (string, error)
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/_Z9SFmr28ft)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/_Z9SFmr28ft)</span></b>
```go
package main
@@ -257,7 +286,7 @@ func main() {
func RandUniqueIntSlice(n, min, max int) []int
```
<b>示例:<span class="run-container">[运行](https://go.dev/play/p/uBkRSOz73Ec)</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/uBkRSOz73Ec)</span></b>
```go
package main
@@ -272,3 +301,55 @@ func main() {
fmt.Println(result) //[0 4 7 1 5] (random)
}
```
### <span id="RandFloat">RandFloat</span>
<p>生成随机float64数字可以指定范围和精度。</p>
<b>函数签名:</b>
```go
func RandFloat(min, max float64, precision int) float64
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/random"
)
func main() {
floatNumber := random.RandFloat(1.0, 5.0, 2)
fmt.Println(floatNumber) //2.14 (random number)
}
```
### <span id="RandFloats">RandFloats</span>
<p>生成随机float64数字切片指定长度范围和精度.</p>
<b>函数签名:</b>
```go
func RandFloats(n int, min, max float64, precision int) []float64
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/random"
)
func main() {
floatNumbers := random.RandFloats(5, 1.0, 5.0, 2)
fmt.Println(floatNumber) //[3.42 3.99 1.3 2.38 4.23] (random)
}
```

View File

@@ -77,7 +77,7 @@ import (
- [IsSortedByKey](#IsSortedByKey)
- [Sort](#Sort)
- [SortBy](#SortBy)
- [SortByField<sup>deprecated</sup>](#SortByField)
- [SortByField](#SortByField)
- [Some](#Some)
- [StringSlice<sup>deprecated</sup>](#StringSlice)
- [SymmetricDifference](#SymmetricDifference)
@@ -91,6 +91,7 @@ import (
- [Without](#Without)
- [KeyBy](#KeyBy)
- [Join](#Join)
- [Partition](#Partition)
<div STYLE="page-break-after: always;"></div>
@@ -2002,9 +2003,9 @@ func main() {
}
```
### <span id="SortByField">SortByField (已弃用: 请使用 Sort 或 SortBy 代替该方法)</span>
### <span id="SortByField">SortByField</span>
<p>按字段对结构切片进行排序。slice元素应为struct字段类型应为int、uint、string或bool。 默认排序类型是升序asc如果是降序设置 sortType 为 desc</p>
<p>按字段对结构切片进行排序。slice元素应为struct排序字段field类型应为int、uint、string或bool。 默认排序类型是升序asc如果是降序设置 sortType 为 desc</p>
<b>函数签名:</b>
@@ -2452,3 +2453,70 @@ func main() {
// 1-2-3-4-5
}
```
### <span id="Partition">Partition</span>
<p>根据给定的predicate判断函数分组切片元素。</p>
<b>函数签名:</b>
```go
func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/lkQ3Ri2NQhV)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
}
```
### <span id="Random">Random</span>
<p>随机返回切片中元素以及下标, 当切片长度为0时返回下标-1</p>
<b>函数签名:</b>
```go
func Random[T any](slice []T) (val T, idx int)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](TODO)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
}
```

View File

@@ -49,6 +49,7 @@ import (
- [StringToBytes](#StringToBytes)
- [BytesToString](#BytesToString)
- [IsBlank](#IsBlank)
- [IsNotBlank](#IsNotBlank)
- [HasPrefixAny](#HasPrefixAny)
- [HasSuffixAny](#HasSuffixAny)
- [IndexOffset](#IndexOffset)
@@ -1075,6 +1076,45 @@ func main() {
}
```
### <span id="IsNotBlank">IsNotBlank</span>
<p>Checks if a string is not whitespace or not empty.</p>
<b>函数签名:</b>
```go
func IsNotBlank(str string) bool
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/e_oJW0RAquA)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/strutil"
)
func main() {
result1 := strutil.IsNotBlank("")
result2 := strutil.IsNotBlank(" ")
result3 := strutil.IsNotBlank("\t\v\f\n")
result4 := strutil.IsNotBlank(" 中文")
result5 := strutil.IsNotBlank(" world ")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// false
// false
// false
// true
// true
}
```
### <span id="HasPrefixAny">HasPrefixAny</span>
<p>检查字符串是否以指定字符串数组中的任何一个开头。</p>

View File

@@ -55,10 +55,18 @@ import (
- [IsZeroValue](#IsZeroValue)
- [IsGBK](#IsGBK)
- [IsPrintable](#IsPrintable)
- [IsBin](#IsBin)
- [IsHex](#IsHex)
- [IsBase64URL](#IsBase64URL)
- [IsJWT](#IsJWT)
- [IsVisa](#IsVisa)
- [IsMasterCard](#IsMasterCard)
- [IsAmericanExpress](#IsAmericanExpress)
- [IsUnionPay](#IsUnionPay)
- [IsChinaUnionPay](#IsChinaUnionPay)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="ContainChinese">ContainChinese</span>
@@ -71,7 +79,7 @@ import (
func ContainChinese(s string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/7DpU0uElYeM)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/7DpU0uElYeM)</span></b>
```go
import (
@@ -105,7 +113,7 @@ func main() {
func ContainLetter(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/lqFD04Yyewp)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/lqFD04Yyewp)</span></b>
```go
import (
@@ -139,7 +147,7 @@ func main() {
func ContainLower(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/Srqi1ItvnAA)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/Srqi1ItvnAA)</span></b>
```go
import (
@@ -173,7 +181,7 @@ func main() {
func ContainUpper(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/CmWeBEk27-z)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/CmWeBEk27-z)</span></b>
```go
import (
@@ -207,7 +215,7 @@ func main() {
func IsAlpha(s string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/7Q5sGOz2izQ)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/7Q5sGOz2izQ)</span></b>
```go
import (
@@ -241,7 +249,7 @@ func main() {
func IsAllUpper(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/ZHctgeK1n4Z)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/ZHctgeK1n4Z)</span></b>
```go
import (
@@ -275,7 +283,7 @@ func main() {
func IsAllLower(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/GjqCnOfV6cM)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/GjqCnOfV6cM)</span></b>
```go
import (
@@ -309,7 +317,7 @@ func main() {
func IsASCII(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/hfQNPLX0jNa)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/hfQNPLX0jNa)</span></b>
```go
import (
@@ -349,7 +357,7 @@ func main() {
func IsBase64(base64 string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/sWHEySAt6hl)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/sWHEySAt6hl)</span></b>
```go
import (
@@ -380,7 +388,7 @@ func main() {
func IsChineseMobile(mobileNum string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/GPYUlGTOqe3)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/GPYUlGTOqe3)</span></b>
```go
import (
@@ -411,7 +419,7 @@ func main() {
func IsChineseIdNum(id string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/d8EWhl2UGDF)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/d8EWhl2UGDF)</span></b>
```go
import (
@@ -442,7 +450,7 @@ func main() {
func IsChinesePhone(phone string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/RUD_-7YZJ3I)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/RUD_-7YZJ3I)</span></b>
```go
import (
@@ -473,7 +481,7 @@ func main() {
func IsCreditCard(creditCart string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/sNwwL6B0-v4)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/sNwwL6B0-v4)</span></b>
```go
import (
@@ -504,7 +512,7 @@ func main() {
func IsDns(dns string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/jlYApVLLGTZ)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/jlYApVLLGTZ)</span></b>
```go
import (
@@ -538,7 +546,7 @@ func main() {
func IsEmail(email string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/Os9VaFlT33G)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/Os9VaFlT33G)</span></b>
```go
import (
@@ -569,7 +577,7 @@ func main() {
func IsEmptyString(s string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/dpzgUjFnBCX)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/dpzgUjFnBCX)</span></b>
```go
import (
@@ -603,7 +611,7 @@ func main() {
func IsInt(v any) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/eFoIHbgzl-z)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/eFoIHbgzl-z)</span></b>
```go
import (
@@ -640,7 +648,7 @@ func main() {
func IsFloat(v any) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/vsyG-sxr99_Z)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/vsyG-sxr99_Z)</span></b>
```go
import (
@@ -677,7 +685,7 @@ func main() {
func IsNumber(v any) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/mdJHOAvtsvF)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/mdJHOAvtsvF)</span></b>
```go
import (
@@ -704,7 +712,6 @@ func main() {
}
```
### <span id="IsIntStr">IsIntStr</span>
<p>验证字符串是否是可以转换为整数。</p>
@@ -715,7 +722,7 @@ func main() {
func IsIntStr(s string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/jQRtFv-a0Rk)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/jQRtFv-a0Rk)</span></b>
```go
import (
@@ -752,7 +759,7 @@ func main() {
func IsFloatStr(s string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/LOYwS_Oyl7U)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/LOYwS_Oyl7U)</span></b>
```go
import (
@@ -789,7 +796,7 @@ func main() {
func IsNumberStr(s string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/LzaKocSV79u)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/LzaKocSV79u)</span></b>
```go
import (
@@ -826,7 +833,7 @@ func main() {
func IsJSON(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/8Kip1Itjiil)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/8Kip1Itjiil)</span></b>
```go
import (
@@ -863,7 +870,7 @@ func main() {
func IsRegexMatch(s, regex string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/z_XeZo_litG)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/z_XeZo_litG)</span></b>
```go
import (
@@ -884,8 +891,6 @@ func main() {
}
```
### <span id="IsIp">IsIp</span>
<p>验证字符串是否是ip地址。</p>
@@ -896,7 +901,7 @@ func main() {
func IsIp(ipstr string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/FgcplDvmxoD)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/FgcplDvmxoD)</span></b>
```go
import (
@@ -933,7 +938,7 @@ func main() {
func IsIpV4(ipstr string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/zBGT99EjaIu)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/zBGT99EjaIu)</span></b>
```go
import (
@@ -964,7 +969,7 @@ func main() {
func IsIpV6(ipstr string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/AHA0r0AzIdC)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/AHA0r0AzIdC)</span></b>
```go
import (
@@ -995,7 +1000,7 @@ func main() {
func IsStrongPassword(password string, length int) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/QHdVcSQ3uDg)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/QHdVcSQ3uDg)</span></b>
```go
import (
@@ -1026,7 +1031,7 @@ func main() {
func IsUrl(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/pbJGa7F98Ka)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/pbJGa7F98Ka)</span></b>
```go
import (
@@ -1061,7 +1066,7 @@ func main() {
func IsWeakPassword(password string, length int) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/wqakscZH5gH)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/wqakscZH5gH)</span></b>
```go
import (
@@ -1092,7 +1097,7 @@ func main() {
func IsZeroValue(value any) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/UMrwaDCi_t4)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/UMrwaDCi_t4)</span></b>
```go
import (
@@ -1129,7 +1134,7 @@ func main() {
func IsGBK(data []byte) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/E2nt3unlmzP)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/E2nt3unlmzP)</span></b>
```go
import (
@@ -1151,7 +1156,6 @@ func main() {
}
```
### <span id="IsPrintable">IsPrintable</span>
<p>检查字符串是否全部为可打印字符。</p>
@@ -1162,7 +1166,7 @@ func main() {
func IsPrintable(str string) bool
```
<b>示例:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/Pe1FE2gdtTP)</span></b>
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/Pe1FE2gdtTP)</span></b>
```go
import (
@@ -1190,4 +1194,301 @@ func main() {
// true
// false
}
```
```
### <span id="IsBin">IsBin</span>
<p>检查字符串是否是有效的二进制数。</p>
<b>函数签名:</b>
```go
func IsBin(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/ogPeg2XJH4P)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsBin("0101")
result2 := validator.IsBin("0b1101")
result3 := validator.IsBin("b1101")
result4 := validator.IsBin("1201")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
```
### <span id="IsHex">IsHex</span>
<p>检查字符串是否是有效的十六进制数。</p>
<b>函数签名:</b>
```go
func IsHex(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/M2qpHbEwmm7)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsHex("0xabcde")
result2 := validator.IsHex("0XABCDE")
result3 := validator.IsHex("cdfeg")
result4 := validator.IsHex("0xcdfeg")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
```
### <span id="IsBase64URL">IsBase64URL</span>
<p>检查字符串是否是有效的base64 url。</p>
<b>函数签名:</b>
```go
func IsBase64URL(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/vhl4mr8GZ6S)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ")
result2 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ==")
result3 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ=")
result4 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ===")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
```
### <span id="IsJWT">IsJWT</span>
<p>检查字符串是否是有效的JSON Web Token (JWT)。</p>
<b>函数签名:</b>
```go
func IsJWT(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/R6Op7heJbKI)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910")
result2 := validator.IsJWT("abc")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsVisa">IsVisa</span>
<p>检查字符串是否是有效的visa卡号。</p>
<b>函数签名:</b>
```go
func IsVisa(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/SdS2keOyJsl)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsVisa("4111111111111111")
result2 := validator.IsVisa("123")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsMasterCard">IsMasterCard</span>
<p>检查字符串是否是有效的MasterCard卡号。</p>
<b>函数签名:</b>
```go
func IsMasterCard(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/CwWBFRrG27b)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsMasterCard("5425233430109903")
result2 := validator.IsMasterCard("4111111111111111")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsAmericanExpress">IsAmericanExpress</span>
<p>检查字符串是否是有效的American Express卡号。</p>
<b>函数签名:</b>
```go
func IsAmericanExpress(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/HIDFpcOdpkd)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsAmericanExpress("342883359122187")
result2 := validator.IsAmericanExpress("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsUnionPay">IsUnionPay</span>
<p>检查字符串是否是有效的美国银联卡号。</p>
<b>函数签名:</b>
```go
func IsUnionPay(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/CUHPEwEITDf)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsUnionPay("6221263430109903")
result2 := validator.IsUnionPay("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsChinaUnionPay">IsChinaUnionPay</span>
<p>检查字符串是否是有效的中国银联卡号。</p>
<b>函数签名:</b>
```go
func IsChinaUnionPay(v string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/yafpdxLiymu)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsChinaUnionPay("6250941006528599")
result2 := validator.IsChinaUnionPay("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```

View File

@@ -27,7 +27,7 @@ outline: deep
display: inline-block;
vertical-align: middle;
line-height: 40px;
background: #ecefff;
background: #059669;
border: 1px solid;
margin-right: 10px;
margin-bottom: 10px;
@@ -37,7 +37,7 @@ outline: deep
</style>
<div>
<p class="package-title">lancet function module</p>
<p class="package-title">Lancet function module</p>
<div class="package-container">
<div class="package-cell">algorithm</div>
<div class="package-cell">compare</div>

View File

@@ -1,18 +1,18 @@
# Cryptor
Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go](https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go](https://github.com/duke-git/lancet/blob/main/cryptor/crypto.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/cryptor"
@@ -23,49 +23,51 @@ import (
## Index
- [AesEcbEncrypt](#AesEcbEncrypt)
- [AesEcbDecrypt](#AesEcbDecrypt)
- [AesCbcEncrypt](#AesCbcEncrypt)
- [AesCbcDecrypt](#AesCbcDecrypt)
- [AesCtrCrypt](#AesCtrCrypt)
- [AesCfbEncrypt](#AesCfbEncrypt)
- [AesCfbDecrypt](#AesCfbDecrypt)
- [AesOfbEncrypt](#AesOfbEncrypt)
- [AesOfbDecrypt](#AesOfbDecrypt)
- [Base64StdEncode](#Base64StdEncode)
- [Base64StdDecode](#Base64StdDecode)
- [DesEcbEncrypt](#DesEcbEncrypt)
- [DesEcbDecrypt](#DesEcbDecrypt)
- [DesCbcEncrypt](#DesCbcEncrypt)
- [DesCbcDecrypt](#DesCbcDecrypt)
- [DesCtrCrypt](#DesCtrCrypt)
- [DesCfbEncrypt](#DesCfbEncrypt)
- [DesCfbDecrypt](#DesCfbDecrypt)
- [DesOfbEncrypt](#DesOfbEncrypt)
- [DesOfbDecrypt](#DesOfbDecrypt)
- [HmacMd5](#HmacMd5)
- [HmacMd5WithBase64](#HmacMd5WithBase64)
- [HmacSha1](#HmacSha1)
- [HmacSha1WithBase64](#HmacSha1WithBase64)
- [HmacSha256](#HmacSha256)
- [HmacSha256WithBase64](#HmacSha256WithBase64)
- [HmacSha512](#HmacSha512)
- [HmacSha512WithBase64](#HmacSha512WithBase64)
- [Md5String](#Md5String)
- [Md5StringWithBase64](#Md5StringWithBase64)
- [Md5Byte](#Md5Byte)
- [Md5ByteWithBase64](#Md5ByteWithBase64)
- [Md5File](#Md5File)
- [Sha1](#Sha1)
- [Sha1WithBase64](#Sha1WithBase64)
- [Sha256](#Sha256)
- [Sha256WithBase64](#Sha256WithBase64)
- [Sha512](#Sha512)
- [Sha512WithBase64](#Sha512WithBase64)
- [GenerateRsaKey](#GenerateRsaKey)
- [RsaEncrypt](#RsaEncrypt)
- [RsaDecrypt](#RsaDecrypt)
- [AesEcbEncrypt](#AesEcbEncrypt)
- [AesEcbDecrypt](#AesEcbDecrypt)
- [AesCbcEncrypt](#AesCbcEncrypt)
- [AesCbcDecrypt](#AesCbcDecrypt)
- [AesCtrCrypt](#AesCtrCrypt)
- [AesCfbEncrypt](#AesCfbEncrypt)
- [AesCfbDecrypt](#AesCfbDecrypt)
- [AesOfbEncrypt](#AesOfbEncrypt)
- [AesOfbDecrypt](#AesOfbDecrypt)
- [Base64StdEncode](#Base64StdEncode)
- [Base64StdDecode](#Base64StdDecode)
- [DesEcbEncrypt](#DesEcbEncrypt)
- [DesEcbDecrypt](#DesEcbDecrypt)
- [DesCbcEncrypt](#DesCbcEncrypt)
- [DesCbcDecrypt](#DesCbcDecrypt)
- [DesCtrCrypt](#DesCtrCrypt)
- [DesCfbEncrypt](#DesCfbEncrypt)
- [DesCfbDecrypt](#DesCfbDecrypt)
- [DesOfbEncrypt](#DesOfbEncrypt)
- [DesOfbDecrypt](#DesOfbDecrypt)
- [HmacMd5](#HmacMd5)
- [HmacMd5WithBase64](#HmacMd5WithBase64)
- [HmacSha1](#HmacSha1)
- [HmacSha1WithBase64](#HmacSha1WithBase64)
- [HmacSha256](#HmacSha256)
- [HmacSha256WithBase64](#HmacSha256WithBase64)
- [HmacSha512](#HmacSha512)
- [HmacSha512WithBase64](#HmacSha512WithBase64)
- [Md5String](#Md5String)
- [Md5StringWithBase64](#Md5StringWithBase64)
- [Md5Byte](#Md5Byte)
- [Md5ByteWithBase64](#Md5ByteWithBase64)
- [Md5File](#Md5File)
- [Sha1](#Sha1)
- [Sha1WithBase64](#Sha1WithBase64)
- [Sha256](#Sha256)
- [Sha256WithBase64](#Sha256WithBase64)
- [Sha512](#Sha512)
- [Sha512WithBase64](#Sha512WithBase64)
- [GenerateRsaKey](#GenerateRsaKey)
- [RsaEncrypt](#RsaEncrypt)
- [RsaDecrypt](#RsaDecrypt)
- [GenerateRsaKeyPair](#GenerateRsaKeyPair)
- [RsaEncryptOAEP](#RsaEncryptOAEP)
- [RsaDecryptOAEP](#RsaDecryptOAEP)
<div STYLE="page-break-after: always;"></div>
@@ -80,6 +82,7 @@ import (
```go
func AesEcbEncrypt(data, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/zI6xsmuQRbn)</span></b>
```go
@@ -113,6 +116,7 @@ func main() {
```go
func AesEcbDecrypt(encrypted, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/zI6xsmuQRbn)</span></b>
```go
@@ -146,6 +150,7 @@ func main() {
```go
func AesCbcEncrypt(data, key []byte) []byte
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/IOq_g8_lKZD)</span></b>
```go
@@ -339,6 +344,7 @@ func main() {
// hello
}
```
### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
<p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -382,6 +388,7 @@ func main() {
```go
func Base64StdEncode(s string) string
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/VOaUyQUreoK)</span></b>
```go
@@ -400,6 +407,7 @@ func main() {
// aGVsbG8=
}
```
### <span id="Base64StdDecode">Base64StdDecode</span>
<p>Decode a base64 encoded string.</p>
@@ -463,6 +471,7 @@ func main() {
// hello
}
```
### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
<p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
@@ -565,6 +574,7 @@ func main() {
// hello
}
```
### <span id="DesCtrCrypt">DesCtrCrypt</span>
<p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p>
@@ -632,6 +642,7 @@ func main() {
// hello
}
```
### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -665,6 +676,7 @@ func main() {
// hello
}
```
### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
<p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
@@ -698,6 +710,7 @@ func main() {
// hello
}
```
### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
<p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
@@ -988,7 +1001,6 @@ func main() {
}
```
### <span id="Md5String">Md5String</span>
<p>Get the md5 value of string.</p>
@@ -1366,11 +1378,11 @@ func main() {
if err != nil {
return
}
data := []byte("hello")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted))
// Output:
@@ -1378,7 +1390,6 @@ func main() {
}
```
### <span id="RsaDecrypt">RsaDecrypt</span>
<p>Decrypt data with private key file useing ras algorithm.</p>
@@ -1404,11 +1415,11 @@ func main() {
if err != nil {
return
}
data := []byte("hello")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted))
// Output:
@@ -1416,5 +1427,113 @@ func main() {
}
```
### <span id="GenerateRsaKeyPair">GenerateRsaKeyPair</span>
<p>Creates rsa private and public key.</p>
<b>Signature:</b>
```go
func GenerateRsaKeyPair(keySize int) (*rsa.PrivateKey, *rsa.PublicKey)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/sSVmkfENKMz)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
pri, pub := cryptor.GenerateRsaKeyPair(1024)
}
```
### <span id="RsaEncryptOAEP">RsaEncryptOAEP</span>
<p>Encrypts the given data with RSA-OAEP.</p>
<b>Signature:</b>
```go
func RsaEncryptOAEP(data []byte, label []byte, key rsa.PublicKey) ([]byte, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/sSVmkfENKMz)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
pri, pub := cryptor.GenerateRsaKeyPair(1024)
data := []byte("hello world")
label := []byte("123456")
encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub)
if err != nil {
return
}
decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri)
if err != nil {
return
}
fmt.Println(string(decrypted))
// Output:
// hello world
}
```
### <span id="RsaDecryptOAEP">RsaDecryptOAEP</span>
<p>Decrypts the data with RSA-OAEP.</p>
<b>Signature:</b>
```go
func RsaDecryptOAEP(ciphertext []byte, label []byte, key rsa.PrivateKey) ([]byte, error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/sSVmkfENKMz)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
)
func main() {
pri, pub := cryptor.GenerateRsaKeyPair(1024)
data := []byte("hello world")
label := []byte("123456")
encrypted, err := cryptor.RsaEncryptOAEP(data, label, *pub)
if err != nil {
return
}
decrypted, err := cryptor.RsaDecryptOAEP([]byte(encrypted), label, *pri)
if err != nil {
return
}
fmt.Println(string(decrypted))
// Output:
// hello world
}
```

View File

@@ -47,6 +47,7 @@ import (
- [WriteCsvFile](#WriteCsvFile)
- [WriteStringToFile](#WriteStringToFile)
- [WriteBytesToFile](#WriteBytesToFile)
- [ReadFile](#ReadFile)
<div STYLE="page-break-after: always;"></div>
@@ -839,3 +840,41 @@ func main() {
// hello
}
```
### <span id="ReadFile">ReadFile</span>
<p>Read File or URL.</p>
<b>Signature:</b>
```go
func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/uNep3Tr8fqF)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/fileutil"
)
func main() {
reader, fn, err := fileutil.ReadFile("https://httpbin.org/robots.txt")
if err != nil {
return
}
defer fn()
dat, err := io.ReadAll(reader)
if err != nil {
return
}
fmt.Println(string(dat))
// Output:
// User-agent: *
// Disallow: /deny
}
```

View File

@@ -29,8 +29,11 @@ import (
- [RandLower](#RandLower)
- [RandNumeral](#RandNumeral)
- [RandNumeralOrLetter](#RandNumeralOrLetter)
- [RandSymbolChar](#RandSymbolChar)
- [UUIdV4](#UUIdV4)
- [RandUniqueIntSlice](#RandUniqueIntSlice)
- [RandFloat](#RandFloat)
- [RandFloats](#RandFloats)
<div STYLE="page-break-after: always;"></div>
@@ -218,6 +221,32 @@ func main() {
}
```
### <span id="RandSymbolChar">RandSymbolChar</span>
<p>Generate a random symbol char of specified length. Symbol chars: !@#$%^&*()_+-=[]{}|;':\",./<>?.</p>
<b>Signature:</b>
```go
func RandSymbolChar(length int) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/random"
)
func main() {
randStr := random.RandSymbolChar(6)
fmt.Println(randStr) //@#(_")
}
```
### <span id="UUIdV4">UUIdV4</span>
<p>Generate a random UUID of version 4 according to RFC 4122.</p>
@@ -273,3 +302,55 @@ func main() {
fmt.Println(result) //[0 4 7 1 5] (random)
}
```
### <span id="RandFloat">RandFloat</span>
<p>Generate a random float64 number between [min, max) with specific precision.</p>
<b>Signature:</b>
```go
func RandFloat(min, max float64, precision int) float64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/random"
)
func main() {
floatNumber := random.RandFloat(1.0, 5.0, 2)
fmt.Println(floatNumber) //2.14 (random number)
}
```
### <span id="RandFloats">RandFloats</span>
<p>Generate a slice of random float64 numbers of length n that do not repeat.</p>
<b>Signature:</b>
```go
func RandFloats(n int, min, max float64, precision int) []float64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/random"
)
func main() {
floatNumbers := random.RandFloats(5, 1.0, 5.0, 2)
fmt.Println(floatNumber) //[3.42 3.99 1.3 2.38 4.23] (random)
}
```

View File

@@ -77,7 +77,7 @@ import (
- [IsSortedByKey](#IsSortedByKey)
- [Sort](#Sort)
- [SortBy](#SortBy)
- [SortByField<sup>deprecated</sup>](#SortByField)
- [SortByField](#SortByField)
- [Some](#Some)
- [StringSlice<sup>deprecated</sup>](#StringSlice)
- [SymmetricDifference](#SymmetricDifference)
@@ -91,6 +91,7 @@ import (
- [Without](#Without)
- [KeyBy](#KeyBy)
- [Join](#Join)
- [Partition](#Partition)
<div STYLE="page-break-after: always;"></div>
@@ -2000,9 +2001,9 @@ func main() {
}
```
### <span id="SortByField">SortByField (Deprecated: use Sort and SortBy for replacement)</span>
### <span id="SortByField">SortByField</span>
<p>Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc.</p>
<p>Sort struct slice by field. Slice element should be struct, `field` param type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set `sortType` param to desc.</p>
<b>Signature:</b>
@@ -2450,3 +2451,69 @@ func main() {
// 1-2-3-4-5
}
```
### <span id="Partition">Partition</span>
<p>Partition all slice elements with the evaluation of the given predicate functions. </p>
<b>Signature:</b>
```go
func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/lkQ3Ri2NQhV)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
}
```
### <span id="Random">Random</span>
<p>Random get a random item of slice, return idx=-1 when slice is empty. </p>
<b>Signature:</b>
```go
func Random[T any](slice []T) (val T, idx int)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](TODO)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
}
```

View File

@@ -49,6 +49,7 @@ import (
- [StringToBytes](#StringToBytes)
- [BytesToString](#BytesToString)
- [IsBlank](#IsBlank)
- [IsNotBlank](#IsNotBlank)
- [HasPrefixAny](#HasPrefixAny)
- [HasSuffixAny](#HasSuffixAny)
- [IndexOffset](#IndexOffset)
@@ -1076,6 +1077,45 @@ func main() {
}
```
### <span id="IsNotBlank">IsNotBlank</span>
<p>Checks if a string is not whitespace or not empty.</p>
<b>Signature:</b>
```go
func IsNotBlank(str string) bool
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/e_oJW0RAquA)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/strutil"
)
func main() {
result1 := strutil.IsNotBlank("")
result2 := strutil.IsNotBlank(" ")
result3 := strutil.IsNotBlank("\t\v\f\n")
result4 := strutil.IsNotBlank(" 中文")
result5 := strutil.IsNotBlank(" world ")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// false
// false
// false
// true
// true
}
```
### <span id="HasPrefixAny">HasPrefixAny</span>
<p>Checks if a string starts with any of an array of specified strings.</p>

View File

@@ -55,6 +55,15 @@ import (
- [IsZeroValue](#IsZeroValue)
- [IsGBK](#IsGBK)
- [IsPrintable](#IsPrintable)
- [IsBin](#IsBin)
- [IsHex](#IsHex)
- [IsBase64URL](#IsBase64URL)
- [IsJWT](#IsJWT)
- [IsVisa](#IsVisa)
- [IsMasterCard](#IsMasterCard)
- [IsAmericanExpress](#IsAmericanExpress)
- [IsUnionPay](#IsUnionPay)
- [IsChinaUnionPay](#IsChinaUnionPay)
<div STYLE="page-break-after: always;"></div>
@@ -72,7 +81,7 @@ import (
func ContainChinese(s string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/7DpU0uElYeM)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/7DpU0uElYeM)</span></b>
```go
import (
@@ -106,7 +115,7 @@ func main() {
func ContainLetter(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/lqFD04Yyewp)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/lqFD04Yyewp)</span></b>
```go
import (
@@ -140,7 +149,7 @@ func main() {
func ContainLower(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/Srqi1ItvnAA)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/Srqi1ItvnAA)</span></b>
```go
import (
@@ -174,7 +183,7 @@ func main() {
func ContainUpper(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/CmWeBEk27-z)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/CmWeBEk27-z)</span></b>
```go
import (
@@ -208,7 +217,7 @@ func main() {
func IsAlpha(s string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/7Q5sGOz2izQ)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/7Q5sGOz2izQ)</span></b>
```go
import (
@@ -242,7 +251,7 @@ func main() {
func IsAllUpper(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/ZHctgeK1n4Z)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/ZHctgeK1n4Z)</span></b>
```go
import (
@@ -276,7 +285,7 @@ func main() {
func IsAllLower(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/GjqCnOfV6cM)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/GjqCnOfV6cM)</span></b>
```go
import (
@@ -310,7 +319,7 @@ func main() {
func IsASCII(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/hfQNPLX0jNa)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/hfQNPLX0jNa)</span></b>
```go
import (
@@ -350,7 +359,7 @@ func main() {
func IsBase64(base64 string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/sWHEySAt6hl)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/sWHEySAt6hl)</span></b>
```go
import (
@@ -381,7 +390,7 @@ func main() {
func IsChineseMobile(mobileNum string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/GPYUlGTOqe3)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/GPYUlGTOqe3)</span></b>
```go
import (
@@ -412,7 +421,7 @@ func main() {
func IsChineseIdNum(id string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/d8EWhl2UGDF)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/d8EWhl2UGDF)</span></b>
```go
import (
@@ -443,7 +452,7 @@ func main() {
func IsChinesePhone(phone string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/RUD_-7YZJ3I)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/RUD_-7YZJ3I)</span></b>
```go
import (
@@ -474,7 +483,7 @@ func main() {
func IsCreditCard(creditCart string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/sNwwL6B0-v4)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/sNwwL6B0-v4)</span></b>
```go
import (
@@ -505,7 +514,7 @@ func main() {
func IsDns(dns string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/jlYApVLLGTZ)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/jlYApVLLGTZ)</span></b>
```go
import (
@@ -539,7 +548,7 @@ func main() {
func IsEmail(email string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/Os9VaFlT33G)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/Os9VaFlT33G)</span></b>
```go
import (
@@ -570,7 +579,7 @@ func main() {
func IsEmptyString(s string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/dpzgUjFnBCX)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/dpzgUjFnBCX)</span></b>
```go
import (
@@ -604,7 +613,7 @@ func main() {
func IsInt(v any) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/eFoIHbgzl-z)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/eFoIHbgzl-z)</span></b>
```go
import (
@@ -641,7 +650,7 @@ func main() {
func IsFloat(v any) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/vsyG-sxr99_Z)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/vsyG-sxr99_Z)</span></b>
```go
import (
@@ -678,7 +687,7 @@ func main() {
func IsNumber(v any) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/mdJHOAvtsvF)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/mdJHOAvtsvF)</span></b>
```go
import (
@@ -715,7 +724,7 @@ func main() {
func IsIntStr(s string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/jQRtFv-a0Rk)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/jQRtFv-a0Rk)</span></b>
```go
import (
@@ -752,7 +761,7 @@ func main() {
func IsFloatStr(s string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/LOYwS_Oyl7U)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/LOYwS_Oyl7U)</span></b>
```go
import (
@@ -789,7 +798,7 @@ func main() {
func IsNumberStr(s string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/LzaKocSV79u)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/LzaKocSV79u)</span></b>
```go
import (
@@ -826,7 +835,7 @@ func main() {
func IsJSON(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/8Kip1Itjiil)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/8Kip1Itjiil)</span></b>
```go
import (
@@ -863,7 +872,7 @@ func main() {
func IsRegexMatch(s, regex string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/z_XeZo_litG)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/z_XeZo_litG)</span></b>
```go
import (
@@ -894,7 +903,7 @@ func main() {
func IsIp(ipstr string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/FgcplDvmxoD)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/FgcplDvmxoD)</span></b>
```go
import (
@@ -931,7 +940,7 @@ func main() {
func IsIpV4(ipstr string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/zBGT99EjaIu)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/zBGT99EjaIu)</span></b>
```go
import (
@@ -962,7 +971,7 @@ func main() {
func IsIpV6(ipstr string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/AHA0r0AzIdC)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/AHA0r0AzIdC)</span></b>
```go
import (
@@ -993,7 +1002,7 @@ func main() {
func IsStrongPassword(password string, length int) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/QHdVcSQ3uDg)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/QHdVcSQ3uDg)</span></b>
```go
import (
@@ -1024,7 +1033,7 @@ func main() {
func IsUrl(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/pbJGa7F98Ka)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/pbJGa7F98Ka)</span></b>
```go
import (
@@ -1059,7 +1068,7 @@ func main() {
func IsWeakPassword(password string, length int) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/wqakscZH5gH)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/wqakscZH5gH)</span></b>
```go
import (
@@ -1090,7 +1099,7 @@ func main() {
func IsZeroValue(value any) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/UMrwaDCi_t4)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/UMrwaDCi_t4)</span></b>
```go
import (
@@ -1127,7 +1136,7 @@ func main() {
func IsGBK(data []byte) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/E2nt3unlmzP)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/E2nt3unlmzP)</span></b>
```go
import (
@@ -1159,7 +1168,7 @@ func main() {
func IsPrintable(str string) bool
```
<b>Example:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/Pe1FE2gdtTP)</span></b>
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/Pe1FE2gdtTP)</span></b>
```go
import (
@@ -1188,3 +1197,300 @@ func main() {
// false
}
```
### <span id="IsBin">IsBin</span>
<p>Checks if a give string is a valid binary value or not.</p>
<b>Signature:</b>
```go
func IsBin(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/ogPeg2XJH4P)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsBin("0101")
result2 := validator.IsBin("0b1101")
result3 := validator.IsBin("b1101")
result4 := validator.IsBin("1201")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
```
### <span id="IsHex">IsHex</span>
<p>Checks if a give string is a valid hexadecimal value or not.</p>
<b>Signature:</b>
```go
func IsHex(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/M2qpHbEwmm7)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsHex("0xabcde")
result2 := validator.IsHex("0XABCDE")
result3 := validator.IsHex("cdfeg")
result4 := validator.IsHex("0xcdfeg")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
```
### <span id="IsBase64URL">IsBase64URL</span>
<p>Checks if a give string is a valid URL-safe Base64 encoded string.</p>
<b>Signature:</b>
```go
func IsBase64URL(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/vhl4mr8GZ6S)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ")
result2 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ==")
result3 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ=")
result4 := validator.IsBase64URL("SAGsbG8sIHdvcmxkIQ===")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
```
### <span id="IsJWT">IsJWT</span>
<p>Checks if a give string is is a valid JSON Web Token (JWT).</p>
<b>Signature:</b>
```go
func IsJWT(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/R6Op7heJbKI)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910")
result2 := validator.IsJWT("abc")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsVisa">IsVisa</span>
<p>Checks if a give string is a valid visa card nubmer or not.</p>
<b>Signature:</b>
```go
func IsVisa(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/SdS2keOyJsl)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsVisa("4111111111111111")
result2 := validator.IsVisa("123")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsMasterCard">IsMasterCard</span>
<p>Checks if a give string is a valid mastercard nubmer or not.</p>
<b>Signature:</b>
```go
func IsMasterCard(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/CwWBFRrG27b)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsMasterCard("5425233430109903")
result2 := validator.IsMasterCard("4111111111111111")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsAmericanExpress">IsAmericanExpress</span>
<p>Checks if a give string is a valid american express nubmer or not.</p>
<b>Signature:</b>
```go
func IsAmericanExpress(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/HIDFpcOdpkd)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsAmericanExpress("342883359122187")
result2 := validator.IsAmericanExpress("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsUnionPay">IsVisa</span>
<p>Checks if a give string is a valid union pay nubmer or not.</p>
<b>Signature:</b>
```go
func IsUnionPay(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/CUHPEwEITDf)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsUnionPay("6221263430109903")
result2 := validator.IsUnionPay("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```
### <span id="IsChinaUnionPay">IsChinaUnionPay</span>
<p>Checks if a give string is a valid china union pay nubmer or not.</p>
<b>Signature:</b>
```go
func IsChinaUnionPay(v string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/yafpdxLiymu)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsChinaUnionPay("6250941006528599")
result2 := validator.IsChinaUnionPay("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
```

View File

@@ -0,0 +1,37 @@
# Lancet Contribution Guide
Hi! Thank you for choosing Lancet.
Lancet is a powerful, efficient, and reusable util function library of go. It makes Go dev easier by taking the hassle out of working with concurrency, net, math, slice, string, etc.
We are excited that you are interested in contributing to lancet. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.
## Issue Guidelines
- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly.
- Before submitting an issue, please check if similar problems have already been issued.
- Please specify which version of Lancet and Go you are using, and provide OS information. [Go Playground](https://go.dev/play/) is recommended to build a live demo so that your issue can be reproduced clearly.
## Pull Request Guidelines
- Fork this repository to your own account. Do not create branches here.
- Commit info should be formatted as `type(scope): info about commit`. eg. `fix(package): [scrollbar] fix xxx bug`.
1. type: type must be one of [chore, docs, feat, fix, refactor, release, test].
2. scope: scope must be one of [package, file, internal].
3. header: header must not be longer than 72 characters.
- Rebase before creating a PR to keep commit history clear.
- Before submitting a PR, please execute the unit test command: `go test -v ./...` to ensure that all unit test tasks should pass.
- Make sure PRs are created to `v2` branch instead of `master` branch.
- If your PR fixes a bug, please provide a description about the related bug.
- If the PR is for a new feature, make sure to complete the relevant documentation (/lancet/docs/en/api/packages).

View File

@@ -0,0 +1,6 @@
# Contributors
<b>Thank you to all the people who contributed to lancet!</b>
<a href="https://github.com/duke-git/lancet/graphs/contributors">
<img src="https://contrib.rocks/image?repo=duke-git/lancet" />
</a>

View File

@@ -47,4 +47,4 @@ func main() {
## More
Check out the [APIs](https://github.com/duke-git/lancet) for details.
Check out the [API](https://www.golancet.cn/en/api/overview.html) for details.

View File

@@ -41,9 +41,9 @@ features:
<a style="border-color: #4565d8;
color: #fff;
background-color: #4565d8;
border-radius: 30px;
border-radius: 20px;
padding: 0 20px;
line-height: 50px;
line-height: 40px;
font-size: 16px;
display: block;
border: 1px solid transparent;

View File

@@ -0,0 +1,37 @@
# Lancet 贡献指南
Hi! 首先感谢你使用 Lancet。
lancet柳叶刀是一个功能强大、全面、高效、可复用的go语言工具函数库。它消除了处理并发、网络、数学、切片、字符串等的麻烦使 Go 开发变得更容易。
Lancet 的成长离不开大家的支持,如果你愿意为 Lancet 贡献代码或提供建议,请阅读以下内容。
## Issue 规范
- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。
- 在提交 issue 之前,请搜索相关内容是否已被提出。
- 请说明 Lancet 和 Go 的版本号,并提供操作系统信息。推荐使用 [Go Playground](https://go.dev/play/) 生成在线 demo这能够更直观地重现问题。
## Pull Request 规范
- 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。
- commit 信息要以 `type(scope): 描述信息` 的形式填写,例如 `fix(package): [scrollbar] fix xxx bug`
1. type: 必须是 chore, docs, feat, fix, refactor, release, test 其中的一个。
2. scope: 必须是 package, file, internal 其中的一个。
3. header: 描述信息不要超过 72 个字符。
- 提交 PR 前请 rebase确保 commit 记录的整洁。
- 提交 PR 前请执行单元测试命令go test -v ./...,确保所有单元测试任务通过。
- 确保 PR 是提交到 `v2` 分支,而不是 `main` 分支。
- 如果是修复 bug请在 PR 中给出描述信息。
- 如果PR是新功能确保完成相关文档(/lancet/docs/api/packages/)。

View File

@@ -0,0 +1,7 @@
# 贡献者
<b>感谢所有为lancet贡献过代码的人</b>
<a href="https://github.com/duke-git/lancet/graphs/contributors">
<img src="https://contrib.rocks/image?repo=duke-git/lancet" />
</a>

View File

@@ -43,6 +43,6 @@ func main() {
}
```
## More
## 更多
其他特性请参考[API](https://lancet.go.dev/api/overview.html).
更多特性请参考[API](https://www.golancet.cn/api/overview.html).

View File

@@ -50,4 +50,4 @@ features:
text-align: center;
font-weight: 600;
margin: 0 auto;
width: 140px;" href="/sponsor/sponsor.html">Sponsor</a>
width: 140px;" href="/sponsor/sponsor.html">赞助</a>

View File

@@ -18,10 +18,11 @@ import (
"io/fs"
"net/http"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"github.com/duke-git/lancet/v2/validator"
)
// IsExist checks if a file or directory exists.
@@ -491,7 +492,7 @@ func CurrentPath() string {
var absPath string
_, filename, _, ok := runtime.Caller(1)
if ok {
absPath = path.Dir(filename)
absPath = filepath.Dir(filename)
}
return absPath
@@ -624,3 +625,24 @@ func WriteBytesToFile(filepath string, content []byte) error {
_, err = f.Write(content)
return err
}
// ReadFile get file reader by a url or a local file
// Play: https://go.dev/play/p/uNep3Tr8fqF
func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) {
switch {
case validator.IsUrl(path):
resp, err := http.Get(path)
if err != nil {
return nil, func() {}, err
}
return resp.Body, func() { resp.Body.Close() }, nil
case IsExist(path):
reader, err := os.Open(path)
if err != nil {
return nil, func() {}, err
}
return reader, func() { reader.Close() }, nil
default:
return nil, func() {}, errors.New("unknown file type")
}
}

View File

@@ -2,6 +2,7 @@ package fileutil
import (
"fmt"
"io"
"os"
)
@@ -385,3 +386,20 @@ func ExampleWriteBytesToFile() {
// Output:
// hello
}
func ExampleReadFile() {
reader, fn, err := ReadFile("https://httpbin.org/robots.txt")
if err != nil {
return
}
defer fn()
dat, err := io.ReadAll(reader)
if err != nil {
return
}
fmt.Println(string(dat))
// Output:
// User-agent: *
// Disallow: /deny
}

View File

@@ -1,6 +1,7 @@
package fileutil
import (
"io"
"os"
"testing"
@@ -457,3 +458,21 @@ func TestWriteBytesToFile(t *testing.T) {
os.Remove(filepath)
}
func TestReadFile(t *testing.T) {
reader, close, err := ReadFile("https://httpbin.org/robots.txt")
if err != nil {
t.Fail()
}
defer close()
dat, err := io.ReadAll(reader)
if err != nil {
t.Fail()
}
want := `User-agent: *
Disallow: /deny
`
internal.NewAssert(t, "TestReadFile").Equal(want, string(dat))
}

View File

@@ -1,2 +1,3 @@
Lili,22,female
Jim,21,male
1 Lili 22 female
2 Jim 21 male
3

View File

@@ -1,2 +1,3 @@
Lili,22,female
Jim,21,male
1 Lili 22 female
2 Jim 21 male
3

View File

@@ -14,6 +14,7 @@ package netutil
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"errors"
@@ -110,22 +111,23 @@ type HttpClientConfig struct {
Verbose bool
}
// defaultHttpClientConfig defalut client config
// defaultHttpClientConfig defalut client config.
var defaultHttpClientConfig = &HttpClientConfig{
Compressed: false,
HandshakeTimeout: 20 * time.Second,
ResponseTimeout: 40 * time.Second,
}
// HttpClient is used for sending http request
// HttpClient is used for sending http request.
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
Context context.Context
}
// NewHttpClient make a HttpClient instance
// NewHttpClient make a HttpClient instance.
func NewHttpClient() *HttpClient {
client := &HttpClient{
Client: &http.Client{
@@ -141,7 +143,7 @@ func NewHttpClient() *HttpClient {
return client
}
// NewHttpClientWithConfig make a HttpClient instance with pass config
// NewHttpClientWithConfig make a HttpClient instance with pass config.
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
if config == nil {
config = defaultHttpClientConfig
@@ -176,6 +178,11 @@ func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, err
rawUrl := request.RawURL
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
if client.Context != nil {
req, err = http.NewRequestWithContext(client.Context, request.Method, rawUrl, bytes.NewBuffer(request.Body))
}
if err != nil {
return nil, err
}

View File

@@ -10,6 +10,8 @@ import (
"io"
"math/rand"
"time"
"github.com/duke-git/lancet/v2/mathutil"
)
const (
@@ -17,29 +19,43 @@ const (
LowwerLetters = "abcdefghijklmnopqrstuvwxyz"
UpperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
SymbolChars = "!@#$%^&*()_+-=[]{}|;':\",./<>?"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// RandInt generate random int between min and max, maybe min, not be max.
// RandInt generate random int between [min, max).
// Play: https://go.dev/play/p/pXyyAAI5YxD
func RandInt(min, max int) int {
if min == max {
return min
}
if max < min {
min, max = max, min
}
// fix: https://github.com/duke-git/lancet/issues/75
// r := rand.New(rand.NewSource(time.Now().UnixNano()))
// return r.Intn(max-min) + min
return rand.Intn(max-min) + min
}
// RandFloat generate random float64 number between [min, max) with specific precision.
// Play: todo
func RandFloat(min, max float64, precision int) float64 {
if min == max {
return min
}
if max < min {
min, max = max, min
}
n := rand.Float64()*(max-min) + min
return mathutil.RoundToFloat(n, precision)
}
// RandBytes generate random byte slice.
// Play: https://go.dev/play/p/EkiLESeXf8d
func RandBytes(length int) []byte {
@@ -55,19 +71,19 @@ func RandBytes(length int) []byte {
return b
}
// RandString generate random string of specified length.
// RandString generate random alpha string of specified length.
// Play: https://go.dev/play/p/W2xvRUXA7Mi
func RandString(length int) string {
return random(Letters, length)
}
// RandUpper generate a random upper case string.
// RandUpper generate a random upper case string of specified length.
// Play: https://go.dev/play/p/29QfOh0DVuh
func RandUpper(length int) string {
return random(UpperLetters, length)
}
// RandLower generate a random lower case string.
// RandLower generate a random lower case string of specified length.
// Play: https://go.dev/play/p/XJtZ471cmtI
func RandLower(length int) string {
return random(LowwerLetters, length)
@@ -79,12 +95,19 @@ func RandNumeral(length int) string {
return random(Numeral, length)
}
// RandNumeralOrLetter generate a random numeral or letter string.
// RandNumeralOrLetter generate a random numeral or alpha string of specified length.
// Play: https://go.dev/play/p/19CEQvpx2jD
func RandNumeralOrLetter(length int) string {
return random(Numeral+Letters, length)
}
// RandSymbolChar generate a random symbol char of specified length.
// symbol chars: !@#$%^&*()_+-=[]{}|;':\",./<>?.
// Play: todo
func RandSymbolChar(length int) string {
return random(SymbolChars, length)
}
// random generate a random string based on given string range.
func random(s string, length int) string {
b := make([]byte, length)
@@ -139,3 +162,21 @@ func RandUniqueIntSlice(n, min, max int) []int {
return nums
}
// RandFloats generate a slice of random float64 numbers of length n that do not repeat.
// Play: todo
func RandFloats(n int, min, max float64, precision int) []float64 {
nums := make([]float64, n)
used := make(map[float64]struct{}, n)
for i := 0; i < n; {
r := RandFloat(min, max, precision)
if _, use := used[r]; use {
continue
}
used[r] = struct{}{}
nums[i] = r
i++
}
return nums
}

View File

@@ -3,6 +3,7 @@ package random
import (
"fmt"
"regexp"
"strconv"
)
func ExampleRandInt() {
@@ -134,3 +135,53 @@ func ExampleRandUniqueIntSlice() {
// Output:
// ok
}
func ExampleRandSymbolChar() {
pattern := `^[\W|_]+$`
reg := regexp.MustCompile(pattern)
s := RandSymbolChar(6)
result1 := reg.MatchString(s)
result2 := len(s)
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// 6
}
func ExampleRandFloat() {
pattern := `^[\d{1}.\d{2}]+$`
reg := regexp.MustCompile(pattern)
num := RandFloat(1.0, 5.0, 2)
// check num is a random float in [1.0, 5.0)
result1 := num >= 1.0 && num < 5.0
result2 := reg.MatchString(strconv.FormatFloat(num, 'f', -1, 64))
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// true
}
func ExampleRandFloats() {
isInRange := true
numbers := RandFloats(5, 1.0, 5.0, 2)
for _, n := range numbers {
isInRange = (n >= 1.0 && n < 5.0)
}
fmt.Println(isInRange)
fmt.Println(len(numbers))
// Output:
// true
// 5
}

View File

@@ -154,3 +154,45 @@ func hasDuplicate(arr []int) bool {
}
return false
}
func TestRandSymbolChar(t *testing.T) {
t.Parallel()
pattern := `^[\W|_]+$`
reg := regexp.MustCompile(pattern)
symbolChars := RandSymbolChar(10)
assert := internal.NewAssert(t, "TestRandSymbolChar")
assert.Equal(10, len(symbolChars))
assert.Equal(true, reg.MatchString(symbolChars))
}
func TestRandFloat(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestRandFloat")
r1 := RandFloat(1.1, 10.1, 2)
assert.GreaterOrEqual(r1, 1.1)
assert.Less(r1, 10.1)
r2 := RandFloat(1.1, 1.1, 2)
assert.Equal(1.1, r2)
r3 := RandFloat(10.1, 1.1, 2)
assert.GreaterOrEqual(r1, 1.1)
assert.Less(r3, 10.1)
}
func TestRandFloats(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestRandFloats")
numbers := RandFloats(5, 1.0, 5.0, 2)
for _, n := range numbers {
assert.Equal(true, (n >= 1.0 && n < 5.0))
}
assert.Equal(len(numbers), 5)
}

View File

@@ -12,6 +12,7 @@ import (
"strings"
"time"
"github.com/duke-git/lancet/v2/random"
"golang.org/x/exp/constraints"
)
@@ -1008,7 +1009,7 @@ func SortBy[T any](slice []T, less func(a, b T) bool) {
// default sortType is ascending (asc), if descending order, set sortType to desc
// This function is deprecated, use Sort and SortBy for replacement.
// Play: https://go.dev/play/p/fU1prOBP9p1
func SortByField(slice any, field string, sortType ...string) error {
func SortByField[T any](slice []T, field string, sortType ...string) error {
sv := sliceValue(slice)
t := sv.Type().Elem()
@@ -1192,10 +1193,51 @@ func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T {
// Join the slice item with specify separator.
// Play: https://go.dev/play/p/huKzqwNDD7V
func Join[T any](s []T, separator string) string {
str := Map(s, func(_ int, item T) string {
func Join[T any](slice []T, separator string) string {
str := Map(slice, func(_ int, item T) string {
return fmt.Sprint(item)
})
return strings.Join(str, separator)
}
// Partition all slice elements with the evaluation of the given predicate functions.
// Play: https://go.dev/play/p/lkQ3Ri2NQhV
func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T {
l := len(predicates)
result := make([][]T, l+1)
for _, item := range slice {
processed := false
for i, f := range predicates {
if f == nil {
panic("predicate function must not be nill")
}
if f(item) {
result[i] = append(result[i], item)
processed = true
break
}
}
if !processed {
result[l] = append(result[l], item)
}
}
return result
}
// Random get a random item of slice, return idx=-1 when slice is empty
// Play: todo
func Random[T any](slice []T) (val T, idx int) {
if len(slice) == 0 {
return val, -1
}
idx = random.RandInt(0, len(slice))
return slice[idx], idx
}

View File

@@ -1046,3 +1046,31 @@ func ExampleJoin() {
// 1,2,3,4,5
// 1-2-3-4-5
}
func ExamplePartition() {
nums := []int{1, 2, 3, 4, 5}
result1 := Partition(nums)
result2 := Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
}
func ExampleRandom() {
nums := []int{1, 2, 3, 4, 5}
val, idx := Random(nums)
if idx >= 0 && idx < len(nums) && Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
}

View File

@@ -1175,3 +1175,38 @@ func TestJoin(t *testing.T) {
assert.Equal("1,2,3,4,5", result1)
assert.Equal("1-2-3-4-5", result2)
}
func TestPartition(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestPartition")
assert.Equal([][]int{{1, 2, 3, 4, 5}}, Partition([]int{1, 2, 3, 4, 5}))
assert.Equal([][]int{{2, 4}, {1, 3, 5}}, Partition([]int{1, 2, 3, 4, 5}, func(n int) bool { return n%2 == 0 }))
assert.Equal([][]int{{1, 2}, {3, 4}, {5}}, Partition([]int{1, 2, 3, 4, 5}, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 }))
}
func TestRandom(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestRandom")
var arr []int
var val, idx int
_, idx = Random(arr)
assert.Equal(-1, idx)
arr = []int{}
_, idx = Random(arr)
assert.Equal(-1, idx)
arr = []int{1}
val, idx = Random(arr)
assert.Equal(0, idx)
assert.Equal(arr[idx], val)
arr = []int{1, 2, 3}
val, idx = Random(arr)
assert.Greater(len(arr), idx)
assert.Equal(arr[idx], val)
}

View File

@@ -408,6 +408,12 @@ func IsBlank(str string) bool {
return true
}
// IsNotBlank checks if a string is not whitespace, not empty.
// Play: https://go.dev/play/p/e_oJW0RAquA
func IsNotBlank(str string) bool {
return !IsBlank(str)
}
// HasPrefixAny check if a string starts with any of a slice of specified strings.
// Play: https://go.dev/play/p/8UUTl2C5slo
func HasPrefixAny(str string, prefixes []string) bool {

View File

@@ -479,6 +479,26 @@ func ExampleIsBlank() {
// false
}
func ExampleIsNotBlank() {
result1 := IsNotBlank("")
result2 := IsNotBlank(" ")
result3 := IsNotBlank("\t\v\f\n")
result4 := IsNotBlank(" 中文")
result5 := IsNotBlank(" world ")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// false
// false
// false
// true
// true
}
func ExampleHasPrefixAny() {
result1 := HasPrefixAny("foo bar", []string{"fo", "xyz", "hello"})
result2 := HasPrefixAny("foo bar", []string{"oom", "world"})

View File

@@ -32,8 +32,10 @@ func splitIntoStrings(s string, upperCase bool) []string {
for i := 0; i < len(runes)-1; i++ {
if isUpper(runes[i][0]) && isLower(runes[i+1][0]) {
runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
runes[i] = runes[i][:len(runes[i])-1]
length := len(runes[i]) - 1
temp := runes[i][length]
runes[i+1] = append([]rune{temp}, runes[i+1]...)
runes[i] = runes[i][:length]
}
}

View File

@@ -427,6 +427,18 @@ func TestIsBlank(t *testing.T) {
assert.Equal(IsBlank(" 中文"), false)
}
func TestIsNotBlank(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsBlank")
assert.Equal(IsNotBlank(""), false)
assert.Equal(IsNotBlank(" "), false)
assert.Equal(IsNotBlank("\t\v\f\n"), false)
assert.Equal(IsNotBlank(" 中文"), true)
assert.Equal(IsNotBlank(" world "), true)
}
func TestHasPrefixAny(t *testing.T) {
t.Parallel()

View File

@@ -6,29 +6,85 @@ package validator
import (
"encoding/json"
"fmt"
"net"
"net/url"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"unicode"
)
var (
alphaMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]+$`)
letterRegexMatcher *regexp.Regexp = regexp.MustCompile(`[a-zA-Z]`)
numberRegexMatcher *regexp.Regexp = regexp.MustCompile(`\d`)
intStrMatcher *regexp.Regexp = regexp.MustCompile(`^[\+-]?\d+$`)
urlMatcher *regexp.Regexp = regexp.MustCompile(`^((ftp|http|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`)
dnsMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$`)
emailMatcher *regexp.Regexp = regexp.MustCompile(`\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*`)
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}|\d{4}-\d{8}`)
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
alphaMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]+$`)
letterRegexMatcher *regexp.Regexp = regexp.MustCompile(`[a-zA-Z]`)
numberRegexMatcher *regexp.Regexp = regexp.MustCompile(`\d`)
intStrMatcher *regexp.Regexp = regexp.MustCompile(`^[\+-]?\d+$`)
urlMatcher *regexp.Regexp = regexp.MustCompile(`^((ftp|http|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`)
dnsMatcher *regexp.Regexp = regexp.MustCompile(`^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$`)
emailMatcher *regexp.Regexp = regexp.MustCompile(`\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*`)
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^(\d{17})([0-9]|X|x)$`)
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}|\d{4}-\d{8}`)
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
base64URLMatcher *regexp.Regexp = regexp.MustCompile(`^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{2}(==)?|[A-Za-z0-9_-]{3}=?)?$`)
binMatcher *regexp.Regexp = regexp.MustCompile(`^(0b)?[01]+$`)
hexMatcher *regexp.Regexp = regexp.MustCompile(`^(#|0x|0X)?[0-9a-fA-F]+$`)
visaMatcher *regexp.Regexp = regexp.MustCompile(`^4[0-9]{12}(?:[0-9]{3})?$`)
masterCardMatcher *regexp.Regexp = regexp.MustCompile(`^5[1-5][0-9]{14}$`)
americanExpressMatcher *regexp.Regexp = regexp.MustCompile(`^3[47][0-9]{13}$`)
unionPay *regexp.Regexp = regexp.MustCompile("^62[0-5]\\d{13,16}$")
chinaUnionPay *regexp.Regexp = regexp.MustCompile(`^62[0-9]{14,17}$`)
)
var (
// Identity card formula
factor = [17]int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
// ID verification bit
verifyStr = [11]string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
// Starting year of ID card
birthStartYear = 1900
// Province code
provinceKv = map[string]struct{}{
"11": {},
"12": {},
"13": {},
"14": {},
"15": {},
"21": {},
"22": {},
"23": {},
"31": {},
"32": {},
"33": {},
"34": {},
"35": {},
"36": {},
"37": {},
"41": {},
"42": {},
"43": {},
"44": {},
"45": {},
"46": {},
"50": {},
"51": {},
"52": {},
"53": {},
"54": {},
"61": {},
"62": {},
"63": {},
"64": {},
"65": {},
//"71": {},
//"81": {},
//"82": {},
}
)
// IsAlpha checks if the string contains only letters (a-zA-Z).
@@ -112,7 +168,7 @@ func ContainLetter(str string) bool {
return letterRegexMatcher.MatchString(str)
}
// ContainLetter check if the string contain at least one number.
// ContainNumber check if the string contain at least one number.
func ContainNumber(input string) bool {
return numberRegexMatcher.MatchString(input)
}
@@ -220,7 +276,32 @@ func IsChineseMobile(mobileNum string) bool {
// IsChineseIdNum check if the string is chinese id card.
// Play: https://go.dev/play/p/d8EWhl2UGDF
func IsChineseIdNum(id string) bool {
return chineseIdMatcher.MatchString(id)
// All characters should be numbers, and the last digit can be either x or X
if !chineseIdMatcher.MatchString(id) {
return false
}
// Verify province codes and complete all province codes according to GB/T2260
_, ok := provinceKv[id[0:2]]
if !ok {
return false
}
// Verify birthday, must be greater than birthStartYear and less than the current year
birthStr := fmt.Sprintf("%s-%s-%s", id[6:10], id[10:12], id[12:14])
birthday, err := time.Parse("2006-01-02", birthStr)
if err != nil || birthday.After(time.Now()) || birthday.Year() < birthStartYear {
return false
}
// Verification code
sum := 0
for i, c := range id[:17] {
v, _ := strconv.Atoi(string(c))
sum += v * factor[i]
}
return verifyStr[sum%11] == strings.ToUpper(id[17:18])
}
// ContainChinese check if the string contain mandarin chinese.
@@ -376,7 +457,7 @@ func IsGBK(data []byte) bool {
return true
}
// IsNumberStr check if the value is number(integer, float) or not.
// IsNumber check if the value is number(integer, float) or not.
// Play: https://go.dev/play/p/mdJHOAvtsvF
func IsNumber(v any) bool {
return IsInt(v) || IsFloat(v)
@@ -401,3 +482,68 @@ func IsInt(v any) bool {
}
return false
}
// IsBin check if a give string is a valid binary value or not.
// Play: https://go.dev/play/p/ogPeg2XJH4P
func IsBin(v string) bool {
return binMatcher.MatchString(v)
}
// IsHex check if a give string is a valid hexadecimal value or not.
// Play: https://go.dev/play/p/M2qpHbEwmm7
func IsHex(v string) bool {
return hexMatcher.MatchString(v)
}
// IsBase64URL check if a give string is a valid URL-safe Base64 encoded string.
// Play: https://go.dev/play/p/vhl4mr8GZ6S
func IsBase64URL(v string) bool {
return base64URLMatcher.MatchString(v)
}
// IsJWT check if a give string is a valid JSON Web Token (JWT).
// Play: https://go.dev/play/p/R6Op7heJbKI
func IsJWT(v string) bool {
strings := strings.Split(v, ".")
if len(strings) != 3 {
return false
}
for _, s := range strings {
if !IsBase64URL(s) {
return false
}
}
return true
}
// IsVisa check if a give string is a valid visa card nubmer or not.
// Play: https://go.dev/play/p/SdS2keOyJsl
func IsVisa(v string) bool {
return visaMatcher.MatchString(v)
}
// IsMasterCard check if a give string is a valid master card nubmer or not.
// Play: https://go.dev/play/p/CwWBFRrG27b
func IsMasterCard(v string) bool {
return masterCardMatcher.MatchString(v)
}
// IsAmericanExpress check if a give string is a valid american expression card nubmer or not.
// Play: https://go.dev/play/p/HIDFpcOdpkd
func IsAmericanExpress(v string) bool {
return americanExpressMatcher.MatchString(v)
}
// IsUnionPay check if a give string is a valid union pay nubmer or not.
// Play: https://go.dev/play/p/CUHPEwEITDf
func IsUnionPay(v string) bool {
return unionPay.MatchString(v)
}
// IsChinaUnionPay check if a give string is a valid china union pay nubmer or not.
// Play: https://go.dev/play/p/yafpdxLiymu
func IsChinaUnionPay(v string) bool {
return chinaUnionPay.MatchString(v)
}

View File

@@ -154,7 +154,7 @@ func ExampleIsChineseMobile() {
}
func ExampleIsChineseIdNum() {
result1 := IsChineseIdNum("210911192105130715")
result1 := IsChineseIdNum("210911192105130714")
result2 := IsChineseIdNum("123456")
fmt.Println(result1)
@@ -200,7 +200,7 @@ func ExampleIsDns() {
// Output:
// true
// false
// true
// false
}
@@ -521,3 +521,129 @@ func ExampleIsNumber() {
// true
// true
}
func ExampleIsBin() {
result1 := IsBin("0101")
result2 := IsBin("0b1101")
result3 := IsBin("b1101")
result4 := IsBin("1201")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
func ExampleIsHex() {
result1 := IsHex("0xabcde")
result2 := IsHex("0XABCDE")
result3 := IsHex("cdfeg")
result4 := IsHex("0xcdfeg")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
func ExampleIsBase64URL() {
result1 := IsBase64URL("SAGsbG8sIHdvcmxkIQ")
result2 := IsBase64URL("SAGsbG8sIHdvcmxkIQ==")
result3 := IsBase64URL("SAGsbG8sIHdvcmxkIQ=")
result4 := IsBase64URL("SAGsbG8sIHdvcmxkIQ===")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// false
// false
}
func ExampleIsJWT() {
result1 := IsJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910")
result2 := IsJWT("abc")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
func ExampleIsVisa() {
result1 := IsVisa("4111111111111111")
result2 := IsVisa("123")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
func ExampleIsMasterCard() {
result1 := IsMasterCard("5425233430109903")
result2 := IsMasterCard("4111111111111111")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
func ExampleIsAmericanExpress() {
result1 := IsAmericanExpress("342883359122187")
result2 := IsAmericanExpress("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
func ExampleIsUnionPay() {
result1 := IsUnionPay("6221263430109903")
result2 := IsUnionPay("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}
func ExampleIsChinaUnionPay() {
result1 := IsChinaUnionPay("6250941006528599")
result2 := IsChinaUnionPay("3782822463100007")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// true
// false
}

View File

@@ -231,7 +231,12 @@ func TestIsIpV4(t *testing.T) {
assert := internal.NewAssert(t, "TestIsIpV4")
assert.Equal(true, IsIpV4("127.0.0.1"))
assert.Equal(false, IsIpV4("::0:0:0:0:0:0:1"))
assert.Equal(false, IsIpV4("127.0.0.1.1"))
assert.Equal(false, IsIpV4("256.0.0.1"))
assert.Equal(false, IsIpV4("127.0.0.a"))
assert.Equal(false, IsIpV4(""))
}
func TestIsIpV6(t *testing.T) {
@@ -239,8 +244,14 @@ func TestIsIpV6(t *testing.T) {
assert := internal.NewAssert(t, "TestIsIpV6")
assert.Equal(false, IsIpV6("127.0.0.1"))
assert.Equal(true, IsIpV6("::0:0:0:0:0:0:1"))
assert.Equal(true, IsIpV6("::1"))
assert.Equal(true, IsIpV6("::"))
assert.Equal(false, IsIpV6("127.0.0.1"))
assert.Equal(false, IsIpV6("2001:db8::8a2e:37023:7334"))
assert.Equal(false, IsIpV6("2001::25de::cade"))
assert.Equal(false, IsIpV6(""))
}
func TestIsUrl(t *testing.T) {
@@ -260,7 +271,11 @@ func TestIsDns(t *testing.T) {
assert := internal.NewAssert(t, "TestIsDns")
assert.Equal(true, IsDns("abc.com"))
assert.Equal(false, IsDns("a.b.com"))
assert.Equal(true, IsDns("123.cn"))
assert.Equal(true, IsDns("a.b.com"))
assert.Equal(false, IsDns("a.b.c"))
assert.Equal(false, IsDns("a@b.com"))
assert.Equal(false, IsDns("http://abc.com"))
}
@@ -309,10 +324,13 @@ func TestIsChineseIdNum(t *testing.T) {
assert := internal.NewAssert(t, "TestIsChineseIdNum")
assert.Equal(true, IsChineseIdNum("210911192105130715"))
assert.Equal(true, IsChineseIdNum("21091119210513071X"))
assert.Equal(true, IsChineseIdNum("21091119210513071x"))
assert.Equal(true, IsChineseIdNum("210911192105130714"))
assert.Equal(true, IsChineseIdNum("11010519491231002X"))
assert.Equal(true, IsChineseIdNum("11010519491231002x"))
assert.Equal(false, IsChineseIdNum("123456"))
assert.Equal(false, IsChineseIdNum("990911192105130714"))
assert.Equal(false, IsChineseIdNum("990911189905130714"))
assert.Equal(false, IsChineseIdNum("210911222205130714"))
}
func TestIsCreditCard(t *testing.T) {
@@ -536,3 +554,90 @@ func TestIsPrintable(t *testing.T) {
assert.Equal(true, IsPrintable("😄"))
assert.Equal(false, IsPrintable("\u0000"))
}
func TestIsBin(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsBin")
assert.Equal(true, IsBin("0101"))
assert.Equal(true, IsBin("0b1101"))
assert.Equal(false, IsBin("b1101"))
assert.Equal(false, IsBin("1201"))
assert.Equal(false, IsBin(""))
}
func TestIsHex(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsHex")
assert.Equal(true, IsHex("ABCDE"))
assert.Equal(true, IsHex("abcde"))
assert.Equal(true, IsHex("0xabcde"))
assert.Equal(true, IsHex("0Xabcde"))
assert.Equal(true, IsHex("#abcde"))
assert.Equal(false, IsHex("cdfeg"))
assert.Equal(false, IsHex("0xcdfeg"))
assert.Equal(false, IsHex(""))
}
func TestIsBase64URL(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsBase64URL")
assert.Equal(true, IsBase64URL("SAGsbG8sIHdvcmxkIQ"))
assert.Equal(true, IsBase64URL("SAGsbG8sIHdvcmxkIQ=="))
assert.Equal(false, IsBase64URL("SAGsbG8sIHdvcmxkIQ="))
assert.Equal(false, IsBase64URL("SAGsbG8sIHdvcmxkIQ==="))
// assert.Equal(false, IsBase64URL(""))
}
func TestIsJWT(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsJWT")
assert.Equal(true, IsJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910"))
assert.Equal(false, IsJWT("abc"))
}
func TestIsVisa(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsVisa")
assert.Equal(true, IsVisa("4111111111111111"))
assert.Equal(false, IsVisa("123"))
}
func TestIsMasterCard(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsMasterCard")
assert.Equal(true, IsMasterCard("5425233430109903"))
assert.Equal(false, IsMasterCard("4111111111111111"))
}
func TestIsAmericanExpress(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsAmericanExpress")
assert.Equal(true, IsAmericanExpress("342883359122187"))
assert.Equal(false, IsAmericanExpress("3782822463100007"))
}
func TestIsUnionPay(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsUnionPay")
assert.Equal(true, IsUnionPay("6221263430109903"))
assert.Equal(false, IsUnionPay("3782822463100007"))
}
func TestIsChinaUnionPay(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestIsChinaUnionPay")
assert.Equal(true, IsChinaUnionPay("6250941006528599"))
assert.Equal(false, IsChinaUnionPay("3782822463100007"))
}