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

Compare commits

..

9 Commits

Author SHA1 Message Date
dudaodong
4959f26003 release v1.4.1 2023-07-31 16:44:44 +08:00
dudaodong
eb683a33d2 doc: update readme file 2023-07-29 16:57:57 +08:00
dudaodong
0e63489e9e doc: update readme file 2023-07-28 17:39:36 +08:00
dudaodong
d9e318550a feat: add new functions to datetime package 2023-07-28 17:25:13 +08:00
dudaodong
993b0e6023 feat: add Join 2023-07-27 20:14:57 +08:00
dudaodong
7cf358a0ec fix: fix CreateDir bug 2023-07-27 18:00:56 +08:00
dudaodong
b85545c584 refactor: clean code 2023-07-27 17:58:57 +08:00
dudaodong
c3c6c92cd4 refactor: clean code 2023-07-27 17:58:40 +08:00
dudaodong
8587abc977 feat: add base64 support for cryptor package 2023-07-27 17:54:26 +08:00
23 changed files with 2115 additions and 687 deletions

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-v1.16-9cf)
[![Release](https://img.shields.io/badge/release-1.4.0-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-1.4.1-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -133,14 +133,24 @@ import "github.com/duke-git/lancet/cryptor"
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesOfbEncrypt)
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesOfbDecrypt)
- [HmacMd5](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacMd5)
- [HmacMd5WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacMd5WithBase64)
- [HmacSha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha1)
- [HmacSha1WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha1WithBase64)
- [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha256)
- [HmacSha256WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha256WithBase64)
- [HmacSha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha512)
- [HmacSha512WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha512WithBase64)
- [Md5String](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5String)
- [Md5StringWithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5StringWithBase64)
- [Md5Byte](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5Byte)
- [Md5ByteWithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5ByteWithBase64)
- [Md5File](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5File)
- [Sha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha1)
- [Sha1WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha1WithBase64)
- [Sha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha256)
- [Sha256WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha256WithBase64)
- [Sha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha512)
- [Sha512WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha512WithBase64)
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#GenerateRsaKey)
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaEncrypt)
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaDecrypt)
@@ -188,6 +198,11 @@ import "github.com/duke-git/lancet/datetime"
- [BetweenSeconds](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BetweenSeconds)
- [DayOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#DayOfYear)
- [IsWeekend](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#IsWeekend)
- [NowDateOrTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NowDateOrTime)
- [Timestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#Timestamp)
- [TimestampMilli](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#TimestampMilli)
- [TimestampMicro](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#TimestampMicro)
- [TimestampNano](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#TimestampNano)
### 5. Fileutil package implements some basic functions for file operations.
@@ -390,6 +405,7 @@ import "github.com/duke-git/lancet/slice"
- [Union](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Union)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#UpdateByIndex)
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Without)
- [Join](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Join)
### 13. Strutil package contains some functions to manipulate string.

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-v1.16-9cf)
[![Release](https://img.shields.io/badge/release-1.4.0-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-1.4.1-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -131,14 +131,25 @@ import "github.com/duke-git/lancet/cryptor"
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesOfbEncrypt)
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesOfbDecrypt)
- [HmacMd5](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacMd5)
- [HmacMd5WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacMd5WithBase64)
md#HmacSha256WithBase64)
- [HmacSha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha1)
- [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha256)
- [HmacSha1WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha1WithBase64)
- [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha256)
- [HmacSha256WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha256WithBase64)
- [HmacSha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha512)
- [HmacSha512WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha512WithBase64)
- [Md5String](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5String)
- [Md5StringWithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5StringWithBase64)
- [Md5Byte](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5Byte)
- [Md5ByteWithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5ByteWithBase64)
- [Md5File](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5File)
- [Sha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha1)
- [Sha1WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha1WithBase64)
- [Sha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha256)
- [Sha256WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha256WithBase64)
- [Sha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha512)
- [Sha512WithBase64](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha512WithBase64)
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#GenerateRsaKey)
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaEncrypt)
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaDecrypt)
@@ -186,6 +197,11 @@ import "github.com/duke-git/lancet/datetime"
- [BetweenSeconds](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#BetweenSeconds)
- [DayOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#DayOfYear)
- [IsWeekend](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#IsWeekend)
- [NowDateOrTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NowDateOrTime)
- [Timestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#Timestamp)
- [TimestampMilli](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#TimestampMilli)
- [TimestampMicro](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#TimestampMicro)
- [TimestampNano](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#TimestampNano)
### 5. fileutil 包支持文件基本操作。
@@ -387,6 +403,7 @@ import "github.com/duke-git/lancet/slice"
- [Union](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Union)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#UpdateByIndex)
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Without)
- [Join](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Join)
### 13. strutil 包含处理字符串的相关函数。

View File

@@ -1,188 +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 {
size := len(key)
if size != 16 && size != 24 && size != 32 {
panic("key length shoud be 16 or 24 or 32")
}
cipher, _ := aes.NewCipher(generateAesKey(key, size))
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))
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 {
size := len(key)
if size != 16 && size != 24 && size != 32 {
panic("key length shoud be 16 or 24 or 32")
}
cipher, _ := aes.NewCipher(generateAesKey(key, size))
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 {
block, _ := aes.NewCipher(key)
if len(encrypted) < aes.BlockSize {
panic("encrypted data is too short")
}
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
}

View File

@@ -1,62 +0,0 @@
package cryptor
import (
"testing"
"github.com/duke-git/lancet/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))
}

View File

@@ -37,6 +37,27 @@ func Md5String(s string) string {
return hex.EncodeToString(h.Sum(nil))
}
// Md5StringWithBase64 return the md5 value of string with base64.
func Md5StringWithBase64(s string) string {
h := md5.New()
h.Write([]byte(s))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
// Md5Byte return the md5 string of byte slice.
func Md5Byte(data []byte) string {
h := md5.New()
h.Write(data)
return hex.EncodeToString(h.Sum(nil))
}
// Md5ByteWithBase64 return the md5 string of byte slice with base64.
func Md5ByteWithBase64(data []byte) string {
h := md5.New()
h.Write(data)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
// Md5File return the md5 value of file
func Md5File(filename string) (string, error) {
if fileInfo, err := os.Stat(filename); err != nil {
@@ -76,6 +97,13 @@ func HmacMd5(data, key string) string {
return hex.EncodeToString(h.Sum([]byte("")))
}
// HmacMd5WithBase64 return the hmac hash of string use md5 with base64.
func HmacMd5WithBase64(data, key string) string {
h := hmac.New(md5.New, []byte(key))
h.Write([]byte(data))
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
}
// HmacSha1 return the hmac hash of string use sha1
func HmacSha1(data, key string) string {
h := hmac.New(sha1.New, []byte(key))
@@ -83,6 +111,13 @@ func HmacSha1(data, key string) string {
return hex.EncodeToString(h.Sum([]byte("")))
}
// HmacSha1WithBase64 return the hmac hash of string use sha1 with base64.
func HmacSha1WithBase64(str, key string) string {
h := hmac.New(sha1.New, []byte(key))
h.Write([]byte(str))
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
}
// HmacSha256 return the hmac hash of string use sha256
func HmacSha256(data, key string) string {
h := hmac.New(sha256.New, []byte(key))
@@ -90,6 +125,13 @@ func HmacSha256(data, key string) string {
return hex.EncodeToString(h.Sum([]byte("")))
}
// HmacSha256WithBase64 return the hmac hash of string use sha256 with base64.
func HmacSha256WithBase64(str, key string) string {
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(str))
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
}
// HmacSha512 return the hmac hash of string use sha512
func HmacSha512(data, key string) string {
h := hmac.New(sha512.New, []byte(key))
@@ -97,6 +139,13 @@ func HmacSha512(data, key string) string {
return hex.EncodeToString(h.Sum([]byte("")))
}
// HmacSha512WithBase64 return the hmac hash of string use sha512 with base64.
func HmacSha512WithBase64(str, key string) string {
h := hmac.New(sha512.New, []byte(key))
h.Write([]byte(str))
return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
}
// Sha1 return the sha1 value (SHA-1 hash algorithm) of string
func Sha1(data string) string {
sha1 := sha1.New()
@@ -104,6 +153,13 @@ func Sha1(data string) string {
return hex.EncodeToString(sha1.Sum([]byte("")))
}
// Sha1WithBase64 return the sha1 value (SHA-1 hash algorithm) of base64 string.
func Sha1WithBase64(str string) string {
sha1 := sha1.New()
sha1.Write([]byte(str))
return base64.StdEncoding.EncodeToString(sha1.Sum([]byte("")))
}
// Sha256 return the sha256 value (SHA256 hash algorithm) of string
func Sha256(data string) string {
sha256 := sha256.New()
@@ -111,9 +167,23 @@ func Sha256(data string) string {
return hex.EncodeToString(sha256.Sum([]byte("")))
}
// Sha256WithBase64 return the sha256 value (SHA256 hash algorithm) of base64 string.
func Sha256WithBase64(str string) string {
sha256 := sha256.New()
sha256.Write([]byte(str))
return base64.StdEncoding.EncodeToString(sha256.Sum([]byte("")))
}
// Sha512 return the sha512 value (SHA512 hash algorithm) of string
func Sha512(data string) string {
sha512 := sha512.New()
sha512.Write([]byte(data))
return hex.EncodeToString(sha512.Sum([]byte("")))
}
// Sha512WithBase64 return the sha512 value (SHA512 hash algorithm) of base64 string.
func Sha512WithBase64(str string) string {
sha512 := sha512.New()
sha512.Write([]byte(str))
return base64.StdEncoding.EncodeToString(sha512.Sum([]byte("")))
}

View File

@@ -21,6 +21,22 @@ func TestMd5String(t *testing.T) {
assert.Equal("5d41402abc4b2a76b9719d911017c592", Md5String("hello"))
}
func TestMd5StringWithBase64(t *testing.T) {
assert := internal.NewAssert(t, "TestMd5StringWithBase64")
assert.Equal("XUFAKrxLKna5cZ2REBfFkg==", Md5StringWithBase64("hello"))
}
func TestMd5Byte(t *testing.T) {
assert := internal.NewAssert(t, "TestMd5Byte")
data := []byte{'a'}
assert.Equal("0cc175b9c0f1b6a831c399e269772661", Md5Byte(data))
}
func TestMd5ByteWithBase64(t *testing.T) {
assert := internal.NewAssert(t, "TestMd5ByteWithBase64")
assert.Equal("XUFAKrxLKna5cZ2REBfFkg==", Md5ByteWithBase64([]byte("hello")))
}
func TestMd5File(t *testing.T) {
fileMd5, err := Md5File("./basic.go")
assert := internal.NewAssert(t, "TestMd5File")
@@ -33,6 +49,11 @@ func TestHmacMd5(t *testing.T) {
assert.Equal("5f4c9faaff0a1ad3007d9ddc06abe36d", HmacMd5("hello world", "12345"))
}
func TestHmacMd5WithBase64(t *testing.T) {
assert := internal.NewAssert(t, "TestHmacMd5WithBase64")
assert.Equal("6DQwbquJLYclJdSRinpjmg==", HmacMd5WithBase64("hello", "12345"))
}
func TestHmacSha1(t *testing.T) {
s := "hello world"
key := "12345"
@@ -43,6 +64,16 @@ func TestHmacSha1(t *testing.T) {
assert.Equal(expected, hmacSha1)
}
func TestHmacSha1WithBase64(t *testing.T) {
s := "hello"
key := "12345"
hmacSha1 := HmacSha1WithBase64(s, key)
expected := "XGqdsMzLkuNu0DI/0Jt/k23prOA="
assert := internal.NewAssert(t, "TestHmacSha1")
assert.Equal(expected, hmacSha1)
}
func TestHmacSha256(t *testing.T) {
s := "hello world"
key := "12345"
@@ -53,6 +84,16 @@ func TestHmacSha256(t *testing.T) {
assert.Equal(expected, hmacSha256)
}
func TestHmacSha256WithBase64(t *testing.T) {
str := "hello"
key := "12345"
hms := HmacSha256WithBase64(str, key)
expected := "MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU="
assert := internal.NewAssert(t, "TestHmacSha256WithBase64")
assert.Equal(expected, hms)
}
func TestHmacSha512(t *testing.T) {
s := "hello world"
key := "12345"
@@ -63,6 +104,16 @@ func TestHmacSha512(t *testing.T) {
assert.Equal(expected, hmacSha512)
}
func TestHmacSha512WithBase64(t *testing.T) {
str := "hello"
key := "12345"
hms := HmacSha512WithBase64(str, key)
expected := "3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A=="
assert := internal.NewAssert(t, "TestHmacSha512WithBase64")
assert.Equal(expected, hms)
}
func TestSha1(t *testing.T) {
s := "hello world"
sha1 := Sha1(s)
@@ -72,6 +123,14 @@ func TestSha1(t *testing.T) {
assert.Equal(expected, sha1)
}
func TestSha1WithBase64(t *testing.T) {
str := Sha1WithBase64("hello")
expected := "qvTGHdzF6KLavt4PO0gs2a6pQ00="
assert := internal.NewAssert(t, "TestSha1WithBase64")
assert.Equal(expected, str)
}
func TestSha256(t *testing.T) {
s := "hello world"
sha256 := Sha256(s)
@@ -81,6 +140,14 @@ func TestSha256(t *testing.T) {
assert.Equal(expected, sha256)
}
func TestSha256WithBase64(t *testing.T) {
str := Sha256WithBase64("hello")
expected := "LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
assert := internal.NewAssert(t, "TestSha256WithBase64")
assert.Equal(expected, str)
}
func TestSha512(t *testing.T) {
s := "hello world"
sha512 := Sha512(s)
@@ -89,3 +156,11 @@ func TestSha512(t *testing.T) {
assert := internal.NewAssert(t, "TestSha512")
assert.Equal(expected, sha512)
}
func TestSha512WithBase64(t *testing.T) {
str := Sha512WithBase64("hello")
expected := "m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw=="
assert := internal.NewAssert(t, "TestSha512WithBase64")
assert.Equal(expected, str)
}

463
cryptor/crypto.go Normal file
View File

@@ -0,0 +1,463 @@
// 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
func AesEcbEncrypt(data, key []byte) []byte {
size := len(key)
if size != 16 && size != 24 && size != 32 {
panic("key length shoud be 16 or 24 or 32")
}
cipher, _ := aes.NewCipher(generateAesKey(key, size))
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))
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 {
size := len(key)
if size != 16 && size != 24 && size != 32 {
panic("key length shoud be 16 or 24 or 32")
}
cipher, _ := aes.NewCipher(generateAesKey(key, size))
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 {
block, _ := aes.NewCipher(key)
if len(encrypted) < aes.BlockSize {
panic("encrypted data is too short")
}
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
}
// DesEcbEncrypt encrypt data with key use DES ECB algorithm
// len(key) should be 8
func DesEcbEncrypt(data, key []byte) []byte {
cipher, _ := des.NewCipher(generateDesKey(key))
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))
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
}
// 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)
}
pem.Encode(file, &block)
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("rsa_public.pem")
file, err = os.Create(pubKeyFile)
if err != nil {
return err
}
pem.Encode(file, &block)
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())
file.Read(buf)
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()
file.Read(buf)
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/crypto_test.go Normal file
View File

@@ -0,0 +1,130 @@
package cryptor
import (
"testing"
"github.com/duke-git/lancet/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))
}

View File

@@ -1,178 +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 {
cipher, _ := des.NewCipher(generateDesKey(key))
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))
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
}

View File

@@ -1,62 +0,0 @@
package cryptor
import (
"testing"
"github.com/duke-git/lancet/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))
}

View File

@@ -1,118 +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)
}
pem.Encode(file, &block)
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("rsa_public.pem")
file, err = os.Create(pubKeyFile)
if err != nil {
return err
}
pem.Encode(file, &block)
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())
file.Read(buf)
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()
file.Read(buf)
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
}

View File

@@ -1,20 +0,0 @@
package cryptor
import (
"testing"
"github.com/duke-git/lancet/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))
}

View File

@@ -3,7 +3,7 @@
// Package datetime implements some functions to format date and time.
// Note:
// 1. `format` param in FormatTimeToStr function should be as flow:
// 1. `format` param in FormatTimeToStr function should be as flow (case no sensitive):
// "yyyy-mm-dd hh:mm:ss"
// "yyyy-mm-dd hh:mm"
// "yyyy-mm-dd hh"
@@ -18,14 +18,20 @@
// "yyyy/mm"
// "mm/dd"
// "dd/mm/yy hh:mm:ss"
// "yyyymmdd"
// "mmddyy"
// "yyyy"
// "yy"
// "mm"
// "hh:mm:ss"
// "hh:mm"
// "mm:ss"
package datetime
import (
"fmt"
"strings"
"time"
)
@@ -47,9 +53,13 @@ func init() {
"yyyy/mm": "2006/01",
"mm/dd": "01/02",
"dd/mm/yy hh:mm:ss": "02/01/06 15:04:05",
"yyyymmdd": "20060102",
"mmddyy": "010206",
"yyyy": "2006",
"yy": "06",
"mm": "01",
"hh:mm:ss": "15:04:05",
"hh:mm": "15:04",
"mm:ss": "04:05",
}
}
@@ -102,18 +112,39 @@ func GetNightTimestamp() int64 {
}
// FormatTimeToStr convert time to string
func FormatTimeToStr(t time.Time, format string) string {
return t.Format(timeFormat[format])
func FormatTimeToStr(t time.Time, format string, timezone ...string) string {
tf, ok := timeFormat[strings.ToLower(format)]
if !ok {
return ""
}
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return ""
}
return t.In(loc).Format(tf)
}
return t.Format(tf)
}
// FormatStrToTime convert string to time
func FormatStrToTime(str, format string) (time.Time, error) {
v, ok := timeFormat[format]
func FormatStrToTime(str, format string, timezone ...string) (time.Time, error) {
tf, ok := timeFormat[strings.ToLower(format)]
if !ok {
return time.Time{}, fmt.Errorf("format %s not found", format)
return time.Time{}, fmt.Errorf("format %s not support", format)
}
return time.Parse(v, str)
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return time.Time{}, err
}
return time.ParseInLocation(tf, str, loc)
}
return time.Parse(tf, str)
}
// BeginOfMinute return beginning minute time of day
@@ -210,3 +241,83 @@ func DayOfYear(t time.Time) int {
func IsWeekend(t time.Time) bool {
return time.Saturday == t.Weekday() || time.Sunday == t.Weekday()
}
// NowDateOrTime return current datetime with specific format and timezone.
func NowDateOrTime(format string, timezone ...string) string {
tf, ok := timeFormat[strings.ToLower(format)]
if !ok {
return ""
}
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return ""
}
return time.Now().In(loc).Format(tf)
}
return time.Now().Format(tf)
}
// Timestamp return current second timestamp.
func Timestamp(timezone ...string) int64 {
t := time.Now()
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return 0
}
t = t.In(loc)
}
return t.Unix()
}
// TimestampMilli return current mill second timestamp.
func TimestampMilli(timezone ...string) int64 {
t := time.Now()
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return 0
}
t = t.In(loc)
}
return int64(time.Nanosecond) * t.UnixNano() / int64(time.Millisecond)
}
// TimestampMicro return current micro second timestamp.
func TimestampMicro(timezone ...string) int64 {
t := time.Now()
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return 0
}
t = t.In(loc)
}
return int64(time.Nanosecond) * t.UnixNano() / int64(time.Microsecond)
}
// TimestampNano return current nano second timestamp.
func TimestampNano(timezone ...string) int64 {
t := time.Now()
if timezone != nil && timezone[0] != "" {
loc, err := time.LoadLocation(timezone[0])
if err != nil {
return 0
}
t = t.In(loc)
}
return t.UnixNano()
}

View File

@@ -298,3 +298,38 @@ func TestIsWeekend(t *testing.T) {
result2 := IsWeekend(date2)
assert.Equal(false, result2)
}
func TestNowDateOrTime(t *testing.T) {
t.Parallel()
formats := []string{
"yyyy-mm-dd hh:mm:ss",
"yyyy-mm-dd",
"dd-mm-yy hh:mm:ss",
"yyyy/mm/dd hh:mm:ss",
"hh:mm:ss",
"yyyy/mm",
"yyyy-mm-dd hh",
}
for i := 0; i < len(formats); i++ {
result := NowDateOrTime(formats[i], "UTC")
t.Log(result)
}
}
func TestTimestamp(t *testing.T) {
t.Parallel()
ts1 := Timestamp()
t.Log(ts1)
ts2 := TimestampMilli()
t.Log(ts2)
ts3 := TimestampMicro()
t.Log(ts3)
ts4 := TimestampNano()
t.Log(ts4)
}

View File

@@ -6,10 +6,8 @@ Package cryptor contains some functions for data encryption and decryption. Supp
## Source:
- [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/crypto.go](https://github.com/duke-git/lancet/blob/v1/cryptor/crypto.go)
<div STYLE="page-break-after: always;"></div>
@@ -46,14 +44,24 @@ import (
- [DesOfbEncrypt](#DesOfbEncrypt)
- [DesOfbDecrypt](#DesOfbDecrypt)
- [HmacMd5](#HmacMd5)
- [HmacMd5WithBase64](#HmacMd5WithBase64)
- [HmacSha1](#HmacSha1)
- [HmacSha1WithBase64](#HmacSha1WithBase64)
- [HmacSha256](#HmacSha256)
- [HmacSha256WithBase64](#HmacSha256WithBase64)
- [HmacSha512](#HmacSha512)
- [HmacSha512WithBase64](#HmacSha512WithBase64)
- [Md5String](#Md5String)
- [Md5StringWithBase64](#Md5StringWithBase64)
- [Md5Byte](#Md5Byte)
- [Md5ByteWithBase64](#Md5ByteWithBase64)
- [Md5File](#Md5File)
- [Sha1](#Sha1)
- [Sha1WithBase64](#Sha1WithBase64)
- [Sha256](#Sha256)
- [Sha256WithBase64](#Sha256WithBase64)
- [Sha512](#Sha512)
- [Sha512WithBase64](#Sha512WithBase64)
- [GenerateRsaKey](#GenerateRsaKey)
- [RsaEncrypt](#RsaEncrypt)
- [RsaDecrypt](#RsaDecrypt)
@@ -664,6 +672,32 @@ func main() {
}
```
### <span id="HmacMd5WithBase64">HmacMd5WithBase64</span>
<p>Return the hmac hash of string use md5 with base64.</p>
<b>Signature:</b>
```go
func HmacMd5WithBase64(data, key string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
s := cryptor.HmacMd5WithBase64("hello", "12345"))
fmt.Println(s) //6DQwbquJLYclJdSRinpjmg==
}
```
### <span id="HmacSha1">HmacSha1</span>
<p>Get the sha1 hmac hash of string.</p>
@@ -689,6 +723,37 @@ func main() {
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
}
```
### <span id="HmacSha1WithBase64">HmacSha1WithBase64</span>
<p>Return the hmac hash of string use sha1 with base64.</p>
<b>Signature:</b>
```go
func HmacSha1WithBase64(str, key string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
str := "hello"
key := "12345"
hms := cryptor.HmacSha1WithBase64(str, key)
fmt.Println(hms)
// Output:
// XGqdsMzLkuNu0DI/0Jt/k23prOA=
}
```
### <span id="HmacSha256">HmacSha256</span>
@@ -716,6 +781,38 @@ func main() {
}
```
### <span id="HmacSha256WithBase64">HmacSha256WithBase64</span>
<p>Return the hmac hash of string use sha256 with base64.</p>
<b>Signature:</b>
```go
func HmacSha256WithBase64(str, key string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
str := "hello"
key := "12345"
hms := cryptor.HmacSha256WithBase64(str, key)
fmt.Println(hms)
// Output:
// MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU=
}
```
### <span id="HmacSha512">HmacSha512</span>
<p>Get the sha512 hmac hash of string.</p>
@@ -742,6 +839,38 @@ func main() {
}
```
### <span id="HmacSha512WithBase64">HmacSha512WithBase64</span>
<p>Return the hmac hash of string use sha512 with base64.</p>
<b>Signature:</b>
```go
func HmacSha512WithBase64(str, key string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
str := "hello"
key := "12345"
hms := cryptor.HmacSha512WithBase64(str, key)
fmt.Println(hms)
// Output:
// 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A==
}
```
### <span id="Md5String">Md5String</span>
<p>Get the md5 value of string.</p>
@@ -768,6 +897,93 @@ func main() {
}
```
### <span id="Md5StringWithBase64">Md5StringWithBase64</span>
<p>Return the md5 value of string with base64.</p>
<b>Signature:</b>
```go
func Md5StringWithBase64(s string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
md5Str := cryptor.Md5StringWithBase64("hello")
fmt.Println(md5Str)
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
}
```
### <span id="Md5Byte">Md5Byte</span>
<p>Return the md5 string of byte slice.</p>
<b>Signature:</b>
```go
func Md5Byte(data []byte) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
md5Str := cryptor.Md5Byte([]byte{'a'})
fmt.Println(md5Str)
// Output:
// 0cc175b9c0f1b6a831c399e269772661
}
```
### <span id="Md5ByteWithBase64">Md5ByteWithBase64</span>
<p>Return the md5 string of byte slice with base64.</p>
<b>Signature:</b>
```go
func Md5ByteWithBase64(data []byte) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
md5Str := cryptor.Md5ByteWithBase64([]byte("hello"))
fmt.Println(md5Str)
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
}
```
### <span id="Md5File">Md5File</span>
<p>Get the md5 value of file.</p>
@@ -820,6 +1036,35 @@ func main() {
}
```
### <span id="Sha1WithBase64">Sha1WithBase64</span>
<p>Return the sha1 value (SHA-1 hash algorithm) of base64 string.</p>
<b>Signature:</b>
```go
func Sha1WithBase64(str string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
result := cryptor.Sha1WithBase64("hello")
fmt.Println(result)
// Output:
// qvTGHdzF6KLavt4PO0gs2a6pQ00=
}
```
### <span id="Sha256">Sha256</span>
<p>Get the sha256 value of string.</p>
@@ -846,6 +1091,35 @@ func main() {
}
```
### <span id="Sha256WithBase64">Sha256WithBase64</span>
<p>Return the sha256 value (SHA256 hash algorithm) of base64 string.</p>
<b>Signature:</b>
```go
func Sha256WithBase64(str string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
result := cryptor.Sha256WithBase64("hello")
fmt.Println(result)
// Output:
// LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
}
```
### <span id="Sha512">Sha512</span>
<p>Get the sha512 value of string.</p>
@@ -872,6 +1146,35 @@ func main() {
}
```
### <span id="Sha512WithBase64">Sha512WithBase64</span>
<p>Get the sha512 value of string with base64.</p>
<b>Signature:</b>
```go
func Sha512WithBase64(str string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
result := cryptor.Sha512WithBase64("hello")
fmt.Println(result)
// Output:
// m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==
}
```
### <span id="GenerateRsaKey">GenerateRsaKey</span>
<p>Create the rsa public and private key file in current directory.</p>

View File

@@ -6,10 +6,8 @@ cryptor 加密包支持数据加密和解密,获取 md5hash 值。支持 ba
## 源码:
- [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/crypto.go](https://github.com/duke-git/lancet/blob/v1/cryptor/crypto.go)
<div STYLE="page-break-after: always;"></div>
@@ -47,13 +45,22 @@ import (
- [DesOfbDecrypt](#DesOfbDecrypt)
- [HmacMd5](#HmacMd5)
- [HmacSha1](#HmacSha1)
- [HmacSha1WithBase64](#HmacSha1WithBase64)
- [HmacSha256](#HmacSha256)
- [HmacSha256WithBase64](#HmacSha256WithBase64)
- [HmacSha512](#HmacSha512)
- [HmacSha512WithBase64](#HmacSha512WithBase64)
- [Md5String](#Md5String)
- [Md5StringWithBase64](#Md5StringWithBase64)
- [Md5Byte](#Md5Byte)
- [Md5ByteWithBase64](#Md5ByteWithBase64)
- [Md5File](#Md5File)
- [Sha1](#Sha1)
- [Sha1WithBase64](#Sha1WithBase64)
- [Sha256](#Sha256)
- [Sha256WithBase64](#Sha256WithBase64)
- [Sha512](#Sha512)
- [Sha512WithBase64](#Sha512WithBase64)
- [GenerateRsaKey](#GenerateRsaKey)
- [RsaEncrypt](#RsaEncrypt)
- [RsaDecrypt](#RsaDecrypt)
@@ -663,6 +670,32 @@ func main() {
}
```
### <span id="HmacMd5WithBase64">HmacMd5WithBase64</span>
<p>获取字符串md5 hmac base64值.</p>
<b>函数签名:</b>
```go
func HmacMd5WithBase64(data, key string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
s := cryptor.HmacMd5WithBase64("hello", "12345"))
fmt.Println(s) //6DQwbquJLYclJdSRinpjmg==
}
```
### <span id="HmacSha1">HmacSha1</span>
<p>获取字符串sha1 hmac值</p>
@@ -689,17 +722,17 @@ func main() {
}
```
### <span id="HmacSha256">HmacSha256</span>
### <span id="HmacSha1WithBase64">HmacSha1WithBase64</span>
<p>获取字符串sha256 hmac值</p>
<p>获取字符串sha1 base64值。</p>
<b>函数签名:</b>
```go
func HmacSha256(data, key string) string
func HmacSha1WithBase64(str, key string) string
```
<b>列子:</b>
<b>实例:</b>
```go
package main
@@ -710,22 +743,93 @@ import (
)
func main() {
s := cryptor.HmacSha256("hello world", "12345"))
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
str := "hello"
key := "12345"
hms := cryptor.HmacSha1WithBase64(str, key)
fmt.Println(hms)
// Output:
// XGqdsMzLkuNu0DI/0Jt/k23prOA=
}
```
### <span id="HmacSha256">HmacSha256</span>
<p>获取字符串sha256 hmac值。</p>
<b>函数签名:</b>
```go
func HmacSha256(str, key string) string
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
str := "hello"
key := "12345"
hms := cryptor.HmacSha256(str, key)
fmt.Println(hms)
// Output:
// 315bb93c4e989862ba09cb62e05d73a5f376cb36f0d786edab0c320d059fde75
}
```
### <span id="HmacSha256WithBase64">HmacSha256WithBase64</span>
<p>获取字符串sha256 hmac base64值。</p>
<b>函数签名:</b>
```go
func HmacSha256WithBase64(str, key string) string
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
str := "hello"
key := "12345"
hms := cryptor.HmacSha256WithBase64(str, key)
fmt.Println(hms)
// Output:
// MVu5PE6YmGK6Ccti4F1zpfN2yzbw14btqwwyDQWf3nU=
}
```
### <span id="HmacSha512">HmacSha512</span>
<p>获取字符串sha512 hmac值</p>
<p>获取字符串sha512 hmac值</p>
<b>函数签名:</b>
```go
func HmacSha512(data, key string) string
func HmacSha512(str, key string) string
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -736,23 +840,28 @@ import (
)
func main() {
s := cryptor.HmacSha512("hello world", "12345"))
fmt.Println(s)
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
str := "hello"
key := "12345"
hms := cryptor.HmacSha512(str, key)
fmt.Println(hms)
// Output:
// dd8f1290a9dd23d354e2526d9a2e9ce8cffffdd37cb320800d1c6c13d2efc363288376a196c5458daf53f8e1aa6b45a6d856303d5c0a2064bff9785861d48cfc
}
```
### <span id="Md5String">Md5String</span>
### <span id="HmacSha512WithBase64">HmacSha512WithBase64</span>
<p>获取字符串md5值</p>
<p>获取字符串sha512 hmac base64值。</p>
<b>函数签名:</b>
```go
func Md5String(s string) string
func HmacSha512WithBase64(str, key string) string
```
<b>列子:</b>
<b>实例:</b>
```go
package main
@@ -763,14 +872,139 @@ import (
)
func main() {
s := cryptor.Md5String("hello"))
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
str := "hello"
key := "12345"
hms := cryptor.HmacSha512WithBase64(str, key)
fmt.Println(hms)
// Output:
// 3Y8SkKndI9NU4lJtmi6c6M///dN8syCADRxsE9Lvw2Mog3ahlsVFja9T+OGqa0Wm2FYwPVwKIGS/+XhYYdSM/A==
}
```
### <span id="Md5String">Md5String</span>
<p>获取字符串md5值。</p>
<b>函数签名:</b>
```go
func Md5String(str string) string
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
str := "hello"
md5Str := cryptor.Md5String(str)
fmt.Println(md5Str)
// Output:
// 5d41402abc4b2a76b9719d911017c592
}
```
### <span id="Md5StringWithBase64">Md5StringWithBase64</span>
<p>获取字符串md5 base64值。</p>
<b>函数签名:</b>
```go
func Md5StringWithBase64(s string) string
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
md5Str := cryptor.Md5StringWithBase64("hello")
fmt.Println(md5Str)
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
}
```
### <span id="Md5Byte">Md5Byte</span>
<p>获取byte slice的md5值。</p>
<b>函数签名:</b>
```go
func Md5Byte(data []byte) string
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
md5Str := cryptor.Md5Byte([]byte{'a'})
fmt.Println(md5Str)
// Output:
// 0cc175b9c0f1b6a831c399e269772661
}
```
### <span id="Md5ByteWithBase64">Md5ByteWithBase64</span>
<p>获取byte slice的md5 base64值。</p>
<b>函数签名:</b>
```go
func Md5ByteWithBase64(data []byte) string
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
md5Str := cryptor.Md5ByteWithBase64([]byte("hello"))
fmt.Println(md5Str)
// Output:
// XUFAKrxLKna5cZ2REBfFkg==
}
```
### <span id="Md5File">Md5File</span>
<p>获取文件md5值.</p>
<p>获取文件md5值</p>
<b>函数签名:</b>
@@ -778,7 +1012,7 @@ func main() {
func Md5File(filepath string) (string, error)
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -796,15 +1030,15 @@ func main() {
### <span id="Sha1">Sha1</span>
<p>获取字符串sha1值</p>
<p>获取字符串sha1值</p>
<b>函数签名:</b>
```go
func Sha1(data string) string
func Sha1(str string) string
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -815,22 +1049,56 @@ import (
)
func main() {
s := cryptor.Sha1("hello world"))
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
str := "hello"
result := cryptor.Sha1(str)
fmt.Println(result)
// Output:
// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
}
```
### <span id="Sha1WithBase64">Sha1WithBase64</span>
<p>获取字符串sha1 base64值。</p>
<b>函数签名:</b>
```go
func Sha1WithBase64(str string) string
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
result := cryptor.Sha1WithBase64("hello")
fmt.Println(result)
// Output:
// qvTGHdzF6KLavt4PO0gs2a6pQ00=
}
```
### <span id="Sha256">Sha256</span>
<p>获取字符串sha256值</p>
<p>获取字符串sha256值</p>
<b>函数签名:</b>
```go
func Sha256(data string) string
func Sha256(str string) string
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -841,22 +1109,56 @@ import (
)
func main() {
s := cryptor.Sha256("hello world"))
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
str := "hello"
result := cryptor.Sha256(str)
fmt.Println(result)
// Output:
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
}
```
### <span id="Sha256WithBase64">Sha256WithBase64</span>
<p>获取字符串sha256 base64值。</p>
<b>函数签名:</b>
```go
func Sha256WithBase64(str string) string
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
result := cryptor.Sha256WithBase64("hello")
fmt.Println(result)
// Output:
// LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
}
```
### <span id="Sha512">Sha512</span>
<p>获取字符串sha512值</p>
<p>获取字符串sha512值</p>
<b>函数签名:</b>
```go
func Sha512(data string) string
func Sha512(str string) string
```
<b>列子:</b>
<b>示例:</b>
```go
package main
@@ -867,8 +1169,42 @@ import (
)
func main() {
s := cryptor.Sha512("hello world"))
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
str := "hello"
result := cryptor.Sha512(str)
fmt.Println(result)
// Output:
// 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
}
```
### <span id="Sha512WithBase64">Sha512WithBase64</span>
<p>获取字符串sha512 base64值。</p>
<b>函数签名:</b>
```go
func Sha512WithBase64(str string) string
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/cryptor"
)
func main() {
result := cryptor.Sha512WithBase64("hello")
fmt.Println(result)
// Output:
// m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==
}
```
@@ -958,7 +1294,7 @@ func main() {
if err != nil {
fmt.Println(err)
}
data := []byte("hello world")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")

View File

@@ -57,6 +57,11 @@ import (
- [BetweenSeconds](#BetweenSeconds)
- [DayOfYear](#DayOfYear)
- [IsWeekend](#IsWeekend)
- [NowDateOrTime](#NowDateOrTime)
- [Timestamp](#Timestamp)
- [TimestampMilli](#TimestampMilli)
- [TimestampMicro](#TimestampMicro)
- [TimestampNano](#TimestampNano)
<div STYLE="page-break-after: always;"></div>
@@ -64,7 +69,7 @@ import (
## Note:
1. 'format' string param in func FormatTimeToStr and FormatStrToTime function should be one of flows:
1. In below functions, the `format` string param should be one of flows value (case no sensitive):
- yyyy-mm-dd hh:mm:ss
- yyyy-mm-dd hh:mm
@@ -75,14 +80,18 @@ import (
- dd-mm-yy hh:mm:ss
- yyyy/mm/dd hh:mm:ss
- yyyy/mm/dd hh:mm
- yyyy-mm-dd hh
- yyyy/mm/dd hh
- yyyy/mm/dd
- yyyy/mm
- mm/dd
- dd/mm/yy hh:mm:ss
- yyyymmdd
- mmddyy
- yyyy
- yy
- mm
- hh:mm:ss
- hh:mm
- mm:ss
### <span id="AddDay">AddDay</span>
@@ -1036,7 +1045,6 @@ func main() {
}
```
### <span id="DayOfYear">DayOfYear</span>
<p>Returns which day of the year the parameter date `t` is.</p>
@@ -1157,3 +1165,198 @@ func main() {
// false
}
```
### <span id="IsWeekend">IsWeekend</span>
<p>Checks if passed time is weekend or not.</p>
<b>Signature:</b>
```go
func IsWeekend(t time.Time) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
date1 := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local)
date2 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local)
date3 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local)
result1 := datetime.IsWeekend(date1)
result2 := datetime.IsWeekend(date2)
result3 := datetime.IsWeekend(date3)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// true
// true
// false
}
```
### <span id="NowDateOrTime">NowDateOrTime</span>
<p>Return current datetime with specific format and timezone.</p>
<b>Signature:</b>
```go
func NowDateOrTime(format string, timezone ...string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
result1 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss")
result2 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss", "EST")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 2023-07-26 15:01:30
// 2023-07-26 02:01:30
}
```
### <span id="Timestamp">Timestamp</span>
<p>Return current second timestamp.</p>
<b>Signature:</b>
```go
func Timestamp(timezone ...string) int64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.Timestamp()
fmt.Println(ts)
// Output:
// 1690363051
}
```
### <span id="TimestampMilli">TimestampMilli</span>
<p>Return current mill second timestamp.</p>
<b>Signature:</b>
```go
func TimestampMilli(timezone ...string) int64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.TimestampMilli()
fmt.Println(ts)
// Output:
// 1690363051331
}
```
### <span id="TimestampMicro">TimestampMicro</span>
<p>Return current micro second timestamp.</p>
<b>Signature:</b>
```go
func TimestampMicro(timezone ...string) int64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.TimestampMicro()
fmt.Println(ts)
// Output:
// 1690363051331784
}
```
### <span id="TimestampNano">TimestampNano</span>
<p>Return current nano second timestamp.</p>
<b>Signature:</b>
```go
func TimestampNano(timezone ...string) int64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.TimestampNano()
fmt.Println(ts)
// Output:
// 1690363051331788000
}
```

View File

@@ -57,7 +57,11 @@ import (
- [BetweenSeconds](#BetweenSeconds)
- [DayOfYear](#DayOfYear)
- [IsWeekend](#IsWeekend)
- [NowDateOrTime](#NowDateOrTime)
- [Timestamp](#Timestamp)
- [TimestampMilli](#TimestampMilli)
- [TimestampMicro](#TimestampMicro)
- [TimestampNano](#TimestampNano)
<div STYLE="page-break-after: always;"></div>
@@ -65,7 +69,7 @@ import (
## 注:
1. 方法 FormatTimeToStr 和 FormatStrToTime 中的 format 参数值需要传以下类型之一:
1. 函数中`format`参数值需要传以下值之一 (忽略大小写):
- yyyy-mm-dd hh:mm:ss
- yyyy-mm-dd hh:mm
@@ -76,14 +80,18 @@ import (
- dd-mm-yy hh:mm:ss
- yyyy/mm/dd hh:mm:ss
- yyyy/mm/dd hh:mm
- yyyy-mm-dd hh
- yyyy/mm/dd hh
- yyyy/mm/dd
- yyyy/mm
- mm/dd
- dd/mm/yy hh:mm:ss
- yyyymmdd
- mmddyy
- yyyy
- yy
- mm
- hh:mm:ss
- hh:mm
- mm:ss
### <span id="AddDay">AddDay</span>
@@ -1077,3 +1085,198 @@ func main() {
// 0
}
```
### <span id="IsWeekend">IsWeekend</span>
<p>判断日期是否是周末。</p>
<b>函数签名:</b>
```go
func IsWeekend(t time.Time) bool
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
date1 := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local)
date2 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local)
date3 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local)
result1 := datetime.IsWeekend(date1)
result2 := datetime.IsWeekend(date2)
result3 := datetime.IsWeekend(date3)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// true
// true
// false
}
```
### <span id="NowDateOrTime">NowDateOrTime</span>
<p>根据指定的格式和时区返回当前时间字符串。</p>
<b>函数签名:</b>
```go
func NowDateOrTime(format string, timezone ...string) string
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
result1 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss")
result2 := datetime.NowDateOrTime("yyyy-mm-dd hh:mm:ss", "EST")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 2023-07-26 15:01:30
// 2023-07-26 02:01:30
}
```
### <span id="Timestamp">Timestamp</span>
<p>返回当前秒级时间戳。</p>
<b>函数签名:</b>
```go
func Timestamp(timezone ...string) int64
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.Timestamp()
fmt.Println(ts)
// Output:
// 1690363051
}
```
### <span id="TimestampMilli">TimestampMilli</span>
<p>返回当前毫秒级时间戳。</p>
<b>函数签名:</b>
```go
func TimestampMilli(timezone ...string) int64
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.TimestampMilli()
fmt.Println(ts)
// Output:
// 1690363051331
}
```
### <span id="TimestampMicro">TimestampMicro</span>
<p>返回当前微秒级时间戳。</p>
<b>函数签名:</b>
```go
func TimestampMicro(timezone ...string) int64
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.TimestampMicro()
fmt.Println(ts)
// Output:
// 1690363051331784
}
```
### <span id="TimestampNano">TimestampNano</span>
<p>返回当前纳秒级时间戳。</p>
<b>函数签名:</b>
```go
func TimestampNano(timezone ...string) int64
```
<b>实例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/datetime"
)
func main() {
ts := datetime.TimestampNano()
fmt.Println(ts)
// Output:
// 1690363051331788000
}
```

View File

@@ -62,6 +62,7 @@ import (
- [Union](#Union)
- [UpdateByIndex](#UpdateByIndex)
- [Without](#Without)
- [Join](#Join)
<div STYLE="page-break-after: always;"></div>
@@ -1172,3 +1173,36 @@ func main() {
fmt.Println(res) //[]int{3, 4, 5}
}
```
### <span id="Join">Join</span>
<p>Join the slice item with specify separator.</p>
<b>Signature:</b>
```go
func Join(slice interface{}, separator string) string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Join(nums, ",")
result2 := slice.Join(nums, "-")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 1,2,3,4,5
// 1-2-3-4-5
}
```

View File

@@ -62,6 +62,8 @@ import (
- [Union](#Union)
- [UpdateByIndex](#UpdateByIndex)
- [Without](#Without)
- [Join](#Join)
<div STYLE="page-break-after: always;"></div>
@@ -1168,3 +1170,36 @@ func main() {
fmt.Println(res) //[]int{3, 4, 5}
}
```
### <span id="Join">Join</span>
<p>用指定的分隔符链接切片元素。</p>
<b>函数签名:</b>
```go
func Join(slice interface{}, separator string) string
```
<b>示例:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Join(nums, ",")
result2 := slice.Join(nums, "-")
fmt.Println(result1)
fmt.Println(result2)
// Output:
// 1,2,3,4,5
// 1-2-3-4-5
}
```

View File

@@ -50,7 +50,7 @@ func CreateFile(path string) bool {
// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/
func CreateDir(absPath string) error {
return os.MkdirAll(path.Dir(absPath), os.ModePerm)
return os.MkdirAll(absPath, os.ModePerm)
}
// IsDir checks if the path is directory or not

View File

@@ -968,3 +968,16 @@ func AppendIfAbsent(slice interface{}, value interface{}) interface{} {
}
return out.Interface()
}
// AppendIfAbsent only absent append the value
func Join(slice interface{}, separator string) string {
sv := sliceValue(slice)
strs := make([]string, sv.Len())
for i := 0; i < sv.Len(); i++ {
strs[i] = fmt.Sprint(sv.Index(i).Interface())
}
return strings.Join(strs, separator)
}

View File

@@ -624,3 +624,15 @@ func TestAppendIfAbsent(t *testing.T) {
assert.Equal([]string{"a", "b"}, AppendIfAbsent(str1, "a"))
assert.Equal([]string{"a", "b", "c"}, AppendIfAbsent(str1, "c"))
}
func TestJoin(t *testing.T) {
assert := internal.NewAssert(t, "TestJoin")
nums := []int{1, 2, 3, 4, 5}
result1 := Join(nums, ",")
result2 := Join(nums, "-")
assert.Equal("1,2,3,4,5", result1)
assert.Equal("1-2-3-4-5", result2)
}