Skip to content

Commit

Permalink
other: v2 更改 ecs 包为内部包,toolkit 下新增 codec、cipher、fileproc 包
Browse files Browse the repository at this point in the history
  • Loading branch information
kercylan98 committed Apr 28, 2024
1 parent f0f5f8a commit a02e8cf
Show file tree
Hide file tree
Showing 34 changed files with 593 additions and 268 deletions.
6 changes: 6 additions & 0 deletions toolkit/cipher/cipher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package cipher

type Cipher interface {
Encrypt(data []byte) ([]byte, error)
Decrypt(data []byte) ([]byte, error)
}
102 changes: 102 additions & 0 deletions toolkit/cipher/rsa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package cipher

import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
)

// NewRSAFromPEM 从 PEM 编码的公钥和私钥创建 RSA 实例
func NewRSAFromPEM(publicKey, privateKey []byte) (*RSA, error) {
privatePem, _ := pem.Decode(privateKey)
private, err := x509.ParsePKCS1PrivateKey(privatePem.Bytes)
if err != nil {
return nil, err
}
return &RSA{privateKey: private}, nil
}

// NewRSAFromPublicKeyPEM 从 PEM 编码的公钥创建 RSA 实例
func NewRSAFromPublicKeyPEM(publicKey []byte) (*RSA, error) {
publicPem, _ := pem.Decode(publicKey)
public, err := x509.ParsePKCS1PublicKey(publicPem.Bytes)
if err != nil {
return nil, err
}
return &RSA{privateKey: &rsa.PrivateKey{PublicKey: *public}}, nil
}

// NewRSAFromPrivateKeyPEM 从 PEM 编码的私钥创建 RSA 实例
func NewRSAFromPrivateKeyPEM(privateKey []byte) (*RSA, error) {
privatePem, _ := pem.Decode(privateKey)
private, err := x509.ParsePKCS1PrivateKey(privatePem.Bytes)
if err != nil {
return nil, err
}
return &RSA{privateKey: private}, nil
}

// NewRSA 创建一个新的 RSA 实例,使用指定的位数生成密钥对
func NewRSA(bits int) (*RSA, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, err
}
return &RSA{privateKey: privateKey}, nil
}

type RSA struct {
privateKey *rsa.PrivateKey
}

// Encrypt 使用 RSA 公钥加密数据
func (r *RSA) Encrypt(data []byte) ([]byte, error) {
pubKey := &r.privateKey.PublicKey
return rsa.EncryptPKCS1v15(rand.Reader, pubKey, data)
}

// Decrypt 使用 RSA 私钥解密数据
func (r *RSA) Decrypt(encrypted []byte) ([]byte, error) {
return rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, encrypted)
}

// PublicKey 返回 RSA 公钥的 PEM 编码。
func (r *RSA) PublicKey() []byte {
pubKey := r.privateKey.PublicKey
pubKeyDer := x509.MarshalPKCS1PublicKey(&pubKey)
return pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubKeyDer,
})
}

// PrivateKey 返回 RSA 私钥的 PEM 编码。
func (r *RSA) PrivateKey() []byte {
privateKeyDer := x509.MarshalPKCS1PrivateKey(r.privateKey)
return pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateKeyDer,
})
}

// Sign 使用 RSA 私钥对数据进行签名
func (r *RSA) Sign(data []byte) ([]byte, error) {
hashed := r.sha256Sum(data)
return rsa.SignPKCS1v15(rand.Reader, r.privateKey, crypto.SHA256, hashed)
}

// Verify 使用 RSA 公钥验证签名
func (r *RSA) Verify(data, signature []byte) error {
hashed := r.sha256Sum(data)
return rsa.VerifyPKCS1v15(&r.privateKey.PublicKey, crypto.SHA256, hashed, signature)
}

// sha256Sum 计算数据的 SHA-256 哈希值
func (r *RSA) sha256Sum(data []byte) []byte {
h := sha256.New()
h.Write(data)
return h.Sum(nil)
}
23 changes: 23 additions & 0 deletions toolkit/codec/base32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package codec

import (
"encoding/base32"
"errors"
)

var base32Encoding = base32.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")

type Base32 struct{}

func (b *Base32) Encode(src []byte) ([]byte, error) {
encoded := base32Encoding.EncodeToString(src)
return []byte(encoded), nil
}

func (b *Base32) Decode(src []byte) ([]byte, error) {
decoded, err := base32Encoding.DecodeString(string(src))
if err != nil {
return nil, errors.New("invalid Base32 data")
}
return decoded, nil
}
60 changes: 60 additions & 0 deletions toolkit/codec/base58.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package codec

import (
"errors"
"math/big"
)

const (
base58Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
base58Base = 58
)

type Base58 struct{}

func (b *Base58) Encode(src []byte) ([]byte, error) {
x := big.NewInt(0).SetBytes(src)
mod := big.NewInt(base58Base)
var encoded []byte

for x.Sign() > 0 {
remainder := big.NewInt(0)
x.DivMod(x, mod, remainder)
encoded = append([]byte{base58Alphabet[remainder.Int64()]}, encoded...)
}

// 添加前导零以保持相同的长度
for _, v := range src {
if v != 0 {
break
}
encoded = append([]byte{base58Alphabet[0]}, encoded...)
}

return encoded, nil
}

