mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-15 02:02:27 +08:00
Compare commits
17 Commits
ca2a51b37e
...
v2.1.13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d95a7c6101 | ||
|
|
bce3641ec6 | ||
|
|
ceb134b2fd | ||
|
|
4b9b1d32c5 | ||
|
|
395e0883c7 | ||
|
|
a930511054 | ||
|
|
7380721ccc | ||
|
|
936011dc3b | ||
|
|
bc0ee08f38 | ||
|
|
f1afd753d4 | ||
|
|
b05a0a91c3 | ||
|
|
da2eb66657 | ||
|
|
ad20159de2 | ||
|
|
278733d3d1 | ||
|
|
2f184907ff | ||
|
|
50fcc718ee | ||
|
|
cc68feb52d |
397
README.md
397
README.md
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -162,7 +162,7 @@ import "github.com/duke-git/lancet/v2/condition"
|
||||
[[play](https://go.dev/play/p/W1SSUmt6pvr)]
|
||||
- **<big>Or</big>** : returns false if neither a nor b is truthy.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Or)]
|
||||
[[play](https://go.dev/play/p/UlQTxHaeEkq)]
|
||||
[[play](https://go.dev/play/p/UlQTxHaeEkq)]]
|
||||
- **<big>Xor</big>** : returns true if a or b but not both is truthy.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/condition.md#Xor)]
|
||||
[[play](https://go.dev/play/p/gObZrW7ZbG8)]
|
||||
@@ -244,38 +244,101 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt)
|
||||
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt)
|
||||
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt)
|
||||
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcDecrypt)
|
||||
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCtrCrypt)
|
||||
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbEncrypt)
|
||||
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbDecrypt)
|
||||
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbEncrypt)
|
||||
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbDecrypt)
|
||||
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdEncode)
|
||||
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdDecode)
|
||||
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbEncrypt)
|
||||
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbDecrypt)
|
||||
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcEncrypt)
|
||||
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcDecrypt)
|
||||
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCtrCrypt)
|
||||
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbEncrypt)
|
||||
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbDecrypt)
|
||||
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbEncrypt)
|
||||
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbDecrypt)
|
||||
- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacMd5)
|
||||
- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha1)
|
||||
- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha256)
|
||||
- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha512)
|
||||
- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5String)
|
||||
- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5File)
|
||||
- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha1)
|
||||
- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha256)
|
||||
- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha512)
|
||||
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#GenerateRsaKey)
|
||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)
|
||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)
|
||||
- **<big>AesEcbEncrypt</big>** : encrypt byte slice data with key use AES ECB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt)]
|
||||
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
||||
- **<big>AesEcbDecrypt</big>** : decrypt byte slice data with key use AES ECB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt)]
|
||||
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
||||
- **<big>AesCbcEncrypt</big>** : encrypt byte slice data with key use AES CBC algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt)]
|
||||
[[play](https://go.dev/play/p/IOq_g8_lKZD)]
|
||||
- **<big>AesCbcDecrypt</big>** : decrypt byte slice data with key use AES CBC algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcDecrypt)]
|
||||
[[play](https://go.dev/play/p/IOq_g8_lKZD)]
|
||||
- **<big>AesCtrCrypt</big>** : encrypt/ decrypt byte slice data with key use AES CRC algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCtrCrypt)]
|
||||
[[play](https://go.dev/play/p/SpaZO0-5Nsp)]
|
||||
- **<big>AesCfbEncrypt</big>** : encrypt byte slice data with key use AES CFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/tfkF10B13kH)]
|
||||
- **<big>AesCfbDecrypt</big>** : decrypt byte slice data with key use AES CFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/tfkF10B13kH)]
|
||||
- **<big>AesOfbEncrypt</big>** : encrypt byte slice data with key use AES OFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/VtHxtkUj-3F)]
|
||||
- **<big>AesOfbDecrypt</big>** : decrypt byte slice data with key use AES OFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/VtHxtkUj-3F)]
|
||||
- **<big>Base64StdEncode</big>** : encode string with base64 encoding.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdEncode)]
|
||||
[[play](https://go.dev/play/p/VOaUyQUreoK)]
|
||||
- **<big>Base64StdDecode</big>** : decode string with base64 encoding.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdDecode)]
|
||||
[[play](https://go.dev/play/p/RWQylnJVgIe)]
|
||||
- **<big>DesEcbEncrypt</big>** : encrypt byte slice data with key use DES ECB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbEncrypt)]
|
||||
[[play](https://go.dev/play/p/8qivmPeZy4P)]
|
||||
- **<big>DesEcbDecrypt</big>** : decrypt byte slice data with key use DES ECB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbDecrypt)]
|
||||
[[play](https://go.dev/play/p/8qivmPeZy4P)]
|
||||
- **<big>DesCbcEncrypt</big>** : encrypt byte slice data with key use DES CBC algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcEncrypt)]
|
||||
[[play](https://go.dev/play/p/4cC4QvWfe3_1)]
|
||||
- **<big>DesCbcDecrypt</big>** : decrypt byte slice data with key use DES CBC algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcDecrypt)]
|
||||
[[play](https://go.dev/play/p/4cC4QvWfe3_1)]
|
||||
- **<big>DesCtrCrypt</big>** : encrypt/decrypt byte slice data with key use DES CRY algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCtrCrypt)]
|
||||
[[play](https://go.dev/play/p/9-T6OjKpcdw)]
|
||||
- **<big>DesCfbEncrypt</big>** : encrypt byte slice data with key use DES CFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/y-eNxcFBlxL)]
|
||||
- **<big>DesCfbDecrypt</big>** : decrypt byte slice data with key use DES CFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/y-eNxcFBlxL)]
|
||||
- **<big>DesOfbEncrypt</big>** : encrypt byte slice data with key use DES OFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/74KmNadjN1J)]
|
||||
- **<big>DesOfbDecrypt</big>** : decrypt byte slice data with key use DES OFB algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/74KmNadjN1J)]
|
||||
- **<big>HmacMd5</big>** : return the md5 hmac hash of string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacMd5)]
|
||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||
- **<big>HmacSha1</big>** : return the hmac hash of string use sha1.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha1)]
|
||||
[[play](https://go.dev/play/p/1UI4oQ4WXKM)]
|
||||
- **<big>HmacSha256</big>** : return the hmac hash of string use sha256.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha256)]
|
||||
[[play](https://go.dev/play/p/HhpwXxFhhC0)]
|
||||
- **<big>HmacSha512</big>** : return the hmac hash of string use sha512.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha512)]
|
||||
[[play](https://go.dev/play/p/59Od6m4A0Ud)]
|
||||
- **<big>Md5String</big>** : return the md5 value of string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5String)]
|
||||
[[play](https://go.dev/play/p/1bLcVetbTOI)]
|
||||
- **<big>Md5File</big>** : return the md5 value of file.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5File)]
|
||||
- **<big>Sha1</big>** : return the sha1 value (SHA-1 hash algorithm) of string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha1)]
|
||||
[[play](https://go.dev/play/p/_m_uoD1deMT)]
|
||||
- **<big>Sha256</big>** : return the sha256 value (SHA-256 hash algorithm) of string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha256)]
|
||||
[[play](https://go.dev/play/p/tU9tfBMIAr1)]
|
||||
- **<big>Sha512</big>** : return the sha512 value (SHA-512 hash algorithm) of string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha512)]
|
||||
[[play](https://go.dev/play/p/3WsvLYZxsHa)]
|
||||
- **<big>GenerateRsaKey</big>** : create rsa private and public pemo file.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#GenerateRsaKey)]
|
||||
[[play](https://go.dev/play/p/zutRHrDqs0X)]
|
||||
- **<big>RsaEncrypt</big>** : encrypt data with ras algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)]
|
||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||
- **<big>RsaDecrypt</big>** : decrypt data with ras algorithm.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)]
|
||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||
|
||||
### 6. Datetime package supports date and time format and compare.
|
||||
|
||||
@@ -285,36 +348,99 @@ import "github.com/duke-git/lancet/v2/datetime"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)
|
||||
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour)
|
||||
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute)
|
||||
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute)
|
||||
- [BeginOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour)
|
||||
- [BeginOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay)
|
||||
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek)
|
||||
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth)
|
||||
- [BeginOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear)
|
||||
- [EndOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute)
|
||||
- [EndOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour)
|
||||
- [EndOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay)
|
||||
- [EndOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek)
|
||||
- [EndOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth)
|
||||
- [EndOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear)
|
||||
- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDate)
|
||||
- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowTime)
|
||||
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNightTimestamp)
|
||||
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatTimeToStr)
|
||||
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatStrToTime)
|
||||
- [NewUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewUnix)
|
||||
- [NewUnixNow](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewUnixNow)
|
||||
- [NewFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewFormat)
|
||||
- [NewISO8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewISO8601)
|
||||
- [ToUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToUnix)
|
||||
- [ToFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormat)
|
||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)
|
||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)
|
||||
- **<big>AddDay</big>** : add or sub day to the time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)]
|
||||
[[play](https://go.dev/play/p/dIGbs_uTdFa)]
|
||||
- **<big>AddHour</big>** : add or sub day to the time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour)]
|
||||
[[play](https://go.dev/play/p/rcMjd7OCsi5)]
|
||||
- **<big>AddMinute</big>** : add or sub day to the time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute)]
|
||||
[[play](https://go.dev/play/p/nT1heB1KUUK)]
|
||||
- **<big>BeginOfMinute</big>** : return the date time at the begin of minute of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute)]
|
||||
[[play](https://go.dev/play/p/ieOLVJ9CiFT)]
|
||||
- **<big>BeginOfHour</big>** : return the date time at the begin of hour of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour)]
|
||||
[[play](https://go.dev/play/p/GhdGFnDWpYs)]
|
||||
- **<big>BeginOfDay</big>** : return the date time at the begin of day of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay)]
|
||||
[[play](https://go.dev/play/p/94m_UT6cWs9)]
|
||||
- **<big>BeginOfWeek</big>** : return the date time at the begin of week of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek)]
|
||||
[[play](https://go.dev/play/p/ynjoJPz7VNV)]
|
||||
- **<big>BeginOfMonth</big>** : return the date time at the begin of month of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth)]
|
||||
[[play](https://go.dev/play/p/bWXVFsmmzwL)]
|
||||
- **<big>BeginOfYear</big>** : return the date time at the begin of year of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear)]
|
||||
[[play](https://go.dev/play/p/i326DSwLnV8)]
|
||||
- **<big>EndOfMinute</big>** : return the date time at the end of minute of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute)]
|
||||
[[play](https://go.dev/play/p/yrL5wGzPj4z)]
|
||||
- **<big>EndOfHour</big>** : return the date time at the end of hour of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour)]
|
||||
[[play](https://go.dev/play/p/6ce3j_6cVqN)]
|
||||
- **<big>EndOfDay</big>** : return the date time at the end of day of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay)]
|
||||
[[play](https://go.dev/play/p/eMBOvmq5Ih1)]
|
||||
- **<big>EndOfWeek</big>** : return the date time at the end of week of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek)]
|
||||
[[play](https://go.dev/play/p/i08qKXD9flf)]
|
||||
- **<big>EndOfMonth</big>** : return the date time at the end of month of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth)]
|
||||
[[play](https://go.dev/play/p/_GWh10B3Nqi)]
|
||||
- **<big>EndOfYear</big>** : return the date time at the end of year of specific date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear)]
|
||||
[[play](https://go.dev/play/p/G01cKlMCvNm)]
|
||||
- **<big>GetNowDate</big>** : return format yyyy-mm-dd of current date.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDate)]
|
||||
[[play](https://go.dev/play/p/PvfkPpcpBBf)]
|
||||
- **<big>GetNowTime</big>** : return format hh-mm-ss of current time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowTime)]
|
||||
[[play](https://go.dev/play/p/l7BNxCkTmJS)]
|
||||
- **<big>GetNowDateTime</big>** : return format yyyy-mm-dd hh-mm-ss of current datetime.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDateTime)]
|
||||
[[play](https://go.dev/play/p/pI4AqngD0al)]
|
||||
- **<big>GetZeroHourTimestamp</big>** : return timestamp of zero hour (timestamp of 00:00).
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetZeroHourTimestamp)]
|
||||
[[play](https://go.dev/play/p/QmL2oIaGE3q)]
|
||||
- **<big>GetNightTimestamp</big>** : return timestamp of zero hour (timestamp of 23:59).
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNightTimestamp)]
|
||||
[[play](https://go.dev/play/p/UolysR3MYP1)]
|
||||
- **<big>FormatTimeToStr</big>** : convert time to string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatTimeToStr)]
|
||||
[[play](https://go.dev/play/p/_Ia7M8H_OvE)]
|
||||
- **<big>FormatStrToTime</big>** : convert string to time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatStrToTime)]
|
||||
[[play](https://go.dev/play/p/1h9FwdU8ql4)]
|
||||
- **<big>NewUnix</big>** : return unix timestamp of specific time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewUnix)]
|
||||
[[play](https://go.dev/play/p/psoSuh_kLRt)]
|
||||
- **<big>NewUnixNow</big>** : return unix timestamp of current time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewUnixNow)]
|
||||
[[play](https://go.dev/play/p/U4PPx-9D0oz)]
|
||||
- **<big>NewFormat</big>** : return unix timestamp of specific time string, t should be "yyyy-mm-dd hh:mm:ss".
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewFormat)]
|
||||
[[play](https://go.dev/play/p/VkW08ZOaXPZ)]
|
||||
- **<big>NewISO8601</big>** : return unix timestamp of specific iso8601 time string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#NewISO8601)]
|
||||
[[play](https://go.dev/play/p/mkhOHQkdeA2)]
|
||||
- **<big>ToUnix</big>** : return unix timestamp.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToUnix)]
|
||||
[[play](https://go.dev/play/p/_LUiwAdocjy)]
|
||||
- **<big>ToFormat</big>** : return the time string 'yyyy-mm-dd hh:mm:ss' of unix time.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormat)]
|
||||
[[play](https://go.dev/play/p/VkW08ZOaXPZ)]
|
||||
- **<big>ToFormatForTpl</big>** : return the time string which format is specific tpl.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToFormatForTpl)]
|
||||
[[play](https://go.dev/play/p/nyXxXcQJ8L5)]
|
||||
- **<big>ToIso8601</big>** : return iso8601 time string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#ToIso8601)]
|
||||
[[play](https://go.dev/play/p/mkhOHQkdeA2)]
|
||||
|
||||
|
||||
|
||||
|
||||
### 7. Datastructure package constains some common data structure. eg. list, linklist, stack, queue, set, tree, graph.
|
||||
|
||||
@@ -329,16 +455,24 @@ import heap "github.com/duke-git/lancet/v2/datastructure/heap"
|
||||
import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||
```
|
||||
|
||||
#### Function list:
|
||||
#### Structure list:
|
||||
|
||||
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list.md)
|
||||
- [Linklist](https://github.com/duke-git/lancet/blob/main/docs/datastructure/linklist.md)
|
||||
- [Stack](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack.md)
|
||||
- [Queue](https://github.com/duke-git/lancet/blob/main/docs/datastructure/queue.md)
|
||||
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set.md)
|
||||
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree.md)
|
||||
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
||||
- [HashMap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)
|
||||
- **<big>List</big>** : a linear table, implemented with slice.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list.md)]
|
||||
- **<big>Link</big>** : link list structure, contains singly link and doubly link.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/link.md)]
|
||||
- **<big>Stack</big>** : stack structure(fifo), contains array stack and link stack.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack.md)]
|
||||
- **<big>Queue</big>** : queue structure(filo), contains array queue, circular queue, link queue and priority queue.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/queue.md)]
|
||||
- **<big>Set</big>** : a data container, like slice, but element of set is not duplicate.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set.md)]
|
||||
- **<big>Tree</big>** : binary search tree structure.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree.md)]
|
||||
- **<big>Heap</big>** : a binary max heap.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)]
|
||||
- **<big>Hashmap</big>** : hash map structure.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)]
|
||||
|
||||
### 8. Fileutil package implements some basic functions for file operations.
|
||||
|
||||
@@ -439,8 +573,6 @@ import "github.com/duke-git/lancet/v2/function"
|
||||
- **<big>Watcher</big>** : Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)]
|
||||
|
||||
|
||||
|
||||
### 11. Maputil package includes some functions to manipulate map.
|
||||
|
||||
```go
|
||||
@@ -526,26 +658,62 @@ import "github.com/duke-git/lancet/v2/netutil"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString)
|
||||
- [EncodeUrl](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#EncodeUrl)
|
||||
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp)
|
||||
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
||||
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
||||
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo)
|
||||
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetRequestPublicIp)
|
||||
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP)
|
||||
- [IsInternalIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsInternalIP)
|
||||
- [HttpRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpRequest)
|
||||
- [HttpClient](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpClient)
|
||||
- [SendRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#SendRequest)
|
||||
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#DecodeResponse)
|
||||
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#StructToUrlValues)
|
||||
- [HttpGet<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
|
||||
- [HttpDelete<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
|
||||
- [HttpPost<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
|
||||
- [HttpPut<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)
|
||||
- [HttpPatch<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
|
||||
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
|
||||
- **<big>ConvertMapToQueryString</big>** : convert map to sorted url query string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString)]
|
||||
[[play](https://go.dev/play/p/jnNt_qoSnRi)]
|
||||
- **<big>EncodeUrl</big>** : encode url(?a=1&b=[2] -> ?a=1&b=%5B2%5D).
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#EncodeUrl)]
|
||||
[[play](https://go.dev/play/p/bsZ6BRC4uKI)]
|
||||
- **<big>GetInternalIp</big>** : return internal ipv4.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp)]
|
||||
[[play](https://go.dev/play/p/5mbu-gFp7ei)]
|
||||
- **<big>GetIps</big>** : return all ipv4 of current system.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)]
|
||||
[[play](https://go.dev/play/p/NUFfcEmukx1)]
|
||||
- **<big>GetMacAddrs</big>** : return mac address of current system.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)]
|
||||
[[play](https://go.dev/play/p/Rq9UUBS_Xp1)]
|
||||
- **<big>GetPublicIpInfo</big>** : return [public ip information](http://ip-api.com/json/).
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo)]
|
||||
[[play](https://go.dev/play/p/YDxIfozsRHR)]
|
||||
- **<big>GetRequestPublicIp</big>** : return the http request public ip.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetRequestPublicIp)]
|
||||
[[play](https://go.dev/play/p/kxU-YDc_eBo)]
|
||||
- **<big>IsPublicIP</big>** : verify a ip is public or not.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP)]
|
||||
[[play](https://go.dev/play/p/nmktSQpJZnn)]
|
||||
- **<big>IsInternalIP</big>** : verify an ip is intranet or not.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsInternalIP)]
|
||||
[[play](https://go.dev/play/p/sYGhXbgO4Cb)]
|
||||
- **<big>HttpRequest</big>** : a composed http request used for HttpClient send request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpRequest)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>HttpClient</big>** : a http client tool, used for sending http request
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpClient)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>SendRequest</big>** : send http request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#SendRequest)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>DecodeResponse</big>** : decode http response into target object.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#DecodeResponse)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>StructToUrlValues</big>** : convert struct to url valuse.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#StructToUrlValues)]
|
||||
[[play](https://go.dev/play/p/pFqMkM40w9z)]
|
||||
- **<big>HttpGet<sup>deprecated</sup></big>** : send get http request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)]
|
||||
- **<big>HttpDelete<sup>deprecated</sup></big>** : send delete http request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)]
|
||||
- **<big>HttpPost<sup>deprecated</sup></big>** : send post http request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)]
|
||||
- **<big>HttpPut<sup>deprecated</sup></big>** : send put http request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)]
|
||||
- **<big>HttpPatch<sup>deprecated</sup></big>** : send patch http request.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)]
|
||||
- **<big>ParseHttpResponse</big>** : decode http response into target object.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)]
|
||||
|
||||
|
||||
|
||||
### 14. Random package implements some basic functions to generate random int and string.
|
||||
|
||||
@@ -561,7 +729,7 @@ import "github.com/duke-git/lancet/v2/random"
|
||||
- **<big>RandInt</big>** : generate random int number between min and max.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandInt)]
|
||||
[[play](https://go.dev/play/p/pXyyAAI5YxD)]
|
||||
- **<big>RandString</big>** : generate random string of specified length.
|
||||
- **<big>RandString</big>** : generate random string of specific length.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)]
|
||||
[[play](https://go.dev/play/p/W2xvRUXA7Mi)]
|
||||
- **<big>RandUpper</big>** : generate a random upper case string.
|
||||
@@ -570,7 +738,7 @@ import "github.com/duke-git/lancet/v2/random"
|
||||
- **<big>RandLower</big>** : generate a random lower case string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandLower)]
|
||||
[[play](https://go.dev/play/p/XJtZ471cmtI)]
|
||||
- **<big>RandNumeral</big>** : generate a random numeral string of specified length.
|
||||
- **<big>RandNumeral</big>** : generate a random numeral string of specific length.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandNumeral)]
|
||||
[[play](https://go.dev/play/p/g4JWVpHsJcf)]
|
||||
- **<big>RandNumeralOrLetter</big>** : generate a random numeral or letter string.
|
||||
@@ -588,11 +756,21 @@ import "github.com/duke-git/lancet/v2/retry"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context)
|
||||
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry)
|
||||
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc)
|
||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
|
||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
|
||||
- **<big>Context</big>** : set retry context config option.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context)]
|
||||
[[play](https://go.dev/play/p/xnAOOXv9GkS)]
|
||||
- **<big>Retry</big>** : executes the retryFunc repeatedly until it was successful or canceled by the context.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry)]
|
||||
[[play](https://go.dev/play/p/nk2XRmagfVF)]
|
||||
- **<big>RetryFunc</big>** : function that retry executes.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc)]
|
||||
[[play](https://go.dev/play/p/nk2XRmagfVF)]
|
||||
- **<big>RetryDuration</big>** : set duration of retry
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)]
|
||||
[[play](https://go.dev/play/p/nk2XRmagfVF)]
|
||||
- **<big>RetryTimes</big>** : set times of retry.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)]
|
||||
[[play](https://go.dev/play/p/ssfVeU2SwLO)]
|
||||
|
||||
### 16. Slice contains some functions to manipulate slice.
|
||||
|
||||
@@ -770,15 +948,15 @@ import "github.com/duke-git/lancet/v2/strutil"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- **<big>After</big>** : returns the substring after the first occurrence of a specified string in the source string.
|
||||
- **<big>After</big>** : returns the substring after the first occurrence of a specific string in the source string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#After)]
|
||||
[[play](https://go.dev/play/p/RbCOQqCDA7m)]
|
||||
- **<big>AfterLast</big>** : returns the substring after the last occurrence of a specified string in the source string. [[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#AfterLast)]
|
||||
- **<big>AfterLast</big>** : returns the substring after the last occurrence of a specific string in the source string. [[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#AfterLast)]
|
||||
[[play](https://go.dev/play/p/1TegARrb8Yn)]
|
||||
- **<big>Before</big>** : returns the substring before the first occurrence of a specified string in the source string.
|
||||
- **<big>Before</big>** : returns the substring before the first occurrence of a specific string in the source string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Before)]
|
||||
[[play](https://go.dev/play/p/JAWTZDS4F5w)]
|
||||
- **<big>BeforeLast</big>** : returns the substring before the last occurrence of a specified string in the source string.
|
||||
- **<big>BeforeLast</big>** : returns the substring before the last occurrence of a specific string in the source string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#BeforeLast)]
|
||||
[[play](https://go.dev/play/p/pJfXXAoG_Te)]
|
||||
- **<big>CamelCase</big>** : coverts source string to its camelCase string.
|
||||
@@ -820,7 +998,7 @@ import "github.com/duke-git/lancet/v2/strutil"
|
||||
- **<big>SplitEx</big>** : split a given string which can control the result slice contains empty string or not.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SplitEx)]
|
||||
[[play](https://go.dev/play/p/Us-ySSbWh-3)]
|
||||
- **<big>Substring</big>** : returns a substring of the specified length starting at the specified offset position.
|
||||
- **<big>Substring</big>** : returns a substring of the specific length starting at the specific offset position.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Substring)]
|
||||
- **<big>Wrap</big>** : wrap a string with given string.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)]
|
||||
@@ -966,7 +1144,10 @@ import "github.com/duke-git/lancet/v2/xerror"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)
|
||||
- **<big>Unwrap</big>** : check if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#Unwrap)]
|
||||
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
||||
|
||||
|
||||
## How to Contribute
|
||||
|
||||
|
||||
386
README_zh-CN.md
386
README_zh-CN.md
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -170,7 +170,7 @@ import "github.com/duke-git/lancet/v2/condition"
|
||||
[[play](https://go.dev/play/p/g2j08F_zZky)
|
||||
- **<big>Xnor</big>** : 如果 a 和 b 都是真的或 a 和 b 均是假的,则返回 true。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Xnor)]
|
||||
[[play](https://go.dev/play/p/OuDB9g51643)]
|
||||
[[play](https://go.dev/play/p/OuDB9g51643)]]
|
||||
- **<big>Nand</big>** : 如果 a 和 b 都为真,返回 false,否则返回 true
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/condition_zh-CN.md#Nand)]
|
||||
[[play](https://go.dev/play/p/vSRMLxLIbq8)]
|
||||
@@ -243,38 +243,103 @@ import "github.com/duke-git/lancet/v2/cryptor"
|
||||
|
||||
#### 函数列表:
|
||||
|
||||
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt)
|
||||
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt)
|
||||
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt)
|
||||
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcDecrypt)
|
||||
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCtrCrypt)
|
||||
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbEncrypt)
|
||||
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbDecrypt)
|
||||
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbEncrypt)
|
||||
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbDecrypt)
|
||||
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdEncode)
|
||||
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdDecode)
|
||||
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbEncrypt)
|
||||
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbDecrypt)
|
||||
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcEncrypt)
|
||||
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcDecrypt)
|
||||
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCtrCrypt)
|
||||
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbEncrypt)
|
||||
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbDecrypt)
|
||||
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbEncrypt)
|
||||
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbDecrypt)
|
||||
- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacMd5)
|
||||
- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha1)
|
||||
- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha256)
|
||||
- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha512)
|
||||
- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5String)
|
||||
- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5File)
|
||||
- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha1)
|
||||
- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha256)
|
||||
- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha512)
|
||||
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#GenerateRsaKey)
|
||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)
|
||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)
|
||||
- **<big>AesEcbEncrypt</big>** : 使用AES ECB算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt)]
|
||||
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
||||
- **<big>AesEcbDecrypt</big>** : 使用AES ECB算法模解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt)]
|
||||
[[play](https://go.dev/play/p/zI6xsmuQRbn)]
|
||||
- **<big>AesCbcEncrypt</big>** : 使用AES CBC算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt)]
|
||||
[[play](https://go.dev/play/p/IOq_g8_lKZD)]
|
||||
- **<big>AesCbcDecrypt</big>** : 使用AES CBC算法模式解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcDecrypt)]
|
||||
[[play](https://go.dev/play/p/IOq_g8_lKZD)]
|
||||
- **<big>AesCtrCrypt</big>** : 使用AES CTR算法模式加密/解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCtrCrypt)]
|
||||
[[play](https://go.dev/play/p/SpaZO0-5Nsp)]
|
||||
- **<big>AesCfbEncrypt</big>** : 使用AES CFB算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/tfkF10B13kH)]
|
||||
- **<big>AesCfbDecrypt</big>** : 使用AES CFB算法模式解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/tfkF10B13kH)]
|
||||
- **<big>AesOfbEncrypt</big>** : 使用AES OFB算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/VtHxtkUj-3F)]
|
||||
- **<big>AesOfbDecrypt</big>** : 使用AES OFB算法模式解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/VtHxtkUj-3F)]
|
||||
- **<big>Base64StdEncode</big>** : 将字符串base64编码。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdEncode)]
|
||||
[[play](https://go.dev/play/p/VOaUyQUreoK)]
|
||||
- **<big>Base64StdDecode</big>** : 解码base64字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdDecode)]
|
||||
[[play](https://go.dev/play/p/RWQylnJVgIe)]
|
||||
- **<big>DesEcbEncrypt</big>** : 使用DES ECB算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbEncrypt)]
|
||||
[[play](https://go.dev/play/p/8qivmPeZy4P)]
|
||||
- **<big>DesEcbDecrypt</big>** : 使用DES ECB算法模解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbDecrypt)]
|
||||
[[play](https://go.dev/play/p/8qivmPeZy4P)]
|
||||
- **<big>DesCbcEncrypt</big>** : 使用DES CBC算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcEncrypt)]
|
||||
[[play](https://go.dev/play/p/4cC4QvWfe3_1)]
|
||||
- **<big>DesCbcDecrypt</big>** : 使用DES CBC算法模式解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcDecrypt)]
|
||||
[[play](https://go.dev/play/p/4cC4QvWfe3_1)]
|
||||
- **<big>DesCtrCrypt</big>** : 使用DES CTR算法模式加密/解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCtrCrypt)]
|
||||
[[play](https://go.dev/play/p/9-T6OjKpcdw)]
|
||||
- **<big>DesCfbEncrypt</big>** : 使用DES CFB算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/y-eNxcFBlxL)]
|
||||
- **<big>DesCfbDecrypt</big>** : 使用DES CFB算法模式解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/y-eNxcFBlxL)]
|
||||
- **<big>DesOfbEncrypt</big>** : 使用DES OFB算法模式加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbEncrypt)]
|
||||
[[play](https://go.dev/play/p/74KmNadjN1J)]
|
||||
- **<big>DesOfbDecrypt</big>** : 使用DES OFB算法模式解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbDecrypt)]
|
||||
[[play](https://go.dev/play/p/74KmNadjN1J)]
|
||||
- **<big>HmacMd5</big>** : 返回字符串md5 hmac值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacMd5)]
|
||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||
- **<big>HmacSha1</big>** : 返回字符串sha1 hmac值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha1)]
|
||||
[[play](https://go.dev/play/p/1UI4oQ4WXKM)]
|
||||
- **<big>HmacSha256</big>** : 返回字符串sha256 hmac值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha256)]
|
||||
[[play](https://go.dev/play/p/HhpwXxFhhC0)]
|
||||
- **<big>HmacSha512</big>** : 返回字符串sha256 hmac值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha512)]
|
||||
[[play](https://go.dev/play/p/59Od6m4A0Ud)]
|
||||
- **<big>Md5String</big>** : 返回字符串md5值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5String)]
|
||||
[[play](https://go.dev/play/p/1bLcVetbTOI)]
|
||||
- **<big>Md5File</big>** : 返回文件md5值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5File)]
|
||||
- **<big>Sha1</big>** : 返回字符串sha1哈希值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha1)]
|
||||
[[play](https://go.dev/play/p/_m_uoD1deMT)]
|
||||
- **<big>Sha256</big>** :返回字符串sha256哈希值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha256)]
|
||||
[[play](https://go.dev/play/p/tU9tfBMIAr1)]
|
||||
- **<big>Sha512</big>** : 返回字符串sha512哈希值。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha512)]
|
||||
[[play](https://go.dev/play/p/3WsvLYZxsHa)]
|
||||
- **<big>GenerateRsaKey</big>** : 在当前目录下创建rsa私钥文件和公钥文件。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#GenerateRsaKey)]
|
||||
[[play](https://go.dev/play/p/zutRHrDqs0X)]
|
||||
- **<big>RsaEncrypt</big>** : 用公钥文件ras加密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)]
|
||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||
- **<big>RsaDecrypt</big>** : 用私钥文件rsa解密数据。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)]
|
||||
[[play](https://go.dev/play/p/uef0q1fz53I)]
|
||||
|
||||
|
||||
|
||||
### 6. datetime 日期时间处理包,格式化日期,比较日期。
|
||||
|
||||
@@ -284,36 +349,98 @@ import "github.com/duke-git/lancet/v2/datetime"
|
||||
|
||||
#### 函数列表:
|
||||
|
||||
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)
|
||||
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour)
|
||||
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute)
|
||||
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute)
|
||||
- [BeginOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour)
|
||||
- [BeginOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay)
|
||||
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek)
|
||||
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth)
|
||||
- [BeginOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear)
|
||||
- [EndOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute)
|
||||
- [EndOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour)
|
||||
- [EndOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay)
|
||||
- [EndOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek)
|
||||
- [EndOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth)
|
||||
- [EndOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear)
|
||||
- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDate)
|
||||
- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowTime)
|
||||
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDateTime)
|
||||
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetZeroHourTimestamp)
|
||||
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNightTimestamp)
|
||||
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatTimeToStr)
|
||||
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatStrToTime)
|
||||
- [NewUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewUnix)
|
||||
- [NewUnixNow](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewUnixNow)
|
||||
- [NewFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewFormat)
|
||||
- [NewISO8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewISO8601)
|
||||
- [ToUnix](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToUnix)
|
||||
- [ToFormat](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormat)
|
||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)
|
||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)
|
||||
- **<big>AddDay</big>** : 将日期加/减天数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)]
|
||||
[[play](https://go.dev/play/p/dIGbs_uTdFa)]
|
||||
- **<big>AddHour</big>** : 将日期加/减小时数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour)]
|
||||
[[play](https://go.dev/play/p/rcMjd7OCsi5)]
|
||||
- **<big>AddMinute</big>** : 将日期加/减分钟数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute)]
|
||||
[[play](https://go.dev/play/p/nT1heB1KUUK)]
|
||||
- **<big>BeginOfMinute</big>** : 返回指定时间的分钟开始时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#BeginOfMinute)]
|
||||
[[play](https://go.dev/play/p/ieOLVJ9CiFT)]
|
||||
- **<big>BeginOfHour</big>** : 返回指定时间的小时开始时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#BeginOfHour)]
|
||||
[[play](https://go.dev/play/p/GhdGFnDWpYs)]
|
||||
- **<big>BeginOfDay</big>** : 返回指定时间的当天开始时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#BeginOfDay)]
|
||||
[[play](https://go.dev/play/p/94m_UT6cWs9)]
|
||||
- **<big>BeginOfWeek</big>** : 返回指定时间的每周开始时间,默认开始时间星期日。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#BeginOfWeek)]
|
||||
[[play](https://go.dev/play/p/ynjoJPz7VNV)]
|
||||
- **<big>BeginOfMonth</big>** : 返回指定时间的当月开始时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#BeginOfMonth)]
|
||||
[[play](https://go.dev/play/p/bWXVFsmmzwL)]
|
||||
- **<big>BeginOfYear</big>** : 返回指定时间的当年开始时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#BeginOfYear)]
|
||||
[[play](https://go.dev/play/p/i326DSwLnV8)]
|
||||
- **<big>EndOfMinute</big>** : 返回指定时间的分钟结束时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#EndOfMinute)]
|
||||
[[play](https://go.dev/play/p/yrL5wGzPj4z)]
|
||||
- **<big>EndOfHour</big>** : 返回指定时间的小时结束时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#EndOfHour)]
|
||||
[[play](https://go.dev/play/p/6ce3j_6cVqN)]
|
||||
- **<big>EndOfDay</big>** : 返回指定时间的当天结束时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#EndOfDay)]
|
||||
[[play](https://go.dev/play/p/eMBOvmq5Ih1)]
|
||||
- **<big>EndOfWeek</big>** : 返回指定时间的星期结束时间,默认结束时间星期六。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#EndOfWeek)]
|
||||
[[play](https://go.dev/play/p/i08qKXD9flf)]
|
||||
- **<big>EndOfMonth</big>** : 返回指定时间的月份结束时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#EndOfMonth)]
|
||||
[[play](https://go.dev/play/p/_GWh10B3Nqi)]
|
||||
- **<big>EndOfYear</big>** : 返回指定时间的年份结束时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#EndOfYear)]
|
||||
[[play](https://go.dev/play/p/G01cKlMCvNm)]
|
||||
- **<big>GetNowDate</big>** : 获取当天日期,返回格式:yyyy-mm-dd。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDate)]
|
||||
[[play](https://go.dev/play/p/PvfkPpcpBBf)]
|
||||
- **<big>GetNowTime</big>** : 获取当时时间,返回格式:hh:mm:ss。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowTime)]
|
||||
[[play](https://go.dev/play/p/l7BNxCkTmJS)]
|
||||
- **<big>GetNowDateTime</big>** : 获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDateTime)]
|
||||
[[play](https://go.dev/play/p/pI4AqngD0al)]
|
||||
- **<big>GetZeroHourTimestamp</big>** : 获取零时时间戳(timestamp of 00:00)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetZeroHourTimestamp)]
|
||||
[[play](https://go.dev/play/p/QmL2oIaGE3q)]
|
||||
- **<big>GetNightTimestamp</big>** : 获取午夜时间戳(timestamp of 23:59)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNightTimestamp)]
|
||||
[[play](https://go.dev/play/p/UolysR3MYP1)]
|
||||
- **<big>FormatTimeToStr</big>** : 将日期格式化成字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatTimeToStr)]
|
||||
[[play](https://go.dev/play/p/_Ia7M8H_OvE)]
|
||||
- **<big>FormatStrToTime</big>** : 将字符串格式化成时间。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatStrToTime)]
|
||||
[[play](https://go.dev/play/p/1h9FwdU8ql4)]
|
||||
- **<big>NewUnix</big>** : 创建一个unix时间戳。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewUnix)]
|
||||
[[play](https://go.dev/play/p/psoSuh_kLRt)]
|
||||
- **<big>NewUnixNow</big>** : 创建一个当前时间的unix时间戳。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewUnixNow)]
|
||||
[[play](https://go.dev/play/p/U4PPx-9D0oz)]
|
||||
- **<big>NewFormat</big>** : 创建一个yyyy-mm-dd hh:mm:ss格式时间字符串的unix时间戳。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewFormat)]
|
||||
[[play](https://go.dev/play/p/VkW08ZOaXPZ)]
|
||||
- **<big>NewISO8601</big>** : 创建一个iso8601格式时间字符串的unix时间戳。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#NewISO8601)]
|
||||
[[play](https://go.dev/play/p/mkhOHQkdeA2)]
|
||||
- **<big>ToUnix</big>** : 返回unix时间戳。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToUnix)]
|
||||
[[play](https://go.dev/play/p/_LUiwAdocjy)]
|
||||
- **<big>ToFormat</big>** : 返回格式'yyyy-mm-dd hh:mm:ss'的日期字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormat)]
|
||||
[[play](https://go.dev/play/p/VkW08ZOaXPZ)]
|
||||
- **<big>ToFormatForTpl</big>** : 返回tpl格式指定的日期字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToFormatForTpl)]
|
||||
[[play](https://go.dev/play/p/nyXxXcQJ8L5)]
|
||||
- **<big>ToIso8601</big>** : 返回iso8601日期字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#ToIso8601)]
|
||||
[[play](https://go.dev/play/p/mkhOHQkdeA2)]
|
||||
|
||||
|
||||
|
||||
### 7. datastructure 包含一些普通的数据结构实现。例如:list, linklist, stack, queue, set, tree, graph.
|
||||
|
||||
@@ -330,14 +457,25 @@ import hashmap "github.com/duke-git/lancet/v2/datastructure/hashmap"
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [List](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list_zh-CN.md)
|
||||
- [Linklist](https://github.com/duke-git/lancet/blob/main/docs/datastructure/linklist_zh-CN.md)
|
||||
- [Stack](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack_zh-CN.md)
|
||||
- [Queue](https://github.com/duke-git/lancet/blob/main/docs/datastructure/queue_zh-CN.md)
|
||||
- [Set](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set_zh-CN.md)
|
||||
- [Tree](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree_zh-CN.md)
|
||||
- [Heap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap.md)
|
||||
- [HashMap](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap.md)
|
||||
- **<big>List</big>** : 线性表结构, 用切片实现。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/list_zh-CN.md)]
|
||||
- **<big>Link</big>** : 链表解构, 包括单链表和双向链表。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/link_zh-CN.md)]
|
||||
- **<big>Stack</big>** : 栈结构(fifo), 包括数组栈和链表栈。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/stack_zh-CN.md)]
|
||||
- **<big>Queue</big>** : 队列结构(filo), 包括数组队列,链表队列,循环队列,优先级队列。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/queue_zh-CN.md)]
|
||||
- **<big>Set</big>** : 集合(set)结构。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/set_zh-CN.md)]
|
||||
- **<big>Tree</big>** : 二叉搜索树。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/tree_zh-CN.md)]
|
||||
- **<big>Heap</big>** : 二叉max堆。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/heap_zh-CN.md)]
|
||||
- **<big>Hashmap</big>** : 哈希映射。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/datastructure/hashmap_zh-CN.md)]
|
||||
|
||||
|
||||
|
||||
|
||||
### 8. fileutil 包含文件基本操作。
|
||||
|
||||
@@ -524,26 +662,63 @@ import "github.com/duke-git/lancet/v2/netutil"
|
||||
|
||||
#### 函数列表:
|
||||
|
||||
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString)
|
||||
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp)
|
||||
- [EncodeUrl](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#EncodeUrl)
|
||||
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps)
|
||||
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs)
|
||||
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo)
|
||||
- [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetRequestPublicIp)
|
||||
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP)
|
||||
- [IsInternalIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsInternalIP)
|
||||
- [HttpRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpRequest)
|
||||
- [HttpClient](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpClient)
|
||||
- [SendRequest](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#SendRequest)
|
||||
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#DecodeResponse)
|
||||
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#StructToUrlValues)
|
||||
- [HttpGet<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
|
||||
- [HttpDelete<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
|
||||
- [HttpPost<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
|
||||
- [HttpPut<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)
|
||||
- [HttpPatch<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
|
||||
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
|
||||
- **<big>ConvertMapToQueryString</big>** : 将map转换成http查询字符串。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString)]
|
||||
[[play](https://go.dev/play/p/jnNt_qoSnRi)]
|
||||
- **<big>EncodeUrl</big>** : 编码url query string的值(?a=1&b=[2] -> ?a=1&b=%5B2%5D)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#EncodeUrl)]
|
||||
[[play](https://go.dev/play/p/bsZ6BRC4uKI)]
|
||||
- **<big>GetInternalIp</big>** : 获取内部ipv4。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp)]
|
||||
[[play](https://go.dev/play/p/5mbu-gFp7ei)]
|
||||
- **<big>GetIps</big>** : 获取系统ipv4地址列表。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetIps)]
|
||||
[[play](https://go.dev/play/p/NUFfcEmukx1)]
|
||||
- **<big>GetMacAddrs</big>** : 获取系统mac地址列。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetMacAddrs)]
|
||||
[[play](https://go.dev/play/p/Rq9UUBS_Xp1)]
|
||||
- **<big>GetPublicIpInfo</big>** : 获取[公网ip信息](http://ip-api.com/json/).
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo)]
|
||||
[[play](https://go.dev/play/p/YDxIfozsRHR)]
|
||||
- **<big>GetRequestPublicIp</big>** : 获取http请求ip。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetRequestPublicIp)]
|
||||
[[play](https://go.dev/play/p/kxU-YDc_eBo)]
|
||||
- **<big>IsPublicIP</big>** : 判断ip是否是公共ip。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP)]
|
||||
[[play](https://go.dev/play/p/nmktSQpJZnn)]
|
||||
- **<big>IsInternalIP</big>** : 判断ip是否是局域网ip。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsInternalIP)]
|
||||
[[play](https://go.dev/play/p/sYGhXbgO4Cb)]
|
||||
- **<big>HttpRequest</big>** : 用于抽象HTTP请求实体的结构。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpRequest)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>HttpClient</big>** : 用于发送HTTP请求。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpClient)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>SendRequest</big>** : 发送http请求。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#SendRequest)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>DecodeResponse</big>** : 解析http响应体到目标结构体。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#DecodeResponse)]
|
||||
[[play](https://go.dev/play/p/jUSgynekH7G)]
|
||||
- **<big>StructToUrlValues</big>** : 将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#StructToUrlValues)]
|
||||
[[play](https://go.dev/play/p/pFqMkM40w9z)]
|
||||
- **<big>HttpGet<sup>deprecated</sup></big>** : 发送http get请求(已弃用:SendRequest代替)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)]
|
||||
- **<big>HttpDelete<sup>deprecated</sup></big>** : 发送http delete请求(已弃用:SendRequest代替)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)]
|
||||
- **<big>HttpPost<sup>deprecated</sup></big>** : 发送http post请求(已弃用:SendRequest代替)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)]
|
||||
- **<big>HttpPut<sup>deprecated</sup></big>** : 发送http put请求(已弃用:SendRequest代替)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)]
|
||||
- **<big>HttpPatch<sup>deprecated</sup></big>** : 发送http patch请求(已弃用:SendRequest代替)。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)]
|
||||
- **<big>ParseHttpResponse</big>** : 解析http响应体到目标结构体。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)]
|
||||
|
||||
|
||||
|
||||
|
||||
### 14. random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||
|
||||
@@ -588,11 +763,23 @@ import "github.com/duke-git/lancet/v2/retry"
|
||||
|
||||
#### 函数列表:
|
||||
|
||||
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context)
|
||||
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry)
|
||||
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc)
|
||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration)
|
||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
|
||||
- **<big>Context</big>** : 设置重试context参数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context)]
|
||||
[[play](https://go.dev/play/p/xnAOOXv9GkS)]
|
||||
- **<big>Retry</big>** : 重试执行函数retryFunc,直到函数运行成功,或被context取消。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry)]
|
||||
[[play](https://go.dev/play/p/nk2XRmagfVF)]
|
||||
- **<big>RetryFunc</big>** : 重试执行的函数。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc)]
|
||||
[[play](https://go.dev/play/p/nk2XRmagfVF)]
|
||||
- **<big>RetryDuration</big>** : 设置重试间隔时间,默认3秒。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration)]
|
||||
[[play](https://go.dev/play/p/nk2XRmagfVF)]
|
||||
- **<big>RetryTimes</big>** : 设置重试次数,默认5。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)]
|
||||
[[play](https://go.dev/play/p/ssfVeU2SwLO)]
|
||||
|
||||
|
||||
|
||||
### 16. slice 包含操作切片的方法集合。
|
||||
|
||||
@@ -968,6 +1155,11 @@ import "github.com/duke-git/lancet/v2/xerror"
|
||||
|
||||
#### 函数列表:
|
||||
|
||||
|
||||
- **<big>Unwrap</big>** : 检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则Unwrap使用err发生panic。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)]
|
||||
[[play](https://go.dev/play/p/w84d7Mb3Afk)]
|
||||
|
||||
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/xerror_zh-CN.md#Unwrap)
|
||||
|
||||
## 如何贡献代码
|
||||
|
||||
@@ -10,6 +10,7 @@ import "github.com/duke-git/lancet/v2/lancetconstraints"
|
||||
|
||||
// LinearSearch return the index of target in slice base on equal function.
|
||||
// If not found return -1
|
||||
// Play: Todo
|
||||
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int {
|
||||
for i, v := range slice {
|
||||
if equal(v, target) {
|
||||
|
||||
@@ -20,7 +20,7 @@ func NewChannel[T any]() *Channel[T] {
|
||||
}
|
||||
|
||||
// Generate creates channel, then put values into the channel.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T {
|
||||
dataStream := make(chan T)
|
||||
|
||||
@@ -40,7 +40,7 @@ func (c *Channel[T]) Generate(ctx context.Context, values ...T) <-chan T {
|
||||
}
|
||||
|
||||
// Repeat create channel, put values into the channel repeatly until cancel the context.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T {
|
||||
dataStream := make(chan T)
|
||||
|
||||
@@ -61,7 +61,7 @@ func (c *Channel[T]) Repeat(ctx context.Context, values ...T) <-chan T {
|
||||
|
||||
// RepeatFn create a channel, excutes fn repeatly, and put the result into the channel
|
||||
// until close context.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T {
|
||||
dataStream := make(chan T)
|
||||
|
||||
@@ -79,7 +79,7 @@ func (c *Channel[T]) RepeatFn(ctx context.Context, fn func() T) <-chan T {
|
||||
}
|
||||
|
||||
// Take create a channel whose values are taken from another channel with limit number.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int) <-chan T {
|
||||
takeStream := make(chan T)
|
||||
|
||||
@@ -99,7 +99,7 @@ func (c *Channel[T]) Take(ctx context.Context, valueStream <-chan T, number int)
|
||||
}
|
||||
|
||||
// FanIn merge multiple channels into one channel.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T {
|
||||
out := make(chan T)
|
||||
|
||||
@@ -127,7 +127,7 @@ func (c *Channel[T]) FanIn(ctx context.Context, channels ...<-chan T) <-chan T {
|
||||
}
|
||||
|
||||
// Tee split one chanel into two channels, until cancel the context.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T) {
|
||||
out1 := make(chan T)
|
||||
out2 := make(chan T)
|
||||
@@ -154,7 +154,7 @@ func (c *Channel[T]) Tee(ctx context.Context, in <-chan T) (<-chan T, <-chan T)
|
||||
}
|
||||
|
||||
// Bridge link multiply channels into one channel.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-chan T {
|
||||
valStream := make(chan T)
|
||||
|
||||
@@ -186,7 +186,7 @@ func (c *Channel[T]) Bridge(ctx context.Context, chanStream <-chan <-chan T) <-c
|
||||
}
|
||||
|
||||
// Or read one or more channels into one channel, will close when any readin channel is closed.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) Or(channels ...<-chan T) <-chan T {
|
||||
switch len(channels) {
|
||||
case 0:
|
||||
@@ -220,7 +220,7 @@ func (c *Channel[T]) Or(channels ...<-chan T) <-chan T {
|
||||
}
|
||||
|
||||
// OrDone read a channel into another channel, will close until cancel context.
|
||||
// Play:
|
||||
// Play: Todo
|
||||
func (c *Channel[T]) OrDone(ctx context.Context, channel <-chan T) <-chan T {
|
||||
valStream := make(chan T)
|
||||
|
||||
|
||||
186
cryptor/aes.go
186
cryptor/aes.go
@@ -1,186 +0,0 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package cryptor implements some util functions to encrypt and decrypt.
|
||||
// Note:
|
||||
// 1. for aes crypt function, the `key` param length should be 16, 24 or 32. if not, will panic.
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
// AesEcbEncrypt encrypt data with key use AES ECB algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesEcbEncrypt(data, key []byte) []byte {
|
||||
length := (len(data) + aes.BlockSize) / aes.BlockSize
|
||||
plain := make([]byte, length*aes.BlockSize)
|
||||
|
||||
copy(plain, data)
|
||||
|
||||
pad := byte(len(plain) - len(data))
|
||||
for i := len(data); i < len(plain); i++ {
|
||||
plain[i] = pad
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(plain))
|
||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
||||
}
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesEcbDecrypt decrypt data with key use AES ECB algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||
}
|
||||
|
||||
trim := 0
|
||||
if len(decrypted) > 0 {
|
||||
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
|
||||
}
|
||||
|
||||
return decrypted[:trim]
|
||||
}
|
||||
|
||||
// AesCbcEncrypt encrypt data with key use AES CBC algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesCbcEncrypt(data, key []byte) []byte {
|
||||
block, _ := aes.NewCipher(key)
|
||||
data = pkcs7Padding(data, block.BlockSize())
|
||||
|
||||
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted[aes.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesCbcDecrypt decrypt data with key use AES CBC algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
||||
block, _ := aes.NewCipher(key)
|
||||
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
encrypted = encrypted[aes.BlockSize:]
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted, encrypted)
|
||||
|
||||
decrypted := pkcs7UnPadding(encrypted)
|
||||
return decrypted
|
||||
}
|
||||
|
||||
// AesCtrCrypt encrypt data with key use AES CTR algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesCtrCrypt(data, key []byte) []byte {
|
||||
block, _ := aes.NewCipher(key)
|
||||
|
||||
iv := bytes.Repeat([]byte("1"), block.BlockSize())
|
||||
stream := cipher.NewCTR(block, iv)
|
||||
|
||||
dst := make([]byte, len(data))
|
||||
stream.XORKeyStream(dst, data)
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// AesCfbEncrypt encrypt data with key use AES CFB algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesCfbEncrypt(data, key []byte) []byte {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted[aes.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesCfbDecrypt decrypt data with key use AES CFB algorithm
|
||||
// len(encrypted) should be great than 16, len(key) should be 16, 24 or 32
|
||||
func AesCfbDecrypt(encrypted, key []byte) []byte {
|
||||
if len(encrypted) < aes.BlockSize {
|
||||
panic("encrypted data is too short")
|
||||
}
|
||||
|
||||
block, _ := aes.NewCipher(key)
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
encrypted = encrypted[aes.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
|
||||
stream.XORKeyStream(encrypted, encrypted)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesOfbEncrypt encrypt data with key use AES OFB algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesOfbEncrypt(data, key []byte) []byte {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
data = pkcs7Padding(data, aes.BlockSize)
|
||||
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
stream.XORKeyStream(encrypted[aes.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesOfbDecrypt decrypt data with key use AES OFB algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func AesOfbDecrypt(data, key []byte) []byte {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
iv := data[:aes.BlockSize]
|
||||
data = data[aes.BlockSize:]
|
||||
if len(data)%aes.BlockSize != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(data))
|
||||
mode := cipher.NewOFB(block, iv)
|
||||
mode.XORKeyStream(decrypted, data)
|
||||
|
||||
decrypted = pkcs7UnPadding(decrypted)
|
||||
|
||||
return decrypted
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestAesEcbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesEcbEncrypt := AesEcbEncrypt([]byte(data), []byte(key))
|
||||
aesEcbDecrypt := AesEcbDecrypt(aesEcbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesEcbEncrypt")
|
||||
assert.Equal(data, string(aesEcbDecrypt))
|
||||
}
|
||||
|
||||
func TestAesCbcEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesCbcEncrypt := AesCbcEncrypt([]byte(data), []byte(key))
|
||||
aesCbcDecrypt := AesCbcDecrypt(aesCbcEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesCbcEncrypt")
|
||||
assert.Equal(data, string(aesCbcDecrypt))
|
||||
}
|
||||
|
||||
func TestAesCtrCrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesCtrCrypt := AesCtrCrypt([]byte(data), []byte(key))
|
||||
aesCtrDeCrypt := AesCtrCrypt(aesCtrCrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesCtrCrypt")
|
||||
assert.Equal(data, string(aesCtrDeCrypt))
|
||||
}
|
||||
|
||||
func TestAesCfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesCfbEncrypt := AesCfbEncrypt([]byte(data), []byte(key))
|
||||
aesCfbDecrypt := AesCfbDecrypt(aesCfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesCfbEncrypt")
|
||||
assert.Equal(data, string(aesCfbDecrypt))
|
||||
}
|
||||
|
||||
func TestAesOfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesOfbEncrypt := AesOfbEncrypt([]byte(data), []byte(key))
|
||||
aesOfbDecrypt := AesOfbDecrypt(aesOfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesOfbEncrypt")
|
||||
assert.Equal(data, string(aesOfbDecrypt))
|
||||
}
|
||||
@@ -19,25 +19,28 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// Base64StdEncode encode string with base64 encoding
|
||||
// Base64StdEncode encode string with base64 encoding.
|
||||
// Play: https://go.dev/play/p/VOaUyQUreoK
|
||||
func Base64StdEncode(s string) string {
|
||||
return base64.StdEncoding.EncodeToString([]byte(s))
|
||||
}
|
||||
|
||||
// Base64StdDecode decode a base64 encoded string
|
||||
// Base64StdDecode decode a base64 encoded string.
|
||||
// Play: https://go.dev/play/p/RWQylnJVgIe
|
||||
func Base64StdDecode(s string) string {
|
||||
b, _ := base64.StdEncoding.DecodeString(s)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Md5String return the md5 value of string
|
||||
// Md5String return the md5 value of string.
|
||||
// Play: https://go.dev/play/p/1bLcVetbTOI
|
||||
func Md5String(s string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(s))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Md5File return the md5 value of file
|
||||
// Md5File return the md5 value of file.
|
||||
func Md5File(filename string) (string, error) {
|
||||
if fileInfo, err := os.Stat(filename); err != nil {
|
||||
return "", err
|
||||
@@ -69,49 +72,56 @@ func Md5File(filename string) (string, error) {
|
||||
return checksum, nil
|
||||
}
|
||||
|
||||
// HmacMd5 return the hmac hash of string use md5
|
||||
// HmacMd5 return the hmac hash of string use md5.
|
||||
// Play: https://go.dev/play/p/uef0q1fz53I
|
||||
func HmacMd5(data, key string) string {
|
||||
h := hmac.New(md5.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha1 return the hmac hash of string use sha1
|
||||
// HmacSha1 return the hmac hash of string use sha1.
|
||||
// Play: https://go.dev/play/p/1UI4oQ4WXKM
|
||||
func HmacSha1(data, key string) string {
|
||||
h := hmac.New(sha1.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha256 return the hmac hash of string use sha256
|
||||
// HmacSha256 return the hmac hash of string use sha256.
|
||||
// Play: https://go.dev/play/p/HhpwXxFhhC0
|
||||
func HmacSha256(data, key string) string {
|
||||
h := hmac.New(sha256.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// HmacSha512 return the hmac hash of string use sha512
|
||||
// HmacSha512 return the hmac hash of string use sha512.
|
||||
// Play: https://go.dev/play/p/59Od6m4A0Ud
|
||||
func HmacSha512(data, key string) string {
|
||||
h := hmac.New(sha512.New, []byte(key))
|
||||
h.Write([]byte(data))
|
||||
return hex.EncodeToString(h.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha1 return the sha1 value (SHA-1 hash algorithm) of string
|
||||
// Sha1 return the sha1 value (SHA-1 hash algorithm) of string.
|
||||
// Play: https://go.dev/play/p/_m_uoD1deMT
|
||||
func Sha1(data string) string {
|
||||
sha1 := sha1.New()
|
||||
sha1.Write([]byte(data))
|
||||
return hex.EncodeToString(sha1.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha256 return the sha256 value (SHA256 hash algorithm) of string
|
||||
// Sha256 return the sha256 value (SHA256 hash algorithm) of string.
|
||||
// Play: https://go.dev/play/p/tU9tfBMIAr1
|
||||
func Sha256(data string) string {
|
||||
sha256 := sha256.New()
|
||||
sha256.Write([]byte(data))
|
||||
return hex.EncodeToString(sha256.Sum([]byte("")))
|
||||
}
|
||||
|
||||
// Sha512 return the sha512 value (SHA512 hash algorithm) of string
|
||||
// Sha512 return the sha512 value (SHA512 hash algorithm) of string.
|
||||
// Play: https://go.dev/play/p/3WsvLYZxsHa
|
||||
func Sha512(data string) string {
|
||||
sha512 := sha512.New()
|
||||
sha512.Write([]byte(data))
|
||||
|
||||
410
cryptor/crypto_example_test.go
Normal file
410
cryptor/crypto_example_test.go
Normal file
@@ -0,0 +1,410 @@
|
||||
package cryptor
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ExampleAesEcbEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesEcbDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesCbcEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesCbcEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesCbcDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesCbcEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesCtrCrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesCtrCrypt([]byte(data), []byte(key))
|
||||
decrypted := AesCtrCrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesCfbEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesCfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesCfbDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesCfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesOfbEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesOfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleAesOfbDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
encrypted := AesOfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := AesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesEcbEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesEcbDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesEcbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesEcbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesCbcEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesCbcEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesCbcDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesCbcEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesCbcDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesCtrCrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesCtrCrypt([]byte(data), []byte(key))
|
||||
decrypted := DesCtrCrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesCfbEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesCfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesCfbDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesCfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesCfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesOfbEncrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesOfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleDesOfbDecrypt() {
|
||||
data := "hello"
|
||||
key := "abcdefgh"
|
||||
|
||||
encrypted := DesOfbEncrypt([]byte(data), []byte(key))
|
||||
|
||||
decrypted := DesOfbDecrypt(encrypted, []byte(key))
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleGenerateRsaKey() {
|
||||
// Create ras private and public pem file
|
||||
err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("foo")
|
||||
|
||||
// Output:
|
||||
// foo
|
||||
}
|
||||
|
||||
func ExampleRsaEncrypt() {
|
||||
// Create ras private and public pem file
|
||||
err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data := []byte("hello")
|
||||
encrypted := RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleRsaDecrypt() {
|
||||
// Create ras private and public pem file
|
||||
err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data := []byte("hello")
|
||||
encrypted := RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
fmt.Println(string(decrypted))
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleBase64StdEncode() {
|
||||
base64Str := Base64StdEncode("hello")
|
||||
|
||||
fmt.Println(base64Str)
|
||||
|
||||
// Output:
|
||||
// aGVsbG8=
|
||||
}
|
||||
|
||||
func ExampleBase64StdDecode() {
|
||||
str := Base64StdDecode("aGVsbG8=")
|
||||
|
||||
fmt.Println(str)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
|
||||
func ExampleHmacMd5() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacMd5(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// e834306eab892d872525d4918a7a639a
|
||||
}
|
||||
|
||||
func ExampleHmacSha1() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha1(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 5c6a9db0cccb92e36ed0323fd09b7f936de9ace0
|
||||
}
|
||||
|
||||
func ExampleHmacSha256() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha256(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75
|
||||
}
|
||||
|
||||
func ExampleHmacSha512() {
|
||||
str := "hello"
|
||||
key := "12345"
|
||||
|
||||
hms := HmacSha512(str, key)
|
||||
|
||||
fmt.Println(hms)
|
||||
|
||||
// Output:
|
||||
// dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc
|
||||
}
|
||||
|
||||
func ExampleMd5String() {
|
||||
str := "hello"
|
||||
|
||||
md5Str := Md5String(str)
|
||||
|
||||
fmt.Println(md5Str)
|
||||
|
||||
// Output:
|
||||
// 5d41402abc4b2a76b9719d911017c592
|
||||
}
|
||||
|
||||
func ExampleSha1() {
|
||||
str := "hello"
|
||||
|
||||
result := Sha1(str)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
|
||||
}
|
||||
|
||||
func ExampleSha256() {
|
||||
str := "hello"
|
||||
|
||||
result := Sha256(str)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
|
||||
}
|
||||
|
||||
func ExampleSha512() {
|
||||
str := "hello"
|
||||
|
||||
result := Sha512(str)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
|
||||
}
|
||||
180
cryptor/des.go
180
cryptor/des.go
@@ -1,180 +0,0 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package cryptor implements some util functions to encrypt and decrypt.
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
// DesEcbEncrypt encrypt data with key use DES ECB algorithm
|
||||
// len(key) should be 8
|
||||
func DesEcbEncrypt(data, key []byte) []byte {
|
||||
length := (len(data) + des.BlockSize) / des.BlockSize
|
||||
plain := make([]byte, length*des.BlockSize)
|
||||
copy(plain, data)
|
||||
|
||||
pad := byte(len(plain) - len(data))
|
||||
for i := len(data); i < len(plain); i++ {
|
||||
plain[i] = pad
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(plain))
|
||||
cipher, _ := des.NewCipher(generateDesKey(key))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
||||
}
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesEcbDecrypt decrypt data with key use DES ECB algorithm
|
||||
// len(key) should be 8
|
||||
func DesEcbDecrypt(encrypted, key []byte) []byte {
|
||||
cipher, _ := des.NewCipher(generateDesKey(key))
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||
}
|
||||
|
||||
trim := 0
|
||||
if len(decrypted) > 0 {
|
||||
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
|
||||
}
|
||||
|
||||
return decrypted[:trim]
|
||||
}
|
||||
|
||||
// DesCbcEncrypt encrypt data with key use DES CBC algorithm
|
||||
// len(key) should be 8
|
||||
func DesCbcEncrypt(data, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
data = pkcs7Padding(data, block.BlockSize())
|
||||
|
||||
encrypted := make([]byte, des.BlockSize+len(data))
|
||||
iv := encrypted[:des.BlockSize]
|
||||
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesCbcDecrypt decrypt data with key use DES CBC algorithm
|
||||
// len(key) should be 8
|
||||
func DesCbcDecrypt(encrypted, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
|
||||
iv := encrypted[:des.BlockSize]
|
||||
encrypted = encrypted[des.BlockSize:]
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted, encrypted)
|
||||
|
||||
decrypted := pkcs7UnPadding(encrypted)
|
||||
return decrypted
|
||||
}
|
||||
|
||||
// DesCtrCrypt encrypt data with key use DES CTR algorithm
|
||||
// len(key) should be 8
|
||||
func DesCtrCrypt(data, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
|
||||
iv := bytes.Repeat([]byte("1"), block.BlockSize())
|
||||
stream := cipher.NewCTR(block, iv)
|
||||
|
||||
dst := make([]byte, len(data))
|
||||
stream.XORKeyStream(dst, data)
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// DesCfbEncrypt encrypt data with key use DES CFB algorithm
|
||||
// len(key) should be 8
|
||||
func DesCfbEncrypt(data, key []byte) []byte {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encrypted := make([]byte, des.BlockSize+len(data))
|
||||
iv := encrypted[:des.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesCfbDecrypt decrypt data with key use DES CFB algorithm
|
||||
// len(encrypted) should be great than 16, len(key) should be 8
|
||||
func DesCfbDecrypt(encrypted, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
if len(encrypted) < des.BlockSize {
|
||||
panic("encrypted data is too short")
|
||||
}
|
||||
iv := encrypted[:des.BlockSize]
|
||||
encrypted = encrypted[des.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted, encrypted)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesOfbEncrypt encrypt data with key use DES OFB algorithm
|
||||
// len(key) should be 16, 24 or 32
|
||||
func DesOfbEncrypt(data, key []byte) []byte {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data = pkcs7Padding(data, des.BlockSize)
|
||||
encrypted := make([]byte, des.BlockSize+len(data))
|
||||
iv := encrypted[:des.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
stream.XORKeyStream(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesOfbDecrypt decrypt data with key use DES OFB algorithm
|
||||
// len(key) should be 8
|
||||
func DesOfbDecrypt(data, key []byte) []byte {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
iv := data[:des.BlockSize]
|
||||
data = data[des.BlockSize:]
|
||||
if len(data)%des.BlockSize != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(data))
|
||||
mode := cipher.NewOFB(block, iv)
|
||||
mode.XORKeyStream(decrypted, data)
|
||||
|
||||
decrypted = pkcs7UnPadding(decrypted)
|
||||
|
||||
return decrypted
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestDesEcbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desEcbEncrypt := DesEcbEncrypt([]byte(data), []byte(key))
|
||||
desEcbDecrypt := DesEcbDecrypt(desEcbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesEcbEncrypt")
|
||||
assert.Equal(data, string(desEcbDecrypt))
|
||||
}
|
||||
|
||||
func TestDesCbcEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desCbcEncrypt := DesCbcEncrypt([]byte(data), []byte(key))
|
||||
desCbcDecrypt := DesCbcDecrypt(desCbcEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesCbcEncrypt")
|
||||
assert.Equal(data, string(desCbcDecrypt))
|
||||
}
|
||||
|
||||
func TestDesCtrCrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desCtrCrypt := DesCtrCrypt([]byte(data), []byte(key))
|
||||
desCtrDeCrypt := DesCtrCrypt(desCtrCrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesCtrCrypt")
|
||||
assert.Equal(data, string(desCtrDeCrypt))
|
||||
}
|
||||
|
||||
func TestDesCfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desCfbEncrypt := DesCfbEncrypt([]byte(data), []byte(key))
|
||||
desCfbDecrypt := DesCfbDecrypt(desCfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesCfbEncrypt")
|
||||
assert.Equal(data, string(desCfbDecrypt))
|
||||
}
|
||||
|
||||
func TestDesOfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desOfbEncrypt := DesOfbEncrypt([]byte(data), []byte(key))
|
||||
desOfbDecrypt := DesOfbDecrypt(desOfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesOfbEncrypt")
|
||||
assert.Equal(data, string(desOfbDecrypt))
|
||||
}
|
||||
498
cryptor/encrypt.go
Normal file
498
cryptor/encrypt.go
Normal file
@@ -0,0 +1,498 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package cryptor implements some util functions to encrypt and decrypt.
|
||||
// Note:
|
||||
// 1. for aes crypt function, the `key` param length should be 16, 24 or 32. if not, will panic.
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// AesEcbEncrypt encrypt data with key use AES ECB algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/jT5irszHx-j
|
||||
func AesEcbEncrypt(data, key []byte) []byte {
|
||||
length := (len(data) + aes.BlockSize) / aes.BlockSize
|
||||
plain := make([]byte, length*aes.BlockSize)
|
||||
|
||||
copy(plain, data)
|
||||
|
||||
pad := byte(len(plain) - len(data))
|
||||
for i := len(data); i < len(plain); i++ {
|
||||
plain[i] = pad
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(plain))
|
||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
||||
}
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesEcbDecrypt decrypt data with key use AES ECB algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/jT5irszHx-j
|
||||
func AesEcbDecrypt(encrypted, key []byte) []byte {
|
||||
cipher, _ := aes.NewCipher(generateAesKey(key))
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||
}
|
||||
|
||||
trim := 0
|
||||
if len(decrypted) > 0 {
|
||||
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
|
||||
}
|
||||
|
||||
return decrypted[:trim]
|
||||
}
|
||||
|
||||
// AesCbcEncrypt encrypt data with key use AES CBC algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/IOq_g8_lKZD
|
||||
func AesCbcEncrypt(data, key []byte) []byte {
|
||||
block, _ := aes.NewCipher(key)
|
||||
data = pkcs7Padding(data, block.BlockSize())
|
||||
|
||||
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted[aes.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesCbcDecrypt decrypt data with key use AES CBC algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/IOq_g8_lKZD
|
||||
func AesCbcDecrypt(encrypted, key []byte) []byte {
|
||||
block, _ := aes.NewCipher(key)
|
||||
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
encrypted = encrypted[aes.BlockSize:]
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted, encrypted)
|
||||
|
||||
decrypted := pkcs7UnPadding(encrypted)
|
||||
return decrypted
|
||||
}
|
||||
|
||||
// AesCtrCrypt encrypt data with key use AES CTR algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/SpaZO0-5Nsp
|
||||
func AesCtrCrypt(data, key []byte) []byte {
|
||||
block, _ := aes.NewCipher(key)
|
||||
|
||||
iv := bytes.Repeat([]byte("1"), block.BlockSize())
|
||||
stream := cipher.NewCTR(block, iv)
|
||||
|
||||
dst := make([]byte, len(data))
|
||||
stream.XORKeyStream(dst, data)
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// AesCfbEncrypt encrypt data with key use AES CFB algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/tfkF10B13kH
|
||||
func AesCfbEncrypt(data, key []byte) []byte {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted[aes.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesCfbDecrypt decrypt data with key use AES CFB algorithm
|
||||
// len(encrypted) should be great than 16, len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/tfkF10B13kH
|
||||
func AesCfbDecrypt(encrypted, key []byte) []byte {
|
||||
if len(encrypted) < aes.BlockSize {
|
||||
panic("encrypted data is too short")
|
||||
}
|
||||
|
||||
block, _ := aes.NewCipher(key)
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
encrypted = encrypted[aes.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
|
||||
stream.XORKeyStream(encrypted, encrypted)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesOfbEncrypt encrypt data with key use AES OFB algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/VtHxtkUj-3F
|
||||
func AesOfbEncrypt(data, key []byte) []byte {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
data = pkcs7Padding(data, aes.BlockSize)
|
||||
encrypted := make([]byte, aes.BlockSize+len(data))
|
||||
iv := encrypted[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
stream.XORKeyStream(encrypted[aes.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// AesOfbDecrypt decrypt data with key use AES OFB algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/VtHxtkUj-3F
|
||||
func AesOfbDecrypt(data, key []byte) []byte {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
iv := data[:aes.BlockSize]
|
||||
data = data[aes.BlockSize:]
|
||||
if len(data)%aes.BlockSize != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(data))
|
||||
mode := cipher.NewOFB(block, iv)
|
||||
mode.XORKeyStream(decrypted, data)
|
||||
|
||||
decrypted = pkcs7UnPadding(decrypted)
|
||||
|
||||
return decrypted
|
||||
}
|
||||
|
||||
// DesEcbEncrypt encrypt data with key use DES ECB algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/8qivmPeZy4P
|
||||
func DesEcbEncrypt(data, key []byte) []byte {
|
||||
length := (len(data) + des.BlockSize) / des.BlockSize
|
||||
plain := make([]byte, length*des.BlockSize)
|
||||
copy(plain, data)
|
||||
|
||||
pad := byte(len(plain) - len(data))
|
||||
for i := len(data); i < len(plain); i++ {
|
||||
plain[i] = pad
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(plain))
|
||||
cipher, _ := des.NewCipher(generateDesKey(key))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
|
||||
}
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesEcbDecrypt decrypt data with key use DES ECB algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/8qivmPeZy4P
|
||||
func DesEcbDecrypt(encrypted, key []byte) []byte {
|
||||
cipher, _ := des.NewCipher(generateDesKey(key))
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
|
||||
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
|
||||
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
|
||||
}
|
||||
|
||||
trim := 0
|
||||
if len(decrypted) > 0 {
|
||||
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
|
||||
}
|
||||
|
||||
return decrypted[:trim]
|
||||
}
|
||||
|
||||
// DesCbcEncrypt encrypt data with key use DES CBC algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/4cC4QvWfe3_1
|
||||
func DesCbcEncrypt(data, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
data = pkcs7Padding(data, block.BlockSize())
|
||||
|
||||
encrypted := make([]byte, des.BlockSize+len(data))
|
||||
iv := encrypted[:des.BlockSize]
|
||||
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesCbcDecrypt decrypt data with key use DES CBC algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/4cC4QvWfe3_1
|
||||
func DesCbcDecrypt(encrypted, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
|
||||
iv := encrypted[:des.BlockSize]
|
||||
encrypted = encrypted[des.BlockSize:]
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted, encrypted)
|
||||
|
||||
decrypted := pkcs7UnPadding(encrypted)
|
||||
return decrypted
|
||||
}
|
||||
|
||||
// DesCtrCrypt encrypt data with key use DES CTR algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/9-T6OjKpcdw
|
||||
func DesCtrCrypt(data, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
|
||||
iv := bytes.Repeat([]byte("1"), block.BlockSize())
|
||||
stream := cipher.NewCTR(block, iv)
|
||||
|
||||
dst := make([]byte, len(data))
|
||||
stream.XORKeyStream(dst, data)
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// DesCfbEncrypt encrypt data with key use DES CFB algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/y-eNxcFBlxL
|
||||
func DesCfbEncrypt(data, key []byte) []byte {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encrypted := make([]byte, des.BlockSize+len(data))
|
||||
iv := encrypted[:des.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesCfbDecrypt decrypt data with key use DES CFB algorithm
|
||||
// len(encrypted) should be great than 16, len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/y-eNxcFBlxL
|
||||
func DesCfbDecrypt(encrypted, key []byte) []byte {
|
||||
block, _ := des.NewCipher(key)
|
||||
if len(encrypted) < des.BlockSize {
|
||||
panic("encrypted data is too short")
|
||||
}
|
||||
iv := encrypted[:des.BlockSize]
|
||||
encrypted = encrypted[des.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(encrypted, encrypted)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesOfbEncrypt encrypt data with key use DES OFB algorithm
|
||||
// len(key) should be 16, 24 or 32.
|
||||
// Play: https://go.dev/play/p/74KmNadjN1J
|
||||
func DesOfbEncrypt(data, key []byte) []byte {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data = pkcs7Padding(data, des.BlockSize)
|
||||
encrypted := make([]byte, des.BlockSize+len(data))
|
||||
iv := encrypted[:des.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
stream.XORKeyStream(encrypted[des.BlockSize:], data)
|
||||
|
||||
return encrypted
|
||||
}
|
||||
|
||||
// DesOfbDecrypt decrypt data with key use DES OFB algorithm
|
||||
// len(key) should be 8.
|
||||
// Play: https://go.dev/play/p/74KmNadjN1J
|
||||
func DesOfbDecrypt(data, key []byte) []byte {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
iv := data[:des.BlockSize]
|
||||
data = data[des.BlockSize:]
|
||||
if len(data)%des.BlockSize != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(data))
|
||||
mode := cipher.NewOFB(block, iv)
|
||||
mode.XORKeyStream(decrypted, data)
|
||||
|
||||
decrypted = pkcs7UnPadding(decrypted)
|
||||
|
||||
return decrypted
|
||||
}
|
||||
|
||||
// GenerateRsaKey create rsa private and public pemo file.
|
||||
// Play: https://go.dev/play/p/zutRHrDqs0X
|
||||
func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error {
|
||||
// private key
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
derText := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
|
||||
block := pem.Block{
|
||||
Type: "rsa private key",
|
||||
Bytes: derText,
|
||||
}
|
||||
|
||||
file, err := os.Create(priKeyFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = pem.Encode(file, &block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
// public key
|
||||
publicKey := privateKey.PublicKey
|
||||
|
||||
derpText, err := x509.MarshalPKIXPublicKey(&publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
block = pem.Block{
|
||||
Type: "rsa public key",
|
||||
Bytes: derpText,
|
||||
}
|
||||
|
||||
file, err = os.Create(pubKeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = pem.Encode(file, &block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RsaEncrypt encrypt data with ras algorithm.
|
||||
// Play: https://go.dev/play/p/rDqTT01SPkZ
|
||||
func RsaEncrypt(data []byte, pubKeyFileName string) []byte {
|
||||
file, err := os.Open(pubKeyFileName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
buf := make([]byte, fileInfo.Size())
|
||||
|
||||
_, err = file.Read(buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(buf)
|
||||
|
||||
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pubKey := pubInterface.(*rsa.PublicKey)
|
||||
|
||||
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cipherText
|
||||
}
|
||||
|
||||
// RsaDecrypt decrypt data with ras algorithm.
|
||||
// Play: https://go.dev/play/p/rDqTT01SPkZ
|
||||
func RsaDecrypt(data []byte, privateKeyFileName string) []byte {
|
||||
file, err := os.Open(privateKeyFileName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
buf := make([]byte, fileInfo.Size())
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Read(buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(buf)
|
||||
|
||||
priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
plainText, err := rsa.DecryptPKCS1v15(rand.Reader, priKey, data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return plainText
|
||||
}
|
||||
130
cryptor/encrypt_test.go
Normal file
130
cryptor/encrypt_test.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestAesEcbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesEcbEncrypt := AesEcbEncrypt([]byte(data), []byte(key))
|
||||
aesEcbDecrypt := AesEcbDecrypt(aesEcbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesEcbEncrypt")
|
||||
assert.Equal(data, string(aesEcbDecrypt))
|
||||
}
|
||||
|
||||
func TestAesCbcEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesCbcEncrypt := AesCbcEncrypt([]byte(data), []byte(key))
|
||||
aesCbcDecrypt := AesCbcDecrypt(aesCbcEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesCbcEncrypt")
|
||||
assert.Equal(data, string(aesCbcDecrypt))
|
||||
}
|
||||
|
||||
func TestAesCtrCrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesCtrCrypt := AesCtrCrypt([]byte(data), []byte(key))
|
||||
aesCtrDeCrypt := AesCtrCrypt(aesCtrCrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesCtrCrypt")
|
||||
assert.Equal(data, string(aesCtrDeCrypt))
|
||||
}
|
||||
|
||||
func TestAesCfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesCfbEncrypt := AesCfbEncrypt([]byte(data), []byte(key))
|
||||
aesCfbDecrypt := AesCfbDecrypt(aesCfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesCfbEncrypt")
|
||||
assert.Equal(data, string(aesCfbDecrypt))
|
||||
}
|
||||
|
||||
func TestAesOfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefghijklmnop"
|
||||
|
||||
aesOfbEncrypt := AesOfbEncrypt([]byte(data), []byte(key))
|
||||
aesOfbDecrypt := AesOfbDecrypt(aesOfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestAesOfbEncrypt")
|
||||
assert.Equal(data, string(aesOfbDecrypt))
|
||||
}
|
||||
|
||||
func TestDesEcbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desEcbEncrypt := DesEcbEncrypt([]byte(data), []byte(key))
|
||||
desEcbDecrypt := DesEcbDecrypt(desEcbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesEcbEncrypt")
|
||||
assert.Equal(data, string(desEcbDecrypt))
|
||||
}
|
||||
|
||||
func TestDesCbcEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desCbcEncrypt := DesCbcEncrypt([]byte(data), []byte(key))
|
||||
desCbcDecrypt := DesCbcDecrypt(desCbcEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesCbcEncrypt")
|
||||
assert.Equal(data, string(desCbcDecrypt))
|
||||
}
|
||||
|
||||
func TestDesCtrCrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desCtrCrypt := DesCtrCrypt([]byte(data), []byte(key))
|
||||
desCtrDeCrypt := DesCtrCrypt(desCtrCrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesCtrCrypt")
|
||||
assert.Equal(data, string(desCtrDeCrypt))
|
||||
}
|
||||
|
||||
func TestDesCfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desCfbEncrypt := DesCfbEncrypt([]byte(data), []byte(key))
|
||||
desCfbDecrypt := DesCfbDecrypt(desCfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesCfbEncrypt")
|
||||
assert.Equal(data, string(desCfbDecrypt))
|
||||
}
|
||||
|
||||
func TestDesOfbEncrypt(t *testing.T) {
|
||||
data := "hello world"
|
||||
key := "abcdefgh"
|
||||
|
||||
desOfbEncrypt := DesOfbEncrypt([]byte(data), []byte(key))
|
||||
desOfbDecrypt := DesOfbDecrypt(desOfbEncrypt, []byte(key))
|
||||
|
||||
assert := internal.NewAssert(t, "TestDesOfbEncrypt")
|
||||
assert.Equal(data, string(desOfbDecrypt))
|
||||
}
|
||||
|
||||
func TestRsaEncrypt(t *testing.T) {
|
||||
err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
data := []byte("hello world")
|
||||
encrypted := RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
assert := internal.NewAssert(t, "TestRsaEncrypt")
|
||||
assert.Equal(string(data), string(decrypted))
|
||||
}
|
||||
134
cryptor/rsa.go
134
cryptor/rsa.go
@@ -1,134 +0,0 @@
|
||||
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package cryptor implements some util functions to encrypt and decrypt.
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"os"
|
||||
)
|
||||
|
||||
// GenerateRsaKey make a rsa private key, and return key file name
|
||||
// Generated key file is `rsa_private.pem` and `rsa_public.pem` in current path
|
||||
func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error {
|
||||
// private key
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
derText := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
|
||||
block := pem.Block{
|
||||
Type: "rsa private key",
|
||||
Bytes: derText,
|
||||
}
|
||||
|
||||
//file,err := os.Create("rsa_private.pem")
|
||||
file, err := os.Create(priKeyFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = pem.Encode(file, &block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
// public key
|
||||
publicKey := privateKey.PublicKey
|
||||
|
||||
derpText, err := x509.MarshalPKIXPublicKey(&publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
block = pem.Block{
|
||||
Type: "rsa public key",
|
||||
Bytes: derpText,
|
||||
}
|
||||
|
||||
file, err = os.Create(pubKeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = pem.Encode(file, &block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RsaEncrypt encrypt data with ras algorithm
|
||||
func RsaEncrypt(data []byte, pubKeyFileName string) []byte {
|
||||
file, err := os.Open(pubKeyFileName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
buf := make([]byte, fileInfo.Size())
|
||||
|
||||
_, err = file.Read(buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(buf)
|
||||
|
||||
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pubKey := pubInterface.(*rsa.PublicKey)
|
||||
|
||||
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cipherText
|
||||
}
|
||||
|
||||
// RsaDecrypt decrypt data with ras algorithm
|
||||
func RsaDecrypt(data []byte, privateKeyFileName string) []byte {
|
||||
file, err := os.Open(privateKeyFileName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
buf := make([]byte, fileInfo.Size())
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Read(buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(buf)
|
||||
|
||||
priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
plainText, err := rsa.DecryptPKCS1v15(rand.Reader, priKey, data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return plainText
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package cryptor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
)
|
||||
|
||||
func TestRsaEncrypt(t *testing.T) {
|
||||
err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
data := []byte("hello world")
|
||||
encrypted := RsaEncrypt(data, "rsa_public.pem")
|
||||
decrypted := RsaDecrypt(encrypted, "rsa_private.pem")
|
||||
|
||||
assert := internal.NewAssert(t, "TestRsaEncrypt")
|
||||
assert.Equal(string(data), string(decrypted))
|
||||
}
|
||||
@@ -8,17 +8,17 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// List is a linear table, implemented with slice
|
||||
// List is a linear table, implemented with slice.
|
||||
type List[T any] struct {
|
||||
data []T
|
||||
}
|
||||
|
||||
// NewList return a pointer of List
|
||||
// NewList return a pointer of List.
|
||||
func NewList[T any](data []T) *List[T] {
|
||||
return &List[T]{data: data}
|
||||
}
|
||||
|
||||
// Data return list data
|
||||
// Data return list data.
|
||||
func (l *List[T]) Data() []T {
|
||||
return l.data
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func (l *List[T]) ValueOf(index int) (*T, bool) {
|
||||
return &l.data[index], true
|
||||
}
|
||||
|
||||
// IndexOf returns the index of value. if not found return -1
|
||||
// IndexOf returns the index of value. if not found return -1.
|
||||
func (l *List[T]) IndexOf(value T) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
@@ -45,7 +45,7 @@ func (l *List[T]) IndexOf(value T) int {
|
||||
}
|
||||
|
||||
// LastIndexOf returns the index of the last occurrence of the value in this list.
|
||||
// if not found return -1
|
||||
// if not found return -1.
|
||||
func (l *List[T]) LastIndexOf(value T) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
@@ -59,7 +59,7 @@ func (l *List[T]) LastIndexOf(value T) int {
|
||||
}
|
||||
|
||||
// IndexOfFunc returns the first index satisfying f(v)
|
||||
// if not found return -1
|
||||
// if not found return -1.
|
||||
func (l *List[T]) IndexOfFunc(f func(T) bool) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
@@ -73,7 +73,7 @@ func (l *List[T]) IndexOfFunc(f func(T) bool) int {
|
||||
}
|
||||
|
||||
// LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying f(data[i])
|
||||
// if not found return -1
|
||||
// if not found return -1.
|
||||
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
@@ -86,7 +86,7 @@ func (l *List[T]) LastIndexOfFunc(f func(T) bool) int {
|
||||
return index
|
||||
}
|
||||
|
||||
// Contain checks if the value in the list or not
|
||||
// Contain checks if the value in the list or not.
|
||||
func (l *List[T]) Contain(value T) bool {
|
||||
data := l.data
|
||||
for _, v := range data {
|
||||
@@ -97,22 +97,22 @@ func (l *List[T]) Contain(value T) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Push append value to the list data
|
||||
// Push append value to the list data.
|
||||
func (l *List[T]) Push(value T) {
|
||||
l.data = append(l.data, value)
|
||||
}
|
||||
|
||||
// InsertAtFirst insert value into list at first index
|
||||
// InsertAtFirst insert value into list at first index.
|
||||
func (l *List[T]) InsertAtFirst(value T) {
|
||||
l.InsertAt(0, value)
|
||||
}
|
||||
|
||||
// InsertAtLast insert value into list at last index
|
||||
// InsertAtLast insert value into list at last index.
|
||||
func (l *List[T]) InsertAtLast(value T) {
|
||||
l.InsertAt(len(l.data), value)
|
||||
}
|
||||
|
||||
// InsertAt insert value into list at index
|
||||
// InsertAt insert value into list at index.
|
||||
func (l *List[T]) InsertAt(index int, value T) {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
@@ -123,7 +123,7 @@ func (l *List[T]) InsertAt(index int, value T) {
|
||||
l.data = append(data[:index], append([]T{value}, data[index:]...)...)
|
||||
}
|
||||
|
||||
// PopFirst delete the first value of list and return it
|
||||
// PopFirst delete the first value of list and return it.
|
||||
func (l *List[T]) PopFirst() (*T, bool) {
|
||||
if len(l.data) == 0 {
|
||||
return nil, false
|
||||
@@ -135,7 +135,7 @@ func (l *List[T]) PopFirst() (*T, bool) {
|
||||
return &v, true
|
||||
}
|
||||
|
||||
// PopLast delete the last value of list and return it
|
||||
// PopLast delete the last value of list and return it.
|
||||
func (l *List[T]) PopLast() (*T, bool) {
|
||||
size := len(l.data)
|
||||
if size == 0 {
|
||||
@@ -148,7 +148,7 @@ func (l *List[T]) PopLast() (*T, bool) {
|
||||
return &v, true
|
||||
}
|
||||
|
||||
// DeleteAt delete the value of list at index
|
||||
// DeleteAt delete the value of list at index.
|
||||
func (l *List[T]) DeleteAt(index int) {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
@@ -199,7 +199,7 @@ func (l *List[T]) UpdateAt(index int, value T) {
|
||||
l.data = append(data[:index], append([]T{value}, data[index+1:]...)...)
|
||||
}
|
||||
|
||||
// Equal compare list to other list, use reflect.DeepEqual
|
||||
// Equal compare list to other list, use reflect.DeepEqual.
|
||||
func (l *List[T]) Equal(other *List[T]) bool {
|
||||
if len(l.data) != len(other.data) {
|
||||
return false
|
||||
@@ -214,17 +214,17 @@ func (l *List[T]) Equal(other *List[T]) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsEmpty check if the list is empty or not
|
||||
// IsEmpty check if the list is empty or not.
|
||||
func (l *List[T]) IsEmpty() bool {
|
||||
return len(l.data) == 0
|
||||
}
|
||||
|
||||
// Clear the data of list
|
||||
// Clear the data of list.
|
||||
func (l *List[T]) Clear() {
|
||||
l.data = make([]T, 0)
|
||||
}
|
||||
|
||||
// Clone return a copy of list
|
||||
// Clone return a copy of list.
|
||||
func (l *List[T]) Clone() *List[T] {
|
||||
cl := NewList(make([]T, len(l.data)))
|
||||
copy(cl.data, l.data)
|
||||
@@ -232,7 +232,7 @@ func (l *List[T]) Clone() *List[T] {
|
||||
return cl
|
||||
}
|
||||
|
||||
// Merge two list, return new list, don't change original list
|
||||
// Merge two list, return new list, don't change original list.
|
||||
func (l *List[T]) Merge(other *List[T]) *List[T] {
|
||||
l1, l2 := len(l.data), len(other.data)
|
||||
ml := NewList(make([]T, l1+l2))
|
||||
@@ -243,17 +243,17 @@ func (l *List[T]) Merge(other *List[T]) *List[T] {
|
||||
return ml
|
||||
}
|
||||
|
||||
// Size return number of list data items
|
||||
// Size return number of list data items.
|
||||
func (l *List[T]) Size() int {
|
||||
return len(l.data)
|
||||
}
|
||||
|
||||
// Cap return cap of the inner data
|
||||
// Cap return cap of the inner data.
|
||||
func (l *List[T]) Cap() int {
|
||||
return cap(l.data)
|
||||
}
|
||||
|
||||
// Swap the value of index i and j in list
|
||||
// Swap the value of index i and j in list.
|
||||
func (l *List[T]) Swap(i, j int) {
|
||||
size := len(l.data)
|
||||
if i < 0 || i >= size || j < 0 || j >= size {
|
||||
@@ -262,14 +262,14 @@ func (l *List[T]) Swap(i, j int) {
|
||||
l.data[i], l.data[j] = l.data[j], l.data[i]
|
||||
}
|
||||
|
||||
// Reverse the item order of list
|
||||
// Reverse the item order of list.
|
||||
func (l *List[T]) Reverse() {
|
||||
for i, j := 0, len(l.data)-1; i < j; i, j = i+1, j-1 {
|
||||
l.data[i], l.data[j] = l.data[j], l.data[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Unique remove duplicate items in list
|
||||
// Unique remove duplicate items in list.
|
||||
func (l *List[T]) Unique() {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
@@ -303,7 +303,7 @@ func (l *List[T]) Union(other *List[T]) *List[T] {
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection creates a new list whose element both be contained in list l and other
|
||||
// Intersection creates a new list whose element both be contained in list l and other.
|
||||
func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
||||
result := NewList(make([]T, 0))
|
||||
|
||||
|
||||
@@ -9,17 +9,20 @@ type theTime struct {
|
||||
unix int64
|
||||
}
|
||||
|
||||
// NewUnixNow return unix timestamp of current time
|
||||
// NewUnixNow return unix timestamp of current time.
|
||||
// Play: https://go.dev/play/p/U4PPx-9D0oz
|
||||
func NewUnixNow() *theTime {
|
||||
return &theTime{unix: time.Now().Unix()}
|
||||
}
|
||||
|
||||
// NewUnix return unix timestamp of specified time
|
||||
// NewUnix return unix timestamp of specified time.
|
||||
// Play: https://go.dev/play/p/psoSuh_kLRt
|
||||
func NewUnix(unix int64) *theTime {
|
||||
return &theTime{unix: unix}
|
||||
}
|
||||
|
||||
// NewFormat return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss"
|
||||
// NewFormat return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".
|
||||
// Play: https://go.dev/play/p/VkW08ZOaXPZ
|
||||
func NewFormat(t string) (*theTime, error) {
|
||||
timeLayout := "2006-01-02 15:04:05"
|
||||
loc := time.FixedZone("CST", 8*3600)
|
||||
@@ -30,7 +33,8 @@ func NewFormat(t string) (*theTime, error) {
|
||||
return &theTime{unix: tt.Unix()}, nil
|
||||
}
|
||||
|
||||
// NewISO8601 return unix timestamp of specified iso8601 time string
|
||||
// NewISO8601 return unix timestamp of specified iso8601 time string.
|
||||
// Play: https://go.dev/play/p/mkhOHQkdeA2
|
||||
func NewISO8601(iso8601 string) (*theTime, error) {
|
||||
t, err := time.ParseInLocation(time.RFC3339, iso8601, time.UTC)
|
||||
if err != nil {
|
||||
@@ -39,22 +43,26 @@ func NewISO8601(iso8601 string) (*theTime, error) {
|
||||
return &theTime{unix: t.Unix()}, nil
|
||||
}
|
||||
|
||||
// ToUnix return unix timestamp
|
||||
// ToUnix return unix timestamp.
|
||||
// Play: https://go.dev/play/p/_LUiwAdocjy
|
||||
func (t *theTime) ToUnix() int64 {
|
||||
return t.unix
|
||||
}
|
||||
|
||||
// ToFormat return the time string 'yyyy-mm-dd hh:mm:ss' of unix time
|
||||
// ToFormat return the time string 'yyyy-mm-dd hh:mm:ss' of unix time.
|
||||
// Play: https://go.dev/play/p/VkW08ZOaXPZ
|
||||
func (t *theTime) ToFormat() string {
|
||||
return time.Unix(t.unix, 0).Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// ToFormatForTpl return the time string which format is specified tpl
|
||||
// ToFormatForTpl return the time string which format is specified tpl.
|
||||
// Play: https://go.dev/play/p/nyXxXcQJ8L5
|
||||
func (t *theTime) ToFormatForTpl(tpl string) string {
|
||||
return time.Unix(t.unix, 0).Format(tpl)
|
||||
}
|
||||
|
||||
// ToFormatForTpl return iso8601 time string
|
||||
// ToFormatForTpl return iso8601 time string.
|
||||
// Play: https://go.dev/play/p/mkhOHQkdeA2
|
||||
func (t *theTime) ToIso8601() string {
|
||||
return time.Unix(t.unix, 0).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
@@ -19,9 +19,6 @@ func TestToUnix(t *testing.T) {
|
||||
func TestToFormat(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToFormat")
|
||||
|
||||
_, err := NewFormat("2022/03/18 17:04:05")
|
||||
assert.IsNotNil(err)
|
||||
|
||||
tm, err := NewFormat("2022-03-18 17:04:05")
|
||||
assert.IsNil(err)
|
||||
|
||||
|
||||
@@ -54,54 +54,64 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// AddMinute add or sub minute to the time
|
||||
// AddMinute add or sub minute to the time.
|
||||
// Play: https://go.dev/play/p/nT1heB1KUUK
|
||||
func AddMinute(t time.Time, minute int64) time.Time {
|
||||
return t.Add(time.Minute * time.Duration(minute))
|
||||
}
|
||||
|
||||
// AddHour add or sub hour to the time
|
||||
// AddHour add or sub hour to the time.
|
||||
// Play: https://go.dev/play/p/rcMjd7OCsi5
|
||||
func AddHour(t time.Time, hour int64) time.Time {
|
||||
return t.Add(time.Hour * time.Duration(hour))
|
||||
}
|
||||
|
||||
// AddDay add or sub day to the time
|
||||
// AddDay add or sub day to the time.
|
||||
// Play: https://go.dev/play/p/dIGbs_uTdFa
|
||||
func AddDay(t time.Time, day int64) time.Time {
|
||||
return t.Add(24 * time.Hour * time.Duration(day))
|
||||
}
|
||||
|
||||
// GetNowDate return format yyyy-mm-dd of current date
|
||||
// GetNowDate return format yyyy-mm-dd of current date.
|
||||
// Play: https://go.dev/play/p/PvfkPpcpBBf
|
||||
func GetNowDate() string {
|
||||
return time.Now().Format("2006-01-02")
|
||||
}
|
||||
|
||||
// GetNowTime return format hh-mm-ss of current time
|
||||
// GetNowTime return format hh-mm-ss of current time.
|
||||
// Play: https://go.dev/play/p/l7BNxCkTmJS
|
||||
func GetNowTime() string {
|
||||
return time.Now().Format("15:04:05")
|
||||
}
|
||||
|
||||
// GetNowDateTime return format yyyy-mm-dd hh-mm-ss of current datetime
|
||||
// GetNowDateTime return format yyyy-mm-dd hh-mm-ss of current datetime.
|
||||
// Play: https://go.dev/play/p/pI4AqngD0al
|
||||
func GetNowDateTime() string {
|
||||
return time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// GetZeroHourTimestamp return timestamp of zero hour (timestamp of 00:00)
|
||||
// GetZeroHourTimestamp return timestamp of zero hour (timestamp of 00:00).
|
||||
// Play: https://go.dev/play/p/QmL2oIaGE3q
|
||||
func GetZeroHourTimestamp() int64 {
|
||||
ts := time.Now().Format("2006-01-02")
|
||||
t, _ := time.Parse("2006-01-02", ts)
|
||||
return t.UTC().Unix() - 8*3600
|
||||
}
|
||||
|
||||
// GetNightTimestamp return timestamp of zero hour (timestamp of 23:59)
|
||||
// GetNightTimestamp return timestamp of zero hour (timestamp of 23:59).
|
||||
// Play: https://go.dev/play/p/UolysR3MYP1
|
||||
func GetNightTimestamp() int64 {
|
||||
return GetZeroHourTimestamp() + 86400 - 1
|
||||
}
|
||||
|
||||
// FormatTimeToStr convert time to string
|
||||
// FormatTimeToStr convert time to string.
|
||||
// Play: https://go.dev/play/p/_Ia7M8H_OvE
|
||||
func FormatTimeToStr(t time.Time, format string) string {
|
||||
return t.Format(timeFormat[format])
|
||||
}
|
||||
|
||||
// FormatStrToTime convert string to time
|
||||
// FormatStrToTime convert string to time.
|
||||
// Play: https://go.dev/play/p/1h9FwdU8ql4
|
||||
func FormatStrToTime(str, format string) (time.Time, error) {
|
||||
v, ok := timeFormat[format]
|
||||
if !ok {
|
||||
@@ -111,43 +121,50 @@ func FormatStrToTime(str, format string) (time.Time, error) {
|
||||
return time.Parse(v, str)
|
||||
}
|
||||
|
||||
// BeginOfMinute return beginning minute time of day
|
||||
// BeginOfMinute return beginning minute time of day.
|
||||
// Play: https://go.dev/play/p/ieOLVJ9CiFT
|
||||
func BeginOfMinute(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), t.Minute(), 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfMinute return end minute time of day
|
||||
// EndOfMinute return end minute time of day.
|
||||
// Play: https://go.dev/play/p/yrL5wGzPj4z
|
||||
func EndOfMinute(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), t.Minute(), 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfHour return beginning hour time of day
|
||||
// BeginOfHour return beginning hour time of day.
|
||||
// Play: https://go.dev/play/p/GhdGFnDWpYs
|
||||
func BeginOfHour(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfHour return end hour time of day
|
||||
// EndOfHour return end hour time of day.
|
||||
// Play: https://go.dev/play/p/6ce3j_6cVqN
|
||||
func EndOfHour(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, t.Hour(), 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfDay return beginning hour time of day
|
||||
// BeginOfDay return beginning hour time of day.
|
||||
// Play: https://go.dev/play/p/94m_UT6cWs9
|
||||
func BeginOfDay(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfDay return end time of day
|
||||
// EndOfDay return end time of day.
|
||||
// Play: https://go.dev/play/p/eMBOvmq5Ih1
|
||||
func EndOfDay(t time.Time) time.Time {
|
||||
y, m, d := t.Date()
|
||||
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
|
||||
}
|
||||
|
||||
// BeginOfWeek return beginning week, default week begin from Sunday
|
||||
// BeginOfWeek return beginning week, default week begin from Sunday.
|
||||
// Play: https://go.dev/play/p/ynjoJPz7VNV
|
||||
func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time {
|
||||
var beginFromWeekday = time.Sunday
|
||||
if len(beginFrom) > 0 {
|
||||
@@ -161,7 +178,8 @@ func BeginOfWeek(t time.Time, beginFrom ...time.Weekday) time.Time {
|
||||
return beginOfWeek
|
||||
}
|
||||
|
||||
// EndOfWeek return end week time, default week end with Saturday
|
||||
// EndOfWeek return end week time, default week end with Saturday.
|
||||
// Play: https://go.dev/play/p/i08qKXD9flf
|
||||
func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time {
|
||||
var endWithWeekday = time.Saturday
|
||||
if len(endWith) > 0 {
|
||||
@@ -175,24 +193,28 @@ func EndOfWeek(t time.Time, endWith ...time.Weekday) time.Time {
|
||||
return endWithWeek
|
||||
}
|
||||
|
||||
// BeginOfMonth return beginning of month
|
||||
// BeginOfMonth return beginning of month.
|
||||
// Play: https://go.dev/play/p/bWXVFsmmzwL
|
||||
func BeginOfMonth(t time.Time) time.Time {
|
||||
y, m, _ := t.Date()
|
||||
return time.Date(y, m, 1, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfMonth return end of month
|
||||
// EndOfMonth return end of month.
|
||||
// Play: https://go.dev/play/p/_GWh10B3Nqi
|
||||
func EndOfMonth(t time.Time) time.Time {
|
||||
return BeginOfMonth(t).AddDate(0, 1, 0).Add(-time.Nanosecond)
|
||||
}
|
||||
|
||||
// BeginOfYear return beginning of year
|
||||
// BeginOfYear return the date time at the begin of year.
|
||||
// Play: https://go.dev/play/p/i326DSwLnV8
|
||||
func BeginOfYear(t time.Time) time.Time {
|
||||
y, _, _ := t.Date()
|
||||
return time.Date(y, time.January, 1, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfYear return end of year
|
||||
// EndOfYear return the date time at the end of year.
|
||||
// Play: https://go.dev/play/p/G01cKlMCvNm
|
||||
func EndOfYear(t time.Time) time.Time {
|
||||
return BeginOfYear(t).AddDate(1, 0, 0).Add(-time.Nanosecond)
|
||||
}
|
||||
|
||||
323
datetime/datetime_example_test.go
Normal file
323
datetime/datetime_example_test.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package datetime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ExampleAddDay() {
|
||||
now := time.Now()
|
||||
|
||||
tomorrow := AddDay(now, 1)
|
||||
diff1 := tomorrow.Sub(now)
|
||||
|
||||
yesterday := AddDay(now, -1)
|
||||
diff2 := yesterday.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 24h0m0s
|
||||
// -24h0m0s
|
||||
}
|
||||
|
||||
func ExampleAddHour() {
|
||||
now := time.Now()
|
||||
|
||||
after2Hours := AddHour(now, 2)
|
||||
diff1 := after2Hours.Sub(now)
|
||||
|
||||
before2Hours := AddHour(now, -2)
|
||||
diff2 := before2Hours.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 2h0m0s
|
||||
// -2h0m0s
|
||||
}
|
||||
|
||||
func ExampleAddMinute() {
|
||||
now := time.Now()
|
||||
|
||||
after2Minutes := AddMinute(now, 2)
|
||||
diff1 := after2Minutes.Sub(now)
|
||||
|
||||
before2Minutes := AddMinute(now, -2)
|
||||
diff2 := before2Minutes.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 2m0s
|
||||
// -2m0s
|
||||
}
|
||||
|
||||
func ExampleGetNowDate() {
|
||||
result := GetNowDate()
|
||||
|
||||
expected := time.Now().Format("2006-01-02")
|
||||
|
||||
fmt.Println(result == expected)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleGetNowTime() {
|
||||
result := GetNowTime()
|
||||
|
||||
expected := time.Now().Format("15:04:05")
|
||||
|
||||
fmt.Println(result == expected)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleGetNowDateTime() {
|
||||
result := GetNowDateTime()
|
||||
|
||||
expected := time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
fmt.Println(result == expected)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
// func ExampleGetZeroHourTimestamp() {
|
||||
// ts := GetZeroHourTimestamp()
|
||||
|
||||
// fmt.Println(ts)
|
||||
|
||||
// // Output:
|
||||
// // 1673107200
|
||||
// }
|
||||
|
||||
// func ExampleGetNightTimestamp() {
|
||||
// ts := GetNightTimestamp()
|
||||
|
||||
// fmt.Println(ts)
|
||||
|
||||
// // Output:
|
||||
// // 1673193599
|
||||
// }
|
||||
|
||||
func ExampleFormatTimeToStr() {
|
||||
datetime, _ := time.Parse("2006-01-02 15:04:05", "2021-01-02 16:04:08")
|
||||
|
||||
result1 := FormatTimeToStr(datetime, "yyyy-mm-dd hh:mm:ss")
|
||||
result2 := FormatTimeToStr(datetime, "yyyy-mm-dd")
|
||||
result3 := FormatTimeToStr(datetime, "dd-mm-yy hh:mm:ss")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 2021-01-02 16:04:08
|
||||
// 2021-01-02
|
||||
// 02-01-21 16:04:08
|
||||
}
|
||||
|
||||
func ExampleFormatStrToTime() {
|
||||
result1, _ := FormatStrToTime("2021-01-02 16:04:08", "yyyy-mm-dd hh:mm:ss")
|
||||
result2, _ := FormatStrToTime("2021-01-02", "yyyy-mm-dd")
|
||||
result3, _ := FormatStrToTime("02-01-21 16:04:08", "dd-mm-yy hh:mm:ss")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 2021-01-02 16:04:08 +0000 UTC
|
||||
// 2021-01-02 00:00:00 +0000 UTC
|
||||
// 2021-01-02 16:04:08 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleBeginOfMinute() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := BeginOfMinute(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:50:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleEndOfMinute() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := EndOfMinute(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:50:59.999999999 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleBeginOfHour() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := BeginOfHour(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:00:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleEndOfHour() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := EndOfHour(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 18:59:59.999999999 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleBeginOfDay() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := BeginOfDay(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 00:00:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleEndOfDay() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := EndOfDay(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleBeginOfWeek() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := BeginOfWeek(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-08 00:00:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleEndOfWeek() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := EndOfWeek(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-14 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleBeginOfMonth() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := BeginOfMonth(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-01 00:00:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleEndOfMonth() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := EndOfMonth(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-31 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleBeginOfYear() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := BeginOfYear(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-01-01 00:00:00 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleEndOfYear() {
|
||||
input := time.Date(2023, 1, 8, 18, 50, 10, 100, time.UTC)
|
||||
|
||||
result := EndOfYear(input)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// 2023-12-31 23:59:59.999999999 +0000 UTC
|
||||
}
|
||||
|
||||
func ExampleNewUnix() {
|
||||
result := NewUnix(1647597438)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// &{1647597438}
|
||||
}
|
||||
|
||||
func ExampleNewUnixNow() {
|
||||
tm1 := NewUnixNow()
|
||||
|
||||
unixTimestamp := tm1.ToUnix()
|
||||
|
||||
tm2 := NewUnix(unixTimestamp)
|
||||
|
||||
fmt.Println(reflect.DeepEqual(tm1, tm2))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
// func ExampleNewFormat() {
|
||||
// tm, err := NewFormat("2022-03-18 17:04:05")
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// result := tm.ToFormat()
|
||||
|
||||
// fmt.Println(result)
|
||||
|
||||
// // Output:
|
||||
// // 2022-03-18 17:04:05
|
||||
// }
|
||||
|
||||
// func ExampleNewISO8601() {
|
||||
// tm, err := NewISO8601("2006-01-02T15:04:05.999Z")
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// result := tm.ToIso8601()
|
||||
|
||||
// fmt.Println(result)
|
||||
|
||||
// // Output:
|
||||
// // 2006-01-02T23:04:05+08:00
|
||||
// }
|
||||
@@ -52,8 +52,8 @@ func TestGetNowDate(t *testing.T) {
|
||||
assert.Equal(expected, GetNowDate())
|
||||
}
|
||||
|
||||
func TestGetNotTime(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestGetNotTime")
|
||||
func TestGetNowTime(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestGetNowTime")
|
||||
expected := time.Now().Format("15:04:05")
|
||||
assert.Equal(expected, GetNowTime())
|
||||
}
|
||||
@@ -81,7 +81,6 @@ func TestFormatTimeToStr(t *testing.T) {
|
||||
for i := 0; i < len(cases); i++ {
|
||||
actual := FormatTimeToStr(datetime, cases[i])
|
||||
assert.Equal(expected[i], actual)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ Package cryptor contains some functions for data encryption and decryption. Supp
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.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/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/encrypt.go](https://github.com/duke-git/lancet/blob/main/cryptor/encrypt.go)
|
||||
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
|
||||
@@ -5,10 +5,8 @@ cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.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/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/cryptor/encrypt.go](https://github.com/duke-git/lancet/blob/main/cryptor/encrypt.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -186,7 +184,7 @@ func main() {
|
||||
|
||||
### <span id="AesCtrCrypt">AesCtrCrypt</span>
|
||||
|
||||
<p>使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。</p>
|
||||
<p>使用AES CTR算法模式加密/解密数据,参数`key`的长度是16, 24 or 32。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
|
||||
@@ -377,7 +377,7 @@ func main() {
|
||||
```
|
||||
|
||||
### <span id="EndOfDay">EndOfDay</span>
|
||||
<p>返回指定时间的当天结束时间.</p>
|
||||
<p>返回指定时间的当天结束时间</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -541,7 +541,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="GetNowDateTime">GetNowDateTime</span>
|
||||
<p>获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss.</p>
|
||||
<p>获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -568,7 +568,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
|
||||
<p>获取零时时间戳(timestamp of 00:00).</p>
|
||||
<p>获取零时时间戳(timestamp of 00:00)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -595,7 +595,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="GetNightTimestamp">GetNightTimestamp</span>
|
||||
<p>获取午夜时间戳(timestamp of 23:59).</p>
|
||||
<p>获取午夜时间戳(timestamp of 23:59)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
|
||||
@@ -531,7 +531,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="StructToUrlValues">StructToUrlValues</span>
|
||||
<p>将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag.</p>
|
||||
<p>将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
|
||||
@@ -46,12 +46,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
|
||||
|
||||
### <span id="Unwrap">Unwrap</span>
|
||||
<p>如果err为nil则展开,则它返回一个有效值。 如果err不是nil则Unwrap使用err发生恐慌。</p>
|
||||
<p>检查error, 如果err为nil则展开,则它返回一个有效值,如果err不是nil则Unwrap使用err发生panic。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -46,12 +46,20 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := xerror.Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
fmt.Println(err.Error()) // err.Error() == v.(*strconv.NumError).Error()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
|
||||
xerror.Unwrap(strconv.Atoi("4o2"))
|
||||
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ func ExampleIsExist() {
|
||||
}
|
||||
|
||||
func ExampleCreateFile() {
|
||||
fname := "./test.txt"
|
||||
fname := "./a.txt"
|
||||
|
||||
result1 := IsExist(fname)
|
||||
|
||||
@@ -175,11 +175,11 @@ func ExampleReadFileByLine() {
|
||||
}
|
||||
|
||||
func ExampleListFileNames() {
|
||||
fileList, _ := ListFileNames("./")
|
||||
fileList, _ := ListFileNames("../formatter/")
|
||||
fmt.Println(fileList)
|
||||
|
||||
// Output:
|
||||
// [file.go file_example_test.go file_test.go]
|
||||
// [formatter.go formatter_example_test.go formatter_test.go]
|
||||
}
|
||||
|
||||
func ExampleZip() {
|
||||
|
||||
@@ -96,16 +96,6 @@ func TestCopyFile(t *testing.T) {
|
||||
os.Remove(destFile)
|
||||
}
|
||||
|
||||
func TestListFileNames(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestListFileNames")
|
||||
|
||||
filesInPath, err := ListFileNames("./")
|
||||
assert.IsNil(err)
|
||||
|
||||
expected := []string{"file.go", "file_test.go"}
|
||||
assert.Equal(expected, filesInPath)
|
||||
}
|
||||
|
||||
func TestReadFileToString(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestReadFileToString")
|
||||
|
||||
@@ -241,3 +231,13 @@ func TestMiMeType(t *testing.T) {
|
||||
assert.Equal("text/plain; charset=utf-8", MiMeType(f))
|
||||
assert.Equal("text/plain; charset=utf-8", MiMeType("./file.go"))
|
||||
}
|
||||
|
||||
func TestListFileNames(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestListFileNames")
|
||||
|
||||
filesInPath, err := ListFileNames("../formatter/")
|
||||
assert.IsNil(err)
|
||||
|
||||
expected := []string{"formatter.go", "formatter_example_test.go", "formatter_test.go"}
|
||||
assert.Equal(expected, filesInPath)
|
||||
}
|
||||
|
||||
@@ -145,14 +145,6 @@ func unsafeInvokeFunc(fn any, args ...any) []reflect.Value {
|
||||
return fv.Call(params)
|
||||
}
|
||||
|
||||
func functionValue(function any) reflect.Value {
|
||||
v := reflect.ValueOf(function)
|
||||
if v.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func mustBeFunction(function any) {
|
||||
v := reflect.ValueOf(function)
|
||||
if v.Kind() != reflect.Func {
|
||||
|
||||
@@ -108,21 +108,21 @@ func ExampleDebounced() {
|
||||
}
|
||||
|
||||
func ExampleSchedule() {
|
||||
var result []string
|
||||
count := 0
|
||||
|
||||
appendFn := func(s string) {
|
||||
result = append(result, s)
|
||||
increase := func() {
|
||||
count++
|
||||
}
|
||||
|
||||
stop := Schedule(1*time.Second, appendFn, "*")
|
||||
stop := Schedule(1*time.Second, increase)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
close(stop)
|
||||
|
||||
fmt.Println(result)
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// [* * *]
|
||||
// 3
|
||||
}
|
||||
|
||||
func ExamplePipeline() {
|
||||
|
||||
@@ -55,6 +55,7 @@ func Factorial(x uint) uint {
|
||||
}
|
||||
|
||||
// Percent calculate the percentage of value to total.
|
||||
// Play: Todo
|
||||
func Percent(val, total float64, n int) float64 {
|
||||
if total == 0 {
|
||||
return float64(0)
|
||||
|
||||
@@ -21,32 +21,32 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
//HttpGet send get http request
|
||||
// HttpGet send get http request.
|
||||
func HttpGet(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodGet, url, params...)
|
||||
}
|
||||
|
||||
//HttpPost send post http request
|
||||
// HttpPost send post http request.
|
||||
func HttpPost(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodPost, url, params...)
|
||||
}
|
||||
|
||||
//HttpPut send put http request
|
||||
// HttpPut send put http request.
|
||||
func HttpPut(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodPut, url, params...)
|
||||
}
|
||||
|
||||
//HttpDelete send delete http request
|
||||
// HttpDelete send delete http request.
|
||||
func HttpDelete(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodDelete, url, params...)
|
||||
}
|
||||
|
||||
// HttpPatch send patch http request
|
||||
// HttpPatch send patch http request.
|
||||
func HttpPatch(url string, params ...any) (*http.Response, error) {
|
||||
return doHttpRequest(http.MethodPatch, url, params...)
|
||||
}
|
||||
|
||||
// ParseHttpResponse decode http response to specified interface
|
||||
// ParseHttpResponse decode http response to specified interface.
|
||||
func ParseHttpResponse(resp *http.Response, obj any) error {
|
||||
if resp == nil {
|
||||
return errors.New("InvalidResp")
|
||||
@@ -55,7 +55,8 @@ func ParseHttpResponse(resp *http.Response, obj any) error {
|
||||
return json.NewDecoder(resp.Body).Decode(obj)
|
||||
}
|
||||
|
||||
// ConvertMapToQueryString convert map to sorted url query string
|
||||
// ConvertMapToQueryString convert map to sorted url query string.
|
||||
// Play: https://go.dev/play/p/jnNt_qoSnRi
|
||||
func ConvertMapToQueryString(param map[string]any) string {
|
||||
if param == nil {
|
||||
return ""
|
||||
|
||||
@@ -92,7 +92,8 @@ func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
|
||||
return client
|
||||
}
|
||||
|
||||
// SendRequest send http request
|
||||
// SendRequest send http request.
|
||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
|
||||
err := validateRequest(request)
|
||||
if err != nil {
|
||||
@@ -128,7 +129,8 @@ func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, err
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// DecodeResponse decode response into target object
|
||||
// DecodeResponse decode response into target object.
|
||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
|
||||
if resp == nil {
|
||||
return errors.New("invalid target param")
|
||||
@@ -203,7 +205,8 @@ func validateRequest(req *HttpRequest) error {
|
||||
}
|
||||
|
||||
// StructToUrlValues convert struct to url valuse,
|
||||
// only convert the field which is exported and has `json` tag
|
||||
// only convert the field which is exported and has `json` tag.
|
||||
// Play: https://go.dev/play/p/pFqMkM40w9z
|
||||
func StructToUrlValues(targetStruct any) url.Values {
|
||||
rv := reflect.ValueOf(targetStruct)
|
||||
rt := reflect.TypeOf(targetStruct)
|
||||
|
||||
99
netutil/http_example_test.go
Normal file
99
netutil/http_example_test.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package netutil
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ExampleHttpClient_SendRequest() {
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(todo.Id)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleHttpClient_DecodeResponse() {
|
||||
request := &HttpRequest{
|
||||
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||
Method: "GET",
|
||||
}
|
||||
|
||||
httpClient := NewHttpClient()
|
||||
resp, err := httpClient.SendRequest(request)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return
|
||||
}
|
||||
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
var todo Todo
|
||||
err = httpClient.DecodeResponse(resp, &todo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(todo.Id)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleStructToUrlValues() {
|
||||
type TodoQuery struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
todoQuery := TodoQuery{
|
||||
Id: 1,
|
||||
Name: "Test",
|
||||
}
|
||||
todoValues := StructToUrlValues(todoQuery)
|
||||
|
||||
fmt.Println(todoValues.Get("id"))
|
||||
fmt.Println(todoValues.Get("name"))
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// Test
|
||||
}
|
||||
|
||||
func ExampleConvertMapToQueryString() {
|
||||
var m = map[string]any{
|
||||
"c": 3,
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
}
|
||||
|
||||
qs := ConvertMapToQueryString(m)
|
||||
|
||||
fmt.Println(qs)
|
||||
|
||||
// Output:
|
||||
// a=1&b=2&c=3
|
||||
}
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetInternalIp return internal ipv4
|
||||
// GetInternalIp return internal ipv4.
|
||||
// Play: https://go.dev/play/p/5mbu-gFp7ei
|
||||
func GetInternalIp() string {
|
||||
addr, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
@@ -26,7 +27,8 @@ func GetInternalIp() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetRequestPublicIp return the requested public ip
|
||||
// GetRequestPublicIp return the requested public ip.
|
||||
// Play: https://go.dev/play/p/kxU-YDc_eBo
|
||||
func GetRequestPublicIp(req *http.Request) string {
|
||||
var ip string
|
||||
for _, ip = range strings.Split(req.Header.Get("X-Forwarded-For"), ",") {
|
||||
@@ -47,7 +49,8 @@ func GetRequestPublicIp(req *http.Request) string {
|
||||
}
|
||||
|
||||
// GetPublicIpInfo return public ip information
|
||||
// return the PublicIpInfo struct
|
||||
// return the PublicIpInfo struct.
|
||||
// Play: https://go.dev/play/p/YDxIfozsRHR
|
||||
func GetPublicIpInfo() (*PublicIpInfo, error) {
|
||||
resp, err := http.Get("http://ip-api.com/json/")
|
||||
if err != nil {
|
||||
@@ -69,7 +72,8 @@ func GetPublicIpInfo() (*PublicIpInfo, error) {
|
||||
return &ip, nil
|
||||
}
|
||||
|
||||
// GetIps return all ipv4 of system
|
||||
// GetIps return all ipv4 of system.
|
||||
// Play: https://go.dev/play/p/NUFfcEmukx1
|
||||
func GetIps() []string {
|
||||
var ips []string
|
||||
|
||||
@@ -89,7 +93,8 @@ func GetIps() []string {
|
||||
return ips
|
||||
}
|
||||
|
||||
// GetMacAddrs get mac address
|
||||
// GetMacAddrs get mac address.
|
||||
// Play: https://go.dev/play/p/Rq9UUBS_Xp1
|
||||
func GetMacAddrs() []string {
|
||||
var macAddrs []string
|
||||
|
||||
@@ -125,7 +130,8 @@ type PublicIpInfo struct {
|
||||
Ip string `json:"query"`
|
||||
}
|
||||
|
||||
// IsPublicIP verify a ip is public or not
|
||||
// IsPublicIP verify a ip is public or not.
|
||||
// Play: https://go.dev/play/p/nmktSQpJZnn
|
||||
func IsPublicIP(IP net.IP) bool {
|
||||
if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {
|
||||
return false
|
||||
@@ -145,7 +151,8 @@ func IsPublicIP(IP net.IP) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsInternalIP verify an ip is intranet or not
|
||||
// IsInternalIP verify an ip is intranet or not.
|
||||
// Play: https://go.dev/play/p/sYGhXbgO4Cb
|
||||
func IsInternalIP(IP net.IP) bool {
|
||||
if IP.IsLoopback() {
|
||||
return true
|
||||
@@ -159,7 +166,8 @@ func IsInternalIP(IP net.IP) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// EncodeUrl encode url
|
||||
// EncodeUrl encode url.
|
||||
// Play: https://go.dev/play/p/bsZ6BRC4uKI
|
||||
func EncodeUrl(urlStr string) (string, error) {
|
||||
URL, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
|
||||
91
netutil/net_example_test.go
Normal file
91
netutil/net_example_test.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func ExampleGetInternalIp() {
|
||||
internalIp := GetInternalIp()
|
||||
|
||||
result := IsInternalIP(net.ParseIP(internalIp))
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleGetPublicIpInfo() {
|
||||
ipInfo, err := GetPublicIpInfo()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result := IsPublicIP(net.ParseIP(ipInfo.Ip))
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleGetRequestPublicIp() {
|
||||
ip := "36.112.24.10"
|
||||
|
||||
request := http.Request{
|
||||
Method: "GET",
|
||||
Header: http.Header{
|
||||
"X-Forwarded-For": {ip},
|
||||
},
|
||||
}
|
||||
publicIp := GetRequestPublicIp(&request)
|
||||
|
||||
fmt.Println(publicIp)
|
||||
|
||||
// Output:
|
||||
// 36.112.24.10
|
||||
}
|
||||
|
||||
func ExampleIsInternalIP() {
|
||||
ip1 := IsInternalIP(net.ParseIP("127.0.0.1"))
|
||||
ip2 := IsInternalIP(net.ParseIP("192.168.0.1"))
|
||||
ip3 := IsInternalIP(net.ParseIP("36.112.24.10"))
|
||||
|
||||
fmt.Println(ip1)
|
||||
fmt.Println(ip2)
|
||||
fmt.Println(ip3)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleIsPublicIP() {
|
||||
ip1 := IsPublicIP(net.ParseIP("127.0.0.1"))
|
||||
ip2 := IsPublicIP(net.ParseIP("192.168.0.1"))
|
||||
ip3 := IsPublicIP(net.ParseIP("36.112.24.10"))
|
||||
|
||||
fmt.Println(ip1)
|
||||
fmt.Println(ip2)
|
||||
fmt.Println(ip3)
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// false
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleEncodeUrl() {
|
||||
urlAddr := "http://www.lancet.com?a=1&b=[2]"
|
||||
|
||||
encodedUrl, err := EncodeUrl(urlAddr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(encodedUrl)
|
||||
|
||||
// Output:
|
||||
// http://www.lancet.com?a=1&b=%5B2%5D
|
||||
}
|
||||
@@ -34,21 +34,24 @@ type RetryFunc func() error
|
||||
// Option is for adding retry config
|
||||
type Option func(*RetryConfig)
|
||||
|
||||
// RetryTimes set times of retry
|
||||
// RetryTimes set times of retry.
|
||||
// Play: https://go.dev/play/p/ssfVeU2SwLO
|
||||
func RetryTimes(n uint) Option {
|
||||
return func(rc *RetryConfig) {
|
||||
rc.retryTimes = n
|
||||
}
|
||||
}
|
||||
|
||||
// RetryDuration set duration of retries
|
||||
// RetryDuration set duration of retries.
|
||||
// Play: https://go.dev/play/p/nk2XRmagfVF
|
||||
func RetryDuration(d time.Duration) Option {
|
||||
return func(rc *RetryConfig) {
|
||||
rc.retryDuration = d
|
||||
}
|
||||
}
|
||||
|
||||
// Context set retry context config
|
||||
// Context set retry context config.
|
||||
// Play: https://go.dev/play/p/xnAOOXv9GkS
|
||||
func Context(ctx context.Context) Option {
|
||||
return func(rc *RetryConfig) {
|
||||
rc.context = ctx
|
||||
@@ -56,7 +59,8 @@ func Context(ctx context.Context) Option {
|
||||
}
|
||||
|
||||
// Retry executes the retryFunc repeatedly until it was successful or canceled by the context
|
||||
// The default times of retries is 5 and the default duration between retries is 3 seconds
|
||||
// The default times of retries is 5 and the default duration between retries is 3 seconds.
|
||||
// Play: https://go.dev/play/p/nk2XRmagfVF
|
||||
func Retry(retryFunc RetryFunc, opts ...Option) error {
|
||||
config := &RetryConfig{
|
||||
retryTimes: DefaultRetryTimes,
|
||||
|
||||
93
retry/retry_example_test.go
Normal file
93
retry/retry_example_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ExampleContext() {
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number > 3 {
|
||||
cancel()
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
Retry(increaseNumber,
|
||||
RetryDuration(time.Microsecond*50),
|
||||
Context(ctx),
|
||||
)
|
||||
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
}
|
||||
|
||||
func ExampleRetryDuration() {
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := Retry(increaseNumber, RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func ExampleRetryTimes() {
|
||||
number := 0
|
||||
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := Retry(increaseNumber, RetryTimes(2))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// function retry.ExampleRetryTimes.func1 run failed after 2 times retry
|
||||
}
|
||||
|
||||
func ExampleRetry() {
|
||||
number := 0
|
||||
increaseNumber := func() error {
|
||||
number++
|
||||
if number == 3 {
|
||||
return nil
|
||||
}
|
||||
return errors.New("error occurs")
|
||||
}
|
||||
|
||||
err := Retry(increaseNumber, RetryDuration(time.Microsecond*50))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(number)
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
@@ -283,6 +283,7 @@ func SplitEx(s, sep string, removeEmptyString bool) []string {
|
||||
}
|
||||
|
||||
// Substring returns a substring of the specified length starting at the specified offset position.
|
||||
// Play: Todo
|
||||
func Substring(s string, offset int, length uint) string {
|
||||
rs := []rune(s)
|
||||
size := len(rs)
|
||||
|
||||
@@ -6,6 +6,7 @@ package xerror
|
||||
|
||||
// Unwrap if err is nil then it returns a valid value
|
||||
// If err is not nil, Unwrap panics with err.
|
||||
// Play: https://go.dev/play/p/w84d7Mb3Afk
|
||||
func Unwrap[T any](val T, err error) T {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
25
xerror/xerror_example_test.go
Normal file
25
xerror/xerror_example_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package xerror
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ExampleUnwrap() {
|
||||
result1 := Unwrap(strconv.Atoi("42"))
|
||||
fmt.Println(result1)
|
||||
|
||||
_, err := strconv.Atoi("4o2")
|
||||
defer func() {
|
||||
v := recover()
|
||||
result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
|
||||
fmt.Println(result2)
|
||||
}()
|
||||
|
||||
Unwrap(strconv.Atoi("4o2"))
|
||||
|
||||
// Output:
|
||||
// 42
|
||||
// true
|
||||
}
|
||||
Reference in New Issue
Block a user