func (b *Base58) Decode(src []byte) ([]byte, error) {
x := big.NewInt(0)
base := big.NewInt(base58Base)

for _, c := range src {
index := b.alphabetIndex(c)
if index == -1 {
return nil, errors.New("invalid Base58 character")
}
x.Mul(x, base)
x.Add(x, big.NewInt(index))
}

return x.Bytes(), nil
}

func (b *Base58) alphabetIndex(char byte) int64 {
for i, a := range []byte(base58Alphabet) {
if a == char {
return int64(i)
}
}
return -1
}
13 changes: 13 additions & 0 deletions toolkit/codec/base64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package codec

import "encoding/base64"

type Base64 struct{}

func (b *Base64) Encode(src []byte) ([]byte, error) {
return []byte(base64.StdEncoding.EncodeToString(src)), nil
}

func (b *Base64) Decode(src []byte) ([]byte, error) {
return base64.StdEncoding.DecodeString(string(src))
}
14 changes: 14 additions & 0 deletions toolkit/codec/codec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package codec

type Encoder interface {
Encode(src []byte) ([]byte, error)
}

type Decoder interface {
Decode(src []byte) ([]byte, error)
}

type Codec interface {
Encoder
Decoder
}
38 changes: 38 additions & 0 deletions toolkit/codec/crc32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package codec

import (
"errors"
"hash/crc32"
)

type Crc32 struct{}

func (c *Crc32) Encode(src []byte) ([]byte, error) {
crcTable := crc32.MakeTable(crc32.IEEE)
crcValue := crc32.Checksum(src, crcTable)

// 将 CRC 值附加到原始数据的末尾
result := append(src, byte(crcValue>>24), byte(crcValue>>16), byte(crcValue>>8), byte(crcValue))
return result, nil
}

func (c *Crc32) Decode(src []byte) ([]byte, error) {
if len(src) < 4 {
return nil, errors.New("invalid data")
}

// 获取数据部分和 CRC 校验码部分
data := src[:len(src)-4]
crcReceived := uint32(src[len(src)-4])<<24 | uint32(src[len(src)-3])<<16 | uint32(src[len(src)-2])<<8 | uint32(src[len(src)-1])

// 计算数据的 CRC
crcTable := crc32.MakeTable(crc32.IEEE)
crcCalculated := crc32.Checksum(data, crcTable)

// 验证 CRC 是否匹配
if crcReceived != crcCalculated {
return nil, errors.New("CRC check failed")
}

return data, nil
}
44 changes: 44 additions & 0 deletions toolkit/codec/crc64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package codec

import (
"errors"
"hash/crc64"
)

type Crc64 struct{}

func (c *Crc64) Encode(src []byte) ([]byte, error) {
crcValue := crc64.Checksum(src, crc64.MakeTable(crc64.ISO))

// 将 CRC-64 值附加到原始数据的末尾(CRC-64 是 8 字节)
result := append(src,
byte(crcValue>>56), byte(crcValue>>48), byte(crcValue>>40), byte(crcValue>>32),
byte(crcValue>>24), byte(crcValue>>16), byte(crcValue>>8), byte(crcValue),
)
return result, nil
}

func (c *Crc64) Decode(src []byte) ([]byte, error) {
if len(src) < 8 {
return nil, errors.New("invalid data")
}

// 获取数据部分和 CRC 校验码部分
data := src[:len(src)-8]
crcReceived := uint64(0)

// 将 CRC 校验码从字节数组转换为 uint64
for i := 0; i < 8; i++ {
crcReceived |= uint64(src[len(src)-8+i]) << (56 - (i * 8))
}

// 计算数据的 CRC
crcCalculated := crc64.Checksum(data, crc64.MakeTable(crc64.ISO))

// 验证 CRC 是否匹配
if crcReceived != crcCalculated {
return nil, errors.New("CRC check failed")
}

return data, nil
}
34 changes: 34 additions & 0 deletions toolkit/codec/md5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package codec

import (
"crypto/md5"
"errors"
)

type MD5 struct{}

func (h *MD5) Encode(src []byte) ([]byte, error) {
hash := md5.New()
hash.Write(src)
return append(src, hash.Sum(nil)...), nil
}

func (h *MD5) Decode(src []byte) ([]byte, error) {
if len(src) < md5.Size {
return nil, errors.New("invalid data length")
}
data := src[:len(src)-md5.Size]
expectedHash := src[len(src)-md5.Size:]

hash := md5.New()
hash.Write(data)
calculatedHash := hash.Sum(nil)

for i := 0; i < md5.Size; i++ {
if expectedHash[i] != calculatedHash[i] {
return nil, errors.New("MD5 mismatch")
}
}

return data, nil
}
35 changes: 35 additions & 0 deletions toolkit/codec/sha1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package codec

import (
"crypto/sha1"
"errors"
)

type Sha1 struct{}

func (h *Sha1) Encode(src []byte) ([]byte, error) {
hash := sha1.New()
hash.Write(src)
return append(src, hash.Sum(nil)...), nil
}

func (h *Sha1) Decode(src []byte) ([]byte, error) {
if len(src) < sha1.Size {
return nil, errors.New("invalid data length")
}

data := src[:len(src)-sha1.Size]
expectedHash := src[len(src)-sha1.Size:]

hash := sha1.New()
hash.Write(data)
calculatedHash := hash.Sum(nil)

for i := 0; i < sha1.Size; i++ {
if expectedHash[i] != calculatedHash[i] {
return nil, errors.New("SHA-1 mismatch")
}
}

return data, nil
}
Loading

0 comments on commit a02e8cf

Please sign in to comment.