update starcrypto
This commit is contained in:
parent
d6fb0b8c7f
commit
0a4c0a944b
122
aes.go
Normal file
122
aes.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PKCS5PADDING = "PKCS5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CustomEncryptAesCFB(origData []byte, key []byte) ([]byte, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
encrypted := make([]byte, aes.BlockSize+len(origData))
|
||||||
|
iv := encrypted[:aes.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stream := cipher.NewCFBEncrypter(block, iv)
|
||||||
|
stream.XORKeyStream(encrypted[aes.BlockSize:], origData)
|
||||||
|
return encrypted, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CustomDecryptAesCFB(encrypted []byte, key []byte) ([]byte, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(encrypted) < aes.BlockSize {
|
||||||
|
return nil, errors.New("ciphertext too short")
|
||||||
|
}
|
||||||
|
iv := encrypted[:aes.BlockSize]
|
||||||
|
encrypted = encrypted[aes.BlockSize:]
|
||||||
|
|
||||||
|
stream := cipher.NewCFBDecrypter(block, iv)
|
||||||
|
stream.XORKeyStream(encrypted, encrypted)
|
||||||
|
return encrypted, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CustomEncryptAesCFBNoBlock(origData []byte, key []byte, iv []byte) ([]byte, error) {
|
||||||
|
if len(iv) != 16 {
|
||||||
|
return nil, errors.New("iv length must be 16")
|
||||||
|
}
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
encrypted := make([]byte, len(origData))
|
||||||
|
stream := cipher.NewCFBEncrypter(block, iv)
|
||||||
|
stream.XORKeyStream(encrypted, origData)
|
||||||
|
return encrypted, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CustomDecryptAesCFBNoBlock(encrypted []byte, key []byte, iv []byte) ([]byte, error) {
|
||||||
|
if len(iv) != 16 {
|
||||||
|
return nil, errors.New("iv length must be 16")
|
||||||
|
}
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stream := cipher.NewCFBDecrypter(block, iv)
|
||||||
|
stream.XORKeyStream(encrypted, encrypted)
|
||||||
|
return encrypted, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncryptAesCBC(data, key []byte, iv []byte, paddingType string) ([]byte, error) {
|
||||||
|
var content []byte
|
||||||
|
aesBlockEncrypter, err := aes.NewCipher(key)
|
||||||
|
switch paddingType {
|
||||||
|
case PKCS5PADDING:
|
||||||
|
content = PKCS5Padding(data, aesBlockEncrypter.BlockSize())
|
||||||
|
default:
|
||||||
|
return nil, errors.New("padding type not supported")
|
||||||
|
}
|
||||||
|
encrypted := make([]byte, len(content))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aesEncrypter := cipher.NewCBCEncrypter(aesBlockEncrypter, iv)
|
||||||
|
aesEncrypter.CryptBlocks(encrypted, content)
|
||||||
|
return encrypted, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PKCS5Padding(cipherText []byte, blockSize int) []byte {
|
||||||
|
padding := blockSize - len(cipherText)%blockSize
|
||||||
|
padText := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||||
|
return append(cipherText, padText...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PKCS5Trimming(encrypt []byte) []byte {
|
||||||
|
padding := encrypt[len(encrypt)-1]
|
||||||
|
if len(encrypt)-int(padding) < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return encrypt[:len(encrypt)-int(padding)]
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecryptAesCBC(src, key []byte, iv []byte, paddingType string) (data []byte, err error) {
|
||||||
|
decrypted := make([]byte, len(src))
|
||||||
|
var aesBlockDecrypter cipher.Block
|
||||||
|
aesBlockDecrypter, err = aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aesDecrypter := cipher.NewCBCDecrypter(aesBlockDecrypter, iv)
|
||||||
|
aesDecrypter.CryptBlocks(decrypted, src)
|
||||||
|
switch paddingType {
|
||||||
|
case PKCS5PADDING:
|
||||||
|
return PKCS5Trimming(decrypted), nil
|
||||||
|
default:
|
||||||
|
return nil, errors.New("padding type not supported")
|
||||||
|
}
|
||||||
|
}
|
@ -3,24 +3,38 @@ package starcrypto
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"hash/crc32"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckCRC32A calculates CRC32A (ITU I.363.5 algorithm, popularized by BZIP2) checksum.
|
// CheckCRC32A calculates CRC32A (ITU I.363.5 algorithm, popularized by BZIP2) checksum.
|
||||||
// This function will produce the same results as following PHP code:
|
// This function will produce the same results as following PHP code:
|
||||||
// hexdec(hash('crc32', $data))
|
//
|
||||||
|
// hexdec(hash('crc32', $data))
|
||||||
func CheckCRC32A(data []byte) uint32 {
|
func CheckCRC32A(data []byte) uint32 {
|
||||||
b := digest(data)
|
b := digest(data)
|
||||||
|
|
||||||
return binary.BigEndian.Uint32(b)
|
return binary.BigEndian.Uint32(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Crc32Str(bstr []byte) string {
|
||||||
|
return String(Crc32(bstr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRC32 输出CRC32校验值
|
||||||
|
func Crc32(bstr []byte) []byte {
|
||||||
|
crcsum := crc32.NewIEEE()
|
||||||
|
crcsum.Write(bstr)
|
||||||
|
return crcsum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
func Crc32A(data []byte) []byte {
|
func Crc32A(data []byte) []byte {
|
||||||
return digest(data)
|
return digest(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crc32AStr is a convenience function that outputs CRC32A (ITU I.363.5 algorithm, popularized by BZIP2) checksum as a hex string.
|
// Crc32AStr is a convenience function that outputs CRC32A (ITU I.363.5 algorithm, popularized by BZIP2) checksum as a hex string.
|
||||||
// This function will produce the same results as following PHP code:
|
// This function will produce the same results as following PHP code:
|
||||||
// hash('crc32', $data)
|
//
|
||||||
|
// hash('crc32', $data)
|
||||||
func Crc32AStr(data []byte) string {
|
func Crc32AStr(data []byte) string {
|
||||||
b := digest(data)
|
b := digest(data)
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestRsaCrypt(t *testing.T) {
|
func TestRsaCrypt(t *testing.T) {
|
||||||
privKey, pubKey, err := GenerateKey(2048)
|
privKey, pubKey, err := GenerateRsaKey(2048)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -23,3 +23,12 @@ func TestRsaCrypt(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHmacSHA224(t *testing.T) {
|
||||||
|
key := []byte("hello world")
|
||||||
|
data := []byte("hello world")
|
||||||
|
code := HmacSHA224Str(key, data)
|
||||||
|
if "1414427f4b2889c3e86e637162c1add2bb888d1fc6c405d05fa5b66b" != code {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
588
crypto.go
588
crypto.go
@ -1,502 +1,28 @@
|
|||||||
package starcrypto
|
package starcrypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/md5"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha1"
|
|
||||||
"crypto/sha256"
|
|
||||||
"crypto/sha512"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"hash"
|
|
||||||
"hash/crc32"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
rands "math/rand"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func String(bstr []byte) string {
|
func String(bstr []byte) string {
|
||||||
return hex.EncodeToString(bstr)
|
return hex.EncodeToString(bstr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MD5 输出MD5校验值
|
|
||||||
func Md5(bstr []byte) []byte {
|
|
||||||
md5sum := md5.New()
|
|
||||||
md5sum.Write(bstr)
|
|
||||||
return md5sum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Md5Str(bstr []byte) string {
|
|
||||||
return String(Md5(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CRC32 输出CRC32校验值
|
|
||||||
func Crc32(bstr []byte) []byte {
|
|
||||||
crcsum := crc32.NewIEEE()
|
|
||||||
crcsum.Write(bstr)
|
|
||||||
return crcsum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Crc32Str(bstr []byte) string {
|
|
||||||
return String(Crc32(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHA512 输出SHA512校验值
|
|
||||||
func Sha512(bstr []byte) []byte {
|
|
||||||
shasum := sha512.New()
|
|
||||||
shasum.Write(bstr)
|
|
||||||
return shasum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha512Str(bstr []byte) string {
|
|
||||||
return String(Sha512(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHA384 输出SHA384校验值
|
|
||||||
func Sha384(bstr []byte) []byte {
|
|
||||||
shasum := sha512.New384()
|
|
||||||
shasum.Write(bstr)
|
|
||||||
return shasum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha384Str(bstr []byte) string {
|
|
||||||
return String(Sha384(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHA256 输出SHA256校验值
|
|
||||||
func Sha256(bstr []byte) []byte {
|
|
||||||
shasum := sha256.New()
|
|
||||||
shasum.Write(bstr)
|
|
||||||
return shasum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha256Str(bstr []byte) string {
|
|
||||||
return String(Sha256(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHA224 输出SHA224校验值
|
|
||||||
func Sha224(bstr []byte) []byte {
|
|
||||||
shasum := sha256.New224()
|
|
||||||
shasum.Write(bstr)
|
|
||||||
return shasum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha224Str(bstr []byte) string {
|
|
||||||
return String(Sha224(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHA1 输出SHA1校验值
|
|
||||||
func Sha1(bstr []byte) []byte {
|
|
||||||
shasum := sha1.New()
|
|
||||||
shasum.Write(bstr)
|
|
||||||
return shasum.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha1Str(bstr []byte) string {
|
|
||||||
return String(Sha512(bstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SumAll 可以对同一数据进行多种校验
|
|
||||||
func SumAll(data []byte, method []string) (map[string][]byte, error) {
|
|
||||||
result := make(map[string][]byte)
|
|
||||||
methods := make(map[string]hash.Hash)
|
|
||||||
var iscrc bool
|
|
||||||
if len(method) == 0 {
|
|
||||||
method = []string{"sha512", "sha256", "sha384", "sha224", "sha1", "crc32", "md5"}
|
|
||||||
}
|
|
||||||
sum512 := sha512.New()
|
|
||||||
sum384 := sha512.New384()
|
|
||||||
sum256 := sha256.New()
|
|
||||||
sum224 := sha256.New224()
|
|
||||||
sum1 := sha1.New()
|
|
||||||
crcsum := crc32.NewIEEE()
|
|
||||||
md5sum := md5.New()
|
|
||||||
for _, v := range method {
|
|
||||||
switch v {
|
|
||||||
case "md5":
|
|
||||||
methods["md5"] = md5sum
|
|
||||||
case "crc32":
|
|
||||||
iscrc = true
|
|
||||||
case "sha1":
|
|
||||||
methods["sha1"] = sum1
|
|
||||||
case "sha224":
|
|
||||||
methods["sha224"] = sum224
|
|
||||||
case "sha256":
|
|
||||||
methods["sha256"] = sum256
|
|
||||||
case "sha384":
|
|
||||||
methods["sha384"] = sum384
|
|
||||||
case "sha512":
|
|
||||||
methods["sha512"] = sum512
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, v := range methods {
|
|
||||||
v.Write(data)
|
|
||||||
}
|
|
||||||
if iscrc {
|
|
||||||
crcsum.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range methods {
|
|
||||||
result[k] = v.Sum(nil)
|
|
||||||
}
|
|
||||||
if iscrc {
|
|
||||||
result["crc32"] = crcsum.Sum(nil)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileSum 输出文件内容校验值,method为单个校验方法,小写
|
|
||||||
//例:FileSum("./test.txt","md5",shell(pect float64){fmt.Sprintf("已完成 %f\r",pect)})
|
|
||||||
func FileSum(filepath, method string, shell func(float64)) (string, error) {
|
|
||||||
var sum hash.Hash
|
|
||||||
var sum32 hash.Hash32
|
|
||||||
var issum32 bool
|
|
||||||
var result string
|
|
||||||
fp, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
switch method {
|
|
||||||
case "sha512":
|
|
||||||
sum = sha512.New()
|
|
||||||
case "sha384":
|
|
||||||
sum = sha512.New384()
|
|
||||||
case "sha256":
|
|
||||||
sum = sha256.New()
|
|
||||||
case "sha224":
|
|
||||||
sum = sha256.New224()
|
|
||||||
case "sha1":
|
|
||||||
sum = sha1.New()
|
|
||||||
case "crc32":
|
|
||||||
sum32 = crc32.NewIEEE()
|
|
||||||
issum32 = true
|
|
||||||
case "md5":
|
|
||||||
sum = md5.New()
|
|
||||||
default:
|
|
||||||
return "", errors.New("Cannot Recognize The Method:" + method)
|
|
||||||
}
|
|
||||||
writer := 0
|
|
||||||
stat, _ := os.Stat(filepath)
|
|
||||||
filebig := float64(stat.Size())
|
|
||||||
if !issum32 {
|
|
||||||
// if _, err := io.Copy(sum, fp); err != nil {
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 1048574)
|
|
||||||
n, err := fp.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
writer += n
|
|
||||||
pect := (float64(writer) / filebig) * 100
|
|
||||||
go shell(pect)
|
|
||||||
sum.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
result = hex.EncodeToString(sum.Sum(nil))
|
|
||||||
} else {
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 1048574)
|
|
||||||
n, err := fp.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
writer += n
|
|
||||||
pect := (float64(writer) / filebig) * 100
|
|
||||||
go shell(pect)
|
|
||||||
sum32.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
result = hex.EncodeToString(sum32.Sum(nil))
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileSumAll 可以对同一文件进行多种校验
|
|
||||||
func FileSumAll(filepath string, method []string, shell func(float64)) (map[string]string, error) {
|
|
||||||
result := make(map[string]string)
|
|
||||||
methods := make(map[string]hash.Hash)
|
|
||||||
var iscrc bool
|
|
||||||
|
|
||||||
if len(method) == 0 {
|
|
||||||
method = []string{"sha512", "sha256", "sha384", "sha224", "sha1", "crc32", "md5"}
|
|
||||||
}
|
|
||||||
fp, err := os.Open(filepath)
|
|
||||||
defer fp.Close()
|
|
||||||
if err != nil {
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
stat, _ := os.Stat(filepath)
|
|
||||||
filebig := float64(stat.Size())
|
|
||||||
sum512 := sha512.New()
|
|
||||||
sum384 := sha512.New384()
|
|
||||||
sum256 := sha256.New()
|
|
||||||
sum224 := sha256.New224()
|
|
||||||
sum1 := sha1.New()
|
|
||||||
crcsum := crc32.NewIEEE()
|
|
||||||
md5sum := md5.New()
|
|
||||||
for _, v := range method {
|
|
||||||
switch v {
|
|
||||||
case "md5":
|
|
||||||
methods["md5"] = md5sum
|
|
||||||
case "crc32":
|
|
||||||
iscrc = true
|
|
||||||
case "sha1":
|
|
||||||
methods["sha1"] = sum1
|
|
||||||
case "sha224":
|
|
||||||
methods["sha224"] = sum224
|
|
||||||
case "sha256":
|
|
||||||
methods["sha256"] = sum256
|
|
||||||
case "sha384":
|
|
||||||
methods["sha384"] = sum384
|
|
||||||
case "sha512":
|
|
||||||
methods["sha512"] = sum512
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writer := 0
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 1048574)
|
|
||||||
n, err := fp.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
writer += n
|
|
||||||
pect := (float64(writer) / filebig) * 100
|
|
||||||
go shell(pect)
|
|
||||||
for _, v := range methods {
|
|
||||||
v.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
if iscrc {
|
|
||||||
crcsum.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for k, v := range methods {
|
|
||||||
result[k] = hex.EncodeToString(v.Sum(nil))
|
|
||||||
}
|
|
||||||
if iscrc {
|
|
||||||
result["crc32"] = hex.EncodeToString(crcsum.Sum(nil))
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach 合并src与dst文件并输出到output中
|
|
||||||
func Attach(src, dst, output string) error {
|
|
||||||
fpsrc, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpsrc.Close()
|
|
||||||
fpdst, err := os.Open(dst)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpdst.Close()
|
|
||||||
fpout, err := os.Create(output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpout.Close()
|
|
||||||
if _, err := io.Copy(fpout, fpsrc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 1048574)
|
|
||||||
n, err := fpdst.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fpout.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detach 按bytenum字节大小分割src文件到dst1与dst2两个新文件中去
|
|
||||||
func Detach(src string, bytenum int, dst1, dst2 string) error {
|
|
||||||
fpsrc, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpsrc.Close()
|
|
||||||
fpdst1, err := os.Create(dst1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpdst1.Close()
|
|
||||||
fpdst2, err := os.Create(dst2)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpdst2.Close()
|
|
||||||
sumall := 0
|
|
||||||
var buf []byte
|
|
||||||
for {
|
|
||||||
if bytenum-sumall < 1048576 {
|
|
||||||
buf = make([]byte, bytenum-sumall)
|
|
||||||
} else {
|
|
||||||
buf = make([]byte, 1048576)
|
|
||||||
}
|
|
||||||
n, err := fpsrc.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sumall += n
|
|
||||||
fpdst1.Write(buf[0:n])
|
|
||||||
if sumall == bytenum {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
buf = make([]byte, 1048576)
|
|
||||||
n, err := fpsrc.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fpdst2.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SplitFile 把src文件按要求分割到dst中去,dst应传入带*号字符串
|
|
||||||
// 如果bynum=true 则把文件分割成num份
|
|
||||||
// 如果bynum=false 则把文件按num字节分成多份
|
|
||||||
func SplitFile(src, dst string, num int, bynum bool, shell func(float64)) error {
|
|
||||||
fpsrc, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpsrc.Close()
|
|
||||||
stat, _ := os.Stat(src)
|
|
||||||
filebig := float64(stat.Size())
|
|
||||||
if bynum {
|
|
||||||
if int(filebig) < num {
|
|
||||||
return errors.New("file is too small to split")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
balance := int(filebig/float64(num)) + 1
|
|
||||||
if !bynum {
|
|
||||||
balance = num
|
|
||||||
}
|
|
||||||
nownum := 0
|
|
||||||
fpdst, err := os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fpdst.Close()
|
|
||||||
var sum, tsum int = 0, 0
|
|
||||||
var buf []byte
|
|
||||||
for {
|
|
||||||
if balance-sum < 1048576 {
|
|
||||||
buf = make([]byte, balance-sum)
|
|
||||||
} else {
|
|
||||||
buf = make([]byte, 1048576)
|
|
||||||
}
|
|
||||||
n, err := fpsrc.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sum += n
|
|
||||||
tsum += n
|
|
||||||
fpdst.Write(buf[0:n])
|
|
||||||
go shell(float64(tsum) / filebig * 100)
|
|
||||||
if sum == balance {
|
|
||||||
fpdst.Close()
|
|
||||||
nownum++
|
|
||||||
fpdst, err = os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sum = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeFile 合并src文件到dst文件中去,src文件应传入带*号字符串
|
|
||||||
func MergeFile(src, dst string, shell func(float64)) error {
|
|
||||||
tmp := strings.Replace(src, "*", "0", -1)
|
|
||||||
dir, err := ioutil.ReadDir(filepath.Dir(tmp))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
base := filepath.Base(src)
|
|
||||||
tmp = strings.Replace(base, "*", "(\\d+)", -1)
|
|
||||||
reg := regexp.MustCompile(tmp)
|
|
||||||
count := 0
|
|
||||||
var filebig float64
|
|
||||||
for _, v := range dir {
|
|
||||||
if reg.MatchString(v.Name()) {
|
|
||||||
count++
|
|
||||||
filebig += float64(v.Size())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fpdst, err := os.Create(dst)
|
|
||||||
defer fpdst.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var sum int64
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
fpsrc, err := os.Open(strings.Replace(src, "*", strconv.Itoa(i), -1))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 1048576)
|
|
||||||
n, err := fpsrc.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sum += int64(n)
|
|
||||||
go shell(float64(sum) / filebig * 100)
|
|
||||||
fpdst.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
fpsrc.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VicqueEncodeV1 Best!
|
|
||||||
func VicqueEncodeV1(srcdata []byte, key string) []byte {
|
func VicqueEncodeV1(srcdata []byte, key string) []byte {
|
||||||
var keys []int
|
var keys []int
|
||||||
var saku, piku uint8
|
var randCode1, randCode2 uint8
|
||||||
data := make([]byte, len(srcdata))
|
data := make([]byte, len(srcdata))
|
||||||
copy(data, srcdata)
|
copy(data, srcdata)
|
||||||
binary.Read(rand.Reader, binary.LittleEndian, &saku)
|
binary.Read(rand.Reader, binary.LittleEndian, &randCode1)
|
||||||
binary.Read(rand.Reader, binary.LittleEndian, &piku)
|
binary.Read(rand.Reader, binary.LittleEndian, &randCode2)
|
||||||
keys = append(keys, len(key)+int(saku))
|
keys = append(keys, len(key)+int(randCode1))
|
||||||
lens := len(data)
|
lens := len(data)
|
||||||
for _, v := range key {
|
for _, v := range key {
|
||||||
keys = append(keys, int(byte(v))+int(saku)-int(piku))
|
keys = append(keys, int(byte(v))+int(randCode1)-int(randCode2))
|
||||||
}
|
}
|
||||||
lenkey := len(keys)
|
lenkey := len(keys)
|
||||||
for k, v := range data {
|
for k, v := range data {
|
||||||
@ -529,22 +55,21 @@ func VicqueEncodeV1(srcdata []byte, key string) []byte {
|
|||||||
data[k] = byte(t)
|
data[k] = byte(t)
|
||||||
data[lens-1-k] = byte(nv)
|
data[lens-1-k] = byte(nv)
|
||||||
}
|
}
|
||||||
data = append(data, byte(saku), byte(piku))
|
data = append(data, byte(randCode1), byte(randCode2))
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// VicqueDecodeV1 Best!
|
|
||||||
func VicqueDecodeV1(srcdata []byte, key string) []byte {
|
func VicqueDecodeV1(srcdata []byte, key string) []byte {
|
||||||
var keys []int
|
var keys []int
|
||||||
var saku, piku int
|
var randCode1, randCode2 int
|
||||||
data := make([]byte, len(srcdata))
|
data := make([]byte, len(srcdata))
|
||||||
copy(data, srcdata)
|
copy(data, srcdata)
|
||||||
lens := len(data)
|
lens := len(data)
|
||||||
saku = int(data[lens-2])
|
randCode1 = int(data[lens-2])
|
||||||
piku = int(data[lens-1])
|
randCode2 = int(data[lens-1])
|
||||||
keys = append(keys, len(key)+int(saku))
|
keys = append(keys, len(key)+int(randCode1))
|
||||||
for _, v := range key {
|
for _, v := range key {
|
||||||
keys = append(keys, int(byte(v))+int(saku)-int(piku))
|
keys = append(keys, int(byte(v))+int(randCode1)-int(randCode2))
|
||||||
}
|
}
|
||||||
lenkey := len(keys)
|
lenkey := len(keys)
|
||||||
lens -= 2
|
lens -= 2
|
||||||
@ -581,7 +106,6 @@ func VicqueDecodeV1(srcdata []byte, key string) []byte {
|
|||||||
return data[:lens]
|
return data[:lens]
|
||||||
}
|
}
|
||||||
|
|
||||||
// VicqueEncodeV1File best
|
|
||||||
func VicqueEncodeV1File(src, dst, pwd string, shell func(float64)) error {
|
func VicqueEncodeV1File(src, dst, pwd string, shell func(float64)) error {
|
||||||
fpsrc, err := os.Open(src)
|
fpsrc, err := os.Open(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -614,7 +138,6 @@ func VicqueEncodeV1File(src, dst, pwd string, shell func(float64)) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VicqueDecodeV1File best
|
|
||||||
func VicqueDecodeV1File(src, dst, pwd string, shell func(float64)) error {
|
func VicqueDecodeV1File(src, dst, pwd string, shell func(float64)) error {
|
||||||
fpsrc, err := os.Open(src)
|
fpsrc, err := os.Open(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -646,92 +169,3 @@ func VicqueDecodeV1File(src, dst, pwd string, shell func(float64)) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FillWithRandom 随机写filesize大小的文件,每次buf大小为bufcap,随机bufnum个字符
|
|
||||||
func FillWithRandom(filepath string, filesize int, bufcap int, bufnum int, shell func(float64)) error {
|
|
||||||
var buf [][]byte
|
|
||||||
var buftmp []byte
|
|
||||||
rands.Seed(time.Now().Unix())
|
|
||||||
if bufnum <= 0 {
|
|
||||||
bufnum = 1
|
|
||||||
}
|
|
||||||
if bufcap > filesize {
|
|
||||||
bufcap = filesize
|
|
||||||
}
|
|
||||||
myfile, err := os.Create(filepath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer myfile.Close()
|
|
||||||
writer := bufio.NewWriter(myfile)
|
|
||||||
for i := 0; i < bufnum; i++ {
|
|
||||||
buftmp = []byte{}
|
|
||||||
for j := 0; j < bufcap; j++ {
|
|
||||||
buftmp = append(buftmp, byte(rands.Intn(256)))
|
|
||||||
}
|
|
||||||
buf = append(buf, buftmp)
|
|
||||||
}
|
|
||||||
sum := 0
|
|
||||||
for {
|
|
||||||
if filesize-sum < bufcap {
|
|
||||||
writer.Write(buf[rands.Intn(bufnum)][0 : filesize-sum])
|
|
||||||
sum += filesize - sum
|
|
||||||
} else {
|
|
||||||
writer.Write(buf[rands.Intn(bufnum)])
|
|
||||||
sum += bufcap
|
|
||||||
}
|
|
||||||
go shell(float64(sum) / float64(filesize) * 100)
|
|
||||||
if sum >= filesize {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.Flush()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// =================== CFB ======================
|
|
||||||
func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) {
|
|
||||||
block, err := aes.NewCipher(key)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
encrypted = make([]byte, aes.BlockSize+len(origData))
|
|
||||||
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:], origData)
|
|
||||||
return encrypted
|
|
||||||
}
|
|
||||||
func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) {
|
|
||||||
block, _ := aes.NewCipher(key)
|
|
||||||
if len(encrypted) < aes.BlockSize {
|
|
||||||
panic("ciphertext too short")
|
|
||||||
}
|
|
||||||
iv := encrypted[:aes.BlockSize]
|
|
||||||
encrypted = encrypted[aes.BlockSize:]
|
|
||||||
|
|
||||||
stream := cipher.NewCFBDecrypter(block, iv)
|
|
||||||
stream.XORKeyStream(encrypted, encrypted)
|
|
||||||
return encrypted
|
|
||||||
}
|
|
||||||
|
|
||||||
func AesEncryptCFBNoBlock(origData []byte, key []byte) (encrypted []byte) {
|
|
||||||
block, err := aes.NewCipher(key)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
encrypted = make([]byte, len(origData))
|
|
||||||
iv := Sha1(key)[:16]
|
|
||||||
stream := cipher.NewCFBEncrypter(block, iv)
|
|
||||||
stream.XORKeyStream(encrypted, origData)
|
|
||||||
return encrypted
|
|
||||||
}
|
|
||||||
func AesDecryptCFBNoBlock(encrypted []byte, key []byte) (decrypted []byte) {
|
|
||||||
block, _ := aes.NewCipher(key)
|
|
||||||
iv := Sha1(key)[:16]
|
|
||||||
stream := cipher.NewCFBDecrypter(block, iv)
|
|
||||||
stream.XORKeyStream(encrypted, encrypted)
|
|
||||||
return encrypted
|
|
||||||
}
|
|
||||||
|
117
ecdsa.go
Normal file
117
ecdsa.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateEcdsaKey(pubkeyCurve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) {
|
||||||
|
// 随机挑选基点,生成私钥
|
||||||
|
priv, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return priv, &priv.PublicKey, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeEcdsaPrivateKey(private *ecdsa.PrivateKey, secret string) ([]byte, error) {
|
||||||
|
b, err := x509.MarshalECPrivateKey(private)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if secret == "" {
|
||||||
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
|
Bytes: b,
|
||||||
|
Type: "EC PRIVATE KEY",
|
||||||
|
}), err
|
||||||
|
}
|
||||||
|
chiper := x509.PEMCipherAES256
|
||||||
|
blk, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", b, []byte(secret), chiper)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pem.EncodeToMemory(blk), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeEcdsaPublicKey(public *ecdsa.PublicKey) ([]byte, error) {
|
||||||
|
publicBytes, err := x509.MarshalPKIXPublicKey(public)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
|
Bytes: publicBytes,
|
||||||
|
Type: "PUBLIC KEY",
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeEcdsaPrivateKey(private []byte, password string) (*ecdsa.PrivateKey, error) {
|
||||||
|
var prikey *ecdsa.PrivateKey
|
||||||
|
var err error
|
||||||
|
var bytes []byte
|
||||||
|
blk, _ := pem.Decode(private)
|
||||||
|
if blk == nil {
|
||||||
|
return nil, errors.New("private key error!")
|
||||||
|
}
|
||||||
|
if password != "" {
|
||||||
|
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bytes = tmp
|
||||||
|
} else {
|
||||||
|
bytes = blk.Bytes
|
||||||
|
}
|
||||||
|
prikey, err = x509.ParseECPrivateKey(bytes)
|
||||||
|
if err != nil {
|
||||||
|
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
prikey = tmp.(*ecdsa.PrivateKey)
|
||||||
|
}
|
||||||
|
return prikey, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeEcdsaPublicKey(pubStr []byte) (*ecdsa.PublicKey, error) {
|
||||||
|
blk, _ := pem.Decode(pubStr)
|
||||||
|
if blk == nil {
|
||||||
|
return nil, errors.New("public key error")
|
||||||
|
}
|
||||||
|
pub, err := x509.ParsePKIXPublicKey(blk.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pub.(*ecdsa.PublicKey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeEcdsaSSHPublicKey(public *ecdsa.PublicKey) ([]byte, error) {
|
||||||
|
publicKey, err := ssh.NewPublicKey(public)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ssh.MarshalAuthorizedKey(publicKey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateEcdsaSSHKeyPair(pubkeyCurve elliptic.Curve, secret string) (string, string, error) {
|
||||||
|
pkey, pubkey, err := GenerateEcdsaKey(pubkeyCurve)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, err := EncodeEcdsaSSHPublicKey(pubkey)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, err := EncodeEcdsaPrivateKey(pkey, secret)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
return string(priv), string(pub), nil
|
||||||
|
}
|
246
file.go
Normal file
246
file.go
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Attach 合并src与dst文件并输出到output中
|
||||||
|
func Attach(src, dst, output string) error {
|
||||||
|
fpsrc, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpsrc.Close()
|
||||||
|
fpdst, err := os.Open(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpdst.Close()
|
||||||
|
fpout, err := os.Create(output)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpout.Close()
|
||||||
|
if _, err := io.Copy(fpout, fpsrc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 1048574)
|
||||||
|
n, err := fpdst.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fpout.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detach 按bytenum字节大小分割src文件到dst1与dst2两个新文件中去
|
||||||
|
func Detach(src string, bytenum int, dst1, dst2 string) error {
|
||||||
|
fpsrc, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpsrc.Close()
|
||||||
|
fpdst1, err := os.Create(dst1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpdst1.Close()
|
||||||
|
fpdst2, err := os.Create(dst2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpdst2.Close()
|
||||||
|
sumall := 0
|
||||||
|
var buf []byte
|
||||||
|
for {
|
||||||
|
if bytenum-sumall < 1048576 {
|
||||||
|
buf = make([]byte, bytenum-sumall)
|
||||||
|
} else {
|
||||||
|
buf = make([]byte, 1048576)
|
||||||
|
}
|
||||||
|
n, err := fpsrc.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sumall += n
|
||||||
|
fpdst1.Write(buf[0:n])
|
||||||
|
if sumall == bytenum {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
buf = make([]byte, 1048576)
|
||||||
|
n, err := fpsrc.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fpdst2.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SplitFile 把src文件按要求分割到dst中去,dst应传入带*号字符串
|
||||||
|
// 如果bynum=true 则把文件分割成num份
|
||||||
|
// 如果bynum=false 则把文件按num字节分成多份
|
||||||
|
func SplitFile(src, dst string, num int, bynum bool, shell func(float64)) error {
|
||||||
|
fpsrc, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpsrc.Close()
|
||||||
|
stat, _ := os.Stat(src)
|
||||||
|
filebig := float64(stat.Size())
|
||||||
|
if bynum {
|
||||||
|
if int(filebig) < num {
|
||||||
|
return errors.New("file is too small to split")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
balance := int(filebig/float64(num)) + 1
|
||||||
|
if !bynum {
|
||||||
|
balance = num
|
||||||
|
}
|
||||||
|
nownum := 0
|
||||||
|
fpdst, err := os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fpdst.Close()
|
||||||
|
var sum, tsum int = 0, 0
|
||||||
|
var buf []byte
|
||||||
|
for {
|
||||||
|
if balance-sum < 1048576 {
|
||||||
|
buf = make([]byte, balance-sum)
|
||||||
|
} else {
|
||||||
|
buf = make([]byte, 1048576)
|
||||||
|
}
|
||||||
|
n, err := fpsrc.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sum += n
|
||||||
|
tsum += n
|
||||||
|
fpdst.Write(buf[0:n])
|
||||||
|
go shell(float64(tsum) / filebig * 100)
|
||||||
|
if sum == balance {
|
||||||
|
fpdst.Close()
|
||||||
|
nownum++
|
||||||
|
fpdst, err = os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sum = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergeFile 合并src文件到dst文件中去,src文件应传入带*号字符串
|
||||||
|
func MergeFile(src, dst string, shell func(float64)) error {
|
||||||
|
tmp := strings.Replace(src, "*", "0", -1)
|
||||||
|
dir, err := ioutil.ReadDir(filepath.Dir(tmp))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
base := filepath.Base(src)
|
||||||
|
tmp = strings.Replace(base, "*", "(\\d+)", -1)
|
||||||
|
reg := regexp.MustCompile(tmp)
|
||||||
|
count := 0
|
||||||
|
var filebig float64
|
||||||
|
for _, v := range dir {
|
||||||
|
if reg.MatchString(v.Name()) {
|
||||||
|
count++
|
||||||
|
filebig += float64(v.Size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fpdst, err := os.Create(dst)
|
||||||
|
defer fpdst.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var sum int64
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
fpsrc, err := os.Open(strings.Replace(src, "*", strconv.Itoa(i), -1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 1048576)
|
||||||
|
n, err := fpsrc.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sum += int64(n)
|
||||||
|
go shell(float64(sum) / filebig * 100)
|
||||||
|
fpdst.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
fpsrc.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillWithRandom 随机写filesize大小的文件,每次buf大小为bufcap,随机bufnum个字符
|
||||||
|
func FillWithRandom(filepath string, filesize int, bufcap int, bufnum int, shell func(float64)) error {
|
||||||
|
var buf [][]byte
|
||||||
|
var buftmp []byte
|
||||||
|
rand.Seed(time.Now().Unix())
|
||||||
|
if bufnum <= 0 {
|
||||||
|
bufnum = 1
|
||||||
|
}
|
||||||
|
if bufcap > filesize {
|
||||||
|
bufcap = filesize
|
||||||
|
}
|
||||||
|
myfile, err := os.Create(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer myfile.Close()
|
||||||
|
writer := bufio.NewWriter(myfile)
|
||||||
|
for i := 0; i < bufnum; i++ {
|
||||||
|
buftmp = []byte{}
|
||||||
|
for j := 0; j < bufcap; j++ {
|
||||||
|
buftmp = append(buftmp, byte(rand.Intn(256)))
|
||||||
|
}
|
||||||
|
buf = append(buf, buftmp)
|
||||||
|
}
|
||||||
|
sum := 0
|
||||||
|
for {
|
||||||
|
if filesize-sum < bufcap {
|
||||||
|
writer.Write(buf[rand.Intn(bufnum)][0 : filesize-sum])
|
||||||
|
sum += filesize - sum
|
||||||
|
} else {
|
||||||
|
writer.Write(buf[rand.Intn(bufnum)])
|
||||||
|
sum += bufcap
|
||||||
|
}
|
||||||
|
go shell(float64(sum) / float64(filesize) * 100)
|
||||||
|
if sum >= filesize {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.Flush()
|
||||||
|
return nil
|
||||||
|
}
|
2
go.mod
2
go.mod
@ -2,4 +2,4 @@ module b612.me/starcrypto
|
|||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000
|
require golang.org/x/crypto v0.21.0
|
||||||
|
48
go.sum
48
go.sum
@ -1,11 +1,45 @@
|
|||||||
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000 h1:SL+8VVnkqyshUSz5iNnXtrBQzvFF2SkROm6t5RczFAE=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
204
hash.go
Normal file
204
hash.go
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"hash"
|
||||||
|
"hash/crc32"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SumAll 可以对同一数据进行多种校验
|
||||||
|
func SumAll(data []byte, method []string) (map[string][]byte, error) {
|
||||||
|
result := make(map[string][]byte)
|
||||||
|
methods := make(map[string]hash.Hash)
|
||||||
|
var iscrc bool
|
||||||
|
if len(method) == 0 {
|
||||||
|
method = []string{"sha512", "sha256", "sha384", "sha224", "sha1", "crc32", "md5"}
|
||||||
|
}
|
||||||
|
sum512 := sha512.New()
|
||||||
|
sum384 := sha512.New384()
|
||||||
|
sum256 := sha256.New()
|
||||||
|
sum224 := sha256.New224()
|
||||||
|
sum1 := sha1.New()
|
||||||
|
crcsum := crc32.NewIEEE()
|
||||||
|
md5sum := md5.New()
|
||||||
|
for _, v := range method {
|
||||||
|
switch v {
|
||||||
|
case "md5":
|
||||||
|
methods["md5"] = md5sum
|
||||||
|
case "crc32":
|
||||||
|
iscrc = true
|
||||||
|
case "sha1":
|
||||||
|
methods["sha1"] = sum1
|
||||||
|
case "sha224":
|
||||||
|
methods["sha224"] = sum224
|
||||||
|
case "sha256":
|
||||||
|
methods["sha256"] = sum256
|
||||||
|
case "sha384":
|
||||||
|
methods["sha384"] = sum384
|
||||||
|
case "sha512":
|
||||||
|
methods["sha512"] = sum512
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range methods {
|
||||||
|
v.Write(data)
|
||||||
|
}
|
||||||
|
if iscrc {
|
||||||
|
crcsum.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range methods {
|
||||||
|
result[k] = v.Sum(nil)
|
||||||
|
}
|
||||||
|
if iscrc {
|
||||||
|
result["crc32"] = crcsum.Sum(nil)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileSum 输出文件内容校验值,method为单个校验方法,小写
|
||||||
|
// 例:FileSum("./test.txt","md5",shell(pect float64){fmt.Sprintf("已完成 %f\r",pect)})
|
||||||
|
func FileSum(filepath, method string, shell func(float64)) (string, error) {
|
||||||
|
var sum hash.Hash
|
||||||
|
var sum32 hash.Hash32
|
||||||
|
var issum32 bool
|
||||||
|
var result string
|
||||||
|
fp, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
switch method {
|
||||||
|
case "sha512":
|
||||||
|
sum = sha512.New()
|
||||||
|
case "sha384":
|
||||||
|
sum = sha512.New384()
|
||||||
|
case "sha256":
|
||||||
|
sum = sha256.New()
|
||||||
|
case "sha224":
|
||||||
|
sum = sha256.New224()
|
||||||
|
case "sha1":
|
||||||
|
sum = sha1.New()
|
||||||
|
case "crc32":
|
||||||
|
sum32 = crc32.NewIEEE()
|
||||||
|
issum32 = true
|
||||||
|
case "md5":
|
||||||
|
sum = md5.New()
|
||||||
|
default:
|
||||||
|
return "", errors.New("Cannot Recognize The Method:" + method)
|
||||||
|
}
|
||||||
|
writer := 0
|
||||||
|
stat, _ := os.Stat(filepath)
|
||||||
|
filebig := float64(stat.Size())
|
||||||
|
if !issum32 {
|
||||||
|
// if _, err := io.Copy(sum, fp); err != nil {
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 1048574)
|
||||||
|
n, err := fp.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
writer += n
|
||||||
|
pect := (float64(writer) / filebig) * 100
|
||||||
|
go shell(pect)
|
||||||
|
sum.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
result = hex.EncodeToString(sum.Sum(nil))
|
||||||
|
} else {
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 1048574)
|
||||||
|
n, err := fp.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
writer += n
|
||||||
|
pect := (float64(writer) / filebig) * 100
|
||||||
|
go shell(pect)
|
||||||
|
sum32.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
result = hex.EncodeToString(sum32.Sum(nil))
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileSumAll 可以对同一文件进行多种校验
|
||||||
|
func FileSumAll(filepath string, method []string, shell func(float64)) (map[string]string, error) {
|
||||||
|
result := make(map[string]string)
|
||||||
|
methods := make(map[string]hash.Hash)
|
||||||
|
var iscrc bool
|
||||||
|
|
||||||
|
if len(method) == 0 {
|
||||||
|
method = []string{"sha512", "sha256", "sha384", "sha224", "sha1", "crc32", "md5"}
|
||||||
|
}
|
||||||
|
fp, err := os.Open(filepath)
|
||||||
|
defer fp.Close()
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
stat, _ := os.Stat(filepath)
|
||||||
|
filebig := float64(stat.Size())
|
||||||
|
sum512 := sha512.New()
|
||||||
|
sum384 := sha512.New384()
|
||||||
|
sum256 := sha256.New()
|
||||||
|
sum224 := sha256.New224()
|
||||||
|
sum1 := sha1.New()
|
||||||
|
crcsum := crc32.NewIEEE()
|
||||||
|
md5sum := md5.New()
|
||||||
|
for _, v := range method {
|
||||||
|
switch v {
|
||||||
|
case "md5":
|
||||||
|
methods["md5"] = md5sum
|
||||||
|
case "crc32":
|
||||||
|
iscrc = true
|
||||||
|
case "sha1":
|
||||||
|
methods["sha1"] = sum1
|
||||||
|
case "sha224":
|
||||||
|
methods["sha224"] = sum224
|
||||||
|
case "sha256":
|
||||||
|
methods["sha256"] = sum256
|
||||||
|
case "sha384":
|
||||||
|
methods["sha384"] = sum384
|
||||||
|
case "sha512":
|
||||||
|
methods["sha512"] = sum512
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer := 0
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 1048574)
|
||||||
|
n, err := fp.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
writer += n
|
||||||
|
pect := (float64(writer) / filebig) * 100
|
||||||
|
go shell(pect)
|
||||||
|
for _, v := range methods {
|
||||||
|
v.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
if iscrc {
|
||||||
|
crcsum.Write(buf[0:n])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range methods {
|
||||||
|
result[k] = hex.EncodeToString(v.Sum(nil))
|
||||||
|
}
|
||||||
|
if iscrc {
|
||||||
|
result["crc32"] = hex.EncodeToString(crcsum.Sum(nil))
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
87
hmac.go
Normal file
87
hmac.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"encoding/hex"
|
||||||
|
"golang.org/x/crypto/md4"
|
||||||
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
func chmac(message, key []byte, f func() hash.Hash) []byte {
|
||||||
|
h := hmac.New(f, []byte(key))
|
||||||
|
h.Write([]byte(message))
|
||||||
|
return h.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func chmacStr(message, key []byte, f func() hash.Hash) string {
|
||||||
|
return hex.EncodeToString(chmac(message, key, f))
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacMd4(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, md4.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacMd4Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, md4.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacMd5(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, md5.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacMd5Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, md5.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA1(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, sha1.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA1Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, sha1.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA256(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, sha256.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA256Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, sha256.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA384(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, sha512.New384)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA384Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, sha512.New384)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA512(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, sha512.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA512Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, sha512.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA224(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, sha256.New224)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSHA224Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, sha256.New224)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacRipeMd160(message, key []byte) []byte {
|
||||||
|
return chmac(message, key, ripemd160.New)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacRipeMd160Str(message, key []byte) string {
|
||||||
|
return chmacStr(message, key, ripemd160.New)
|
||||||
|
}
|
27
md5.go
Normal file
27
md5.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"golang.org/x/crypto/md4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MD5 输出MD5校验值
|
||||||
|
func Md5(bstr []byte) []byte {
|
||||||
|
md5sum := md5.New()
|
||||||
|
md5sum.Write(bstr)
|
||||||
|
return md5sum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md5Str(bstr []byte) string {
|
||||||
|
return String(Md5(bstr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md4(bstr []byte) []byte {
|
||||||
|
md4sum := md4.New()
|
||||||
|
md4sum.Write(bstr)
|
||||||
|
return md4sum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md4Str(bstr []byte) string {
|
||||||
|
return String(Md4(bstr))
|
||||||
|
}
|
15
ripe.go
Normal file
15
ripe.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RipeMd160(bstr []byte) []byte {
|
||||||
|
ripe := ripemd160.New()
|
||||||
|
ripe.Write(bstr)
|
||||||
|
return ripe.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RipeMd160Str(bstr []byte) string {
|
||||||
|
return String(RipeMd160(bstr))
|
||||||
|
}
|
43
rsa.go
43
rsa.go
@ -12,7 +12,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GenerateKey(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
|
func GenerateRsaKey(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
|
||||||
private, err := rsa.GenerateKey(rand.Reader, bits)
|
private, err := rsa.GenerateKey(rand.Reader, bits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -21,14 +21,22 @@ func GenerateKey(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncodePrivateKey(private *rsa.PrivateKey) []byte {
|
func EncodeRsaPrivateKey(private *rsa.PrivateKey, secret string) ([]byte, error) {
|
||||||
return pem.EncodeToMemory(&pem.Block{
|
if secret == "" {
|
||||||
Bytes: x509.MarshalPKCS1PrivateKey(private),
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
Type: "RSA PRIVATE KEY",
|
Bytes: x509.MarshalPKCS1PrivateKey(private),
|
||||||
})
|
Type: "RSA PRIVATE KEY",
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
chiper := x509.PEMCipherAES256
|
||||||
|
blk, err := x509.EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(private), []byte(secret), chiper)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pem.EncodeToMemory(blk), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncodePublicKey(public *rsa.PublicKey) ([]byte, error) {
|
func EncodeRsaPublicKey(public *rsa.PublicKey) ([]byte, error) {
|
||||||
publicBytes, err := x509.MarshalPKIXPublicKey(public)
|
publicBytes, err := x509.MarshalPKIXPublicKey(public)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -39,7 +47,7 @@ func EncodePublicKey(public *rsa.PublicKey) ([]byte, error) {
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecodePrivateKey(private []byte, password string) (*rsa.PrivateKey, error) {
|
func DecodeRsaPrivateKey(private []byte, password string) (*rsa.PrivateKey, error) {
|
||||||
var prikey *rsa.PrivateKey
|
var prikey *rsa.PrivateKey
|
||||||
var err error
|
var err error
|
||||||
var bytes []byte
|
var bytes []byte
|
||||||
@ -67,7 +75,7 @@ func DecodePrivateKey(private []byte, password string) (*rsa.PrivateKey, error)
|
|||||||
return prikey, err
|
return prikey, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecodePublicKey(pubStr []byte) (*rsa.PublicKey, error) {
|
func DecodeRsaPublicKey(pubStr []byte) (*rsa.PublicKey, error) {
|
||||||
blk, _ := pem.Decode(pubStr)
|
blk, _ := pem.Decode(pubStr)
|
||||||
if blk == nil {
|
if blk == nil {
|
||||||
return nil, errors.New("public key error")
|
return nil, errors.New("public key error")
|
||||||
@ -79,8 +87,7 @@ func DecodePublicKey(pubStr []byte) (*rsa.PublicKey, error) {
|
|||||||
return pub.(*rsa.PublicKey), nil
|
return pub.(*rsa.PublicKey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//EncodeSSHKey
|
func EncodeRsaSSHPublicKey(public *rsa.PublicKey) ([]byte, error) {
|
||||||
func EncodeSSHKey(public *rsa.PublicKey) ([]byte, error) {
|
|
||||||
publicKey, err := ssh.NewPublicKey(public)
|
publicKey, err := ssh.NewPublicKey(public)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -88,20 +95,22 @@ func EncodeSSHKey(public *rsa.PublicKey) ([]byte, error) {
|
|||||||
return ssh.MarshalAuthorizedKey(publicKey), nil
|
return ssh.MarshalAuthorizedKey(publicKey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeSSHKeyPair(bits int) (string, string, error) {
|
func GenerateRsaSSHKeyPair(bits int, secret string) (string, string, error) {
|
||||||
|
pkey, pubkey, err := GenerateRsaKey(bits)
|
||||||
pkey, pubkey, err := GenerateKey(bits)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub, err := EncodeSSHKey(pubkey)
|
pub, err := EncodeRsaSSHPublicKey(pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
//glog.Info("privateKey=[%s]\n pubKey=[%s]",string(EncodePrivateKey(pkey)),string(pub))
|
priv, err := EncodeRsaPrivateKey(pkey, secret)
|
||||||
return string(EncodePrivateKey(pkey)), string(pub), nil
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
return string(priv), string(pub), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSAEncrypt RSA公钥加密
|
// RSAEncrypt RSA公钥加密
|
||||||
|
62
sha.go
Normal file
62
sha.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SHA512 输出SHA512校验值
|
||||||
|
func Sha512(bstr []byte) []byte {
|
||||||
|
shasum := sha512.New()
|
||||||
|
shasum.Write(bstr)
|
||||||
|
return shasum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha512Str(bstr []byte) string {
|
||||||
|
return String(Sha512(bstr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHA384 输出SHA384校验值
|
||||||
|
func Sha384(bstr []byte) []byte {
|
||||||
|
shasum := sha512.New384()
|
||||||
|
shasum.Write(bstr)
|
||||||
|
return shasum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha384Str(bstr []byte) string {
|
||||||
|
return String(Sha384(bstr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHA256 输出SHA256校验值
|
||||||
|
func Sha256(bstr []byte) []byte {
|
||||||
|
shasum := sha256.New()
|
||||||
|
shasum.Write(bstr)
|
||||||
|
return shasum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha256Str(bstr []byte) string {
|
||||||
|
return String(Sha256(bstr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHA224 输出SHA224校验值
|
||||||
|
func Sha224(bstr []byte) []byte {
|
||||||
|
shasum := sha256.New224()
|
||||||
|
shasum.Write(bstr)
|
||||||
|
return shasum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha224Str(bstr []byte) string {
|
||||||
|
return String(Sha224(bstr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHA1 输出SHA1校验值
|
||||||
|
func Sha1(bstr []byte) []byte {
|
||||||
|
shasum := sha1.New()
|
||||||
|
shasum.Write(bstr)
|
||||||
|
return shasum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha1Str(bstr []byte) string {
|
||||||
|
return String(Sha512(bstr))
|
||||||
|
}
|
15
sm3.go
Normal file
15
sm3.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package starcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"b612.me/starcrypto/sm3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SM3(bstr []byte) []byte {
|
||||||
|
sm3sum := sm3.New()
|
||||||
|
sm3sum.Write(bstr)
|
||||||
|
return sm3sum.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SM3Str(bstr []byte) string {
|
||||||
|
return String(SM3(bstr))
|
||||||
|
}
|
259
sm3/sm3.go
Normal file
259
sm3/sm3.go
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sm3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SM3 struct {
|
||||||
|
digest [8]uint32 // digest represents the partial evaluation of V
|
||||||
|
length uint64 // length of the message
|
||||||
|
unhandleMsg []byte // uint8 //
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm3 *SM3) ff0(x, y, z uint32) uint32 { return x ^ y ^ z }
|
||||||
|
|
||||||
|
func (sm3 *SM3) ff1(x, y, z uint32) uint32 { return (x & y) | (x & z) | (y & z) }
|
||||||
|
|
||||||
|
func (sm3 *SM3) gg0(x, y, z uint32) uint32 { return x ^ y ^ z }
|
||||||
|
|
||||||
|
func (sm3 *SM3) gg1(x, y, z uint32) uint32 { return (x & y) | (^x & z) }
|
||||||
|
|
||||||
|
func (sm3 *SM3) p0(x uint32) uint32 { return x ^ sm3.leftRotate(x, 9) ^ sm3.leftRotate(x, 17) }
|
||||||
|
|
||||||
|
func (sm3 *SM3) p1(x uint32) uint32 { return x ^ sm3.leftRotate(x, 15) ^ sm3.leftRotate(x, 23) }
|
||||||
|
|
||||||
|
func (sm3 *SM3) leftRotate(x uint32, i uint32) uint32 { return x<<(i%32) | x>>(32-i%32) }
|
||||||
|
|
||||||
|
func (sm3 *SM3) pad() []byte {
|
||||||
|
msg := sm3.unhandleMsg
|
||||||
|
msg = append(msg, 0x80) // Append '1'
|
||||||
|
blockSize := 64 // Append until the resulting message length (in bits) is congruent to 448 (mod 512)
|
||||||
|
for len(msg)%blockSize != 56 {
|
||||||
|
msg = append(msg, 0x00)
|
||||||
|
}
|
||||||
|
// append message length
|
||||||
|
msg = append(msg, uint8(sm3.length>>56&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>48&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>40&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>32&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>24&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>16&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>8&0xff))
|
||||||
|
msg = append(msg, uint8(sm3.length>>0&0xff))
|
||||||
|
|
||||||
|
if len(msg)%64 != 0 {
|
||||||
|
panic("------SM3 Pad: error msgLen =")
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm3 *SM3) update(msg []byte) {
|
||||||
|
var w [68]uint32
|
||||||
|
var w1 [64]uint32
|
||||||
|
|
||||||
|
a, b, c, d, e, f, g, h := sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7]
|
||||||
|
for len(msg) >= 64 {
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
w[i] = binary.BigEndian.Uint32(msg[4*i : 4*(i+1)])
|
||||||
|
}
|
||||||
|
for i := 16; i < 68; i++ {
|
||||||
|
w[i] = sm3.p1(w[i-16]^w[i-9]^sm3.leftRotate(w[i-3], 15)) ^ sm3.leftRotate(w[i-13], 7) ^ w[i-6]
|
||||||
|
}
|
||||||
|
for i := 0; i < 64; i++ {
|
||||||
|
w1[i] = w[i] ^ w[i+4]
|
||||||
|
}
|
||||||
|
A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x79cc4519, uint32(i)), 7)
|
||||||
|
SS2 := SS1 ^ sm3.leftRotate(A, 12)
|
||||||
|
TT1 := sm3.ff0(A, B, C) + D + SS2 + w1[i]
|
||||||
|
TT2 := sm3.gg0(E, F, G) + H + SS1 + w[i]
|
||||||
|
D = C
|
||||||
|
C = sm3.leftRotate(B, 9)
|
||||||
|
B = A
|
||||||
|
A = TT1
|
||||||
|
H = G
|
||||||
|
G = sm3.leftRotate(F, 19)
|
||||||
|
F = E
|
||||||
|
E = sm3.p0(TT2)
|
||||||
|
}
|
||||||
|
for i := 16; i < 64; i++ {
|
||||||
|
SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x7a879d8a, uint32(i)), 7)
|
||||||
|
SS2 := SS1 ^ sm3.leftRotate(A, 12)
|
||||||
|
TT1 := sm3.ff1(A, B, C) + D + SS2 + w1[i]
|
||||||
|
TT2 := sm3.gg1(E, F, G) + H + SS1 + w[i]
|
||||||
|
D = C
|
||||||
|
C = sm3.leftRotate(B, 9)
|
||||||
|
B = A
|
||||||
|
A = TT1
|
||||||
|
H = G
|
||||||
|
G = sm3.leftRotate(F, 19)
|
||||||
|
F = E
|
||||||
|
E = sm3.p0(TT2)
|
||||||
|
}
|
||||||
|
a ^= A
|
||||||
|
b ^= B
|
||||||
|
c ^= C
|
||||||
|
d ^= D
|
||||||
|
e ^= E
|
||||||
|
f ^= F
|
||||||
|
g ^= G
|
||||||
|
h ^= H
|
||||||
|
msg = msg[64:]
|
||||||
|
}
|
||||||
|
sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7] = a, b, c, d, e, f, g, h
|
||||||
|
}
|
||||||
|
func (sm3 *SM3) update2(msg []byte) [8]uint32 {
|
||||||
|
var w [68]uint32
|
||||||
|
var w1 [64]uint32
|
||||||
|
|
||||||
|
a, b, c, d, e, f, g, h := sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7]
|
||||||
|
for len(msg) >= 64 {
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
w[i] = binary.BigEndian.Uint32(msg[4*i : 4*(i+1)])
|
||||||
|
}
|
||||||
|
for i := 16; i < 68; i++ {
|
||||||
|
w[i] = sm3.p1(w[i-16]^w[i-9]^sm3.leftRotate(w[i-3], 15)) ^ sm3.leftRotate(w[i-13], 7) ^ w[i-6]
|
||||||
|
}
|
||||||
|
for i := 0; i < 64; i++ {
|
||||||
|
w1[i] = w[i] ^ w[i+4]
|
||||||
|
}
|
||||||
|
A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x79cc4519, uint32(i)), 7)
|
||||||
|
SS2 := SS1 ^ sm3.leftRotate(A, 12)
|
||||||
|
TT1 := sm3.ff0(A, B, C) + D + SS2 + w1[i]
|
||||||
|
TT2 := sm3.gg0(E, F, G) + H + SS1 + w[i]
|
||||||
|
D = C
|
||||||
|
C = sm3.leftRotate(B, 9)
|
||||||
|
B = A
|
||||||
|
A = TT1
|
||||||
|
H = G
|
||||||
|
G = sm3.leftRotate(F, 19)
|
||||||
|
F = E
|
||||||
|
E = sm3.p0(TT2)
|
||||||
|
}
|
||||||
|
for i := 16; i < 64; i++ {
|
||||||
|
SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x7a879d8a, uint32(i)), 7)
|
||||||
|
SS2 := SS1 ^ sm3.leftRotate(A, 12)
|
||||||
|
TT1 := sm3.ff1(A, B, C) + D + SS2 + w1[i]
|
||||||
|
TT2 := sm3.gg1(E, F, G) + H + SS1 + w[i]
|
||||||
|
D = C
|
||||||
|
C = sm3.leftRotate(B, 9)
|
||||||
|
B = A
|
||||||
|
A = TT1
|
||||||
|
H = G
|
||||||
|
G = sm3.leftRotate(F, 19)
|
||||||
|
F = E
|
||||||
|
E = sm3.p0(TT2)
|
||||||
|
}
|
||||||
|
a ^= A
|
||||||
|
b ^= B
|
||||||
|
c ^= C
|
||||||
|
d ^= D
|
||||||
|
e ^= E
|
||||||
|
f ^= F
|
||||||
|
g ^= G
|
||||||
|
h ^= H
|
||||||
|
msg = msg[64:]
|
||||||
|
}
|
||||||
|
var digest [8]uint32
|
||||||
|
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7] = a, b, c, d, e, f, g, h
|
||||||
|
return digest
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建哈希计算实例
|
||||||
|
func New() hash.Hash {
|
||||||
|
var sm3 SM3
|
||||||
|
|
||||||
|
sm3.Reset()
|
||||||
|
return &sm3
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockSize returns the hash's underlying block size.
|
||||||
|
// The Write method must be able to accept any amount
|
||||||
|
// of data, but it may operate more efficiently if all writes
|
||||||
|
// are a multiple of the block size.
|
||||||
|
func (sm3 *SM3) BlockSize() int { return 64 }
|
||||||
|
|
||||||
|
// Size returns the number of bytes Sum will return.
|
||||||
|
func (sm3 *SM3) Size() int { return 32 }
|
||||||
|
|
||||||
|
// Reset clears the internal state by zeroing bytes in the state buffer.
|
||||||
|
// This can be skipped for a newly-created hash state; the default zero-allocated state is correct.
|
||||||
|
func (sm3 *SM3) Reset() {
|
||||||
|
// Reset digest
|
||||||
|
sm3.digest[0] = 0x7380166f
|
||||||
|
sm3.digest[1] = 0x4914b2b9
|
||||||
|
sm3.digest[2] = 0x172442d7
|
||||||
|
sm3.digest[3] = 0xda8a0600
|
||||||
|
sm3.digest[4] = 0xa96f30bc
|
||||||
|
sm3.digest[5] = 0x163138aa
|
||||||
|
sm3.digest[6] = 0xe38dee4d
|
||||||
|
sm3.digest[7] = 0xb0fb0e4e
|
||||||
|
|
||||||
|
sm3.length = 0 // Reset numberic states
|
||||||
|
sm3.unhandleMsg = []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write (via the embedded io.Writer interface) adds more data to the running hash.
|
||||||
|
// It never returns an error.
|
||||||
|
func (sm3 *SM3) Write(p []byte) (int, error) {
|
||||||
|
toWrite := len(p)
|
||||||
|
sm3.length += uint64(len(p) * 8)
|
||||||
|
msg := append(sm3.unhandleMsg, p...)
|
||||||
|
nblocks := len(msg) / sm3.BlockSize()
|
||||||
|
sm3.update(msg)
|
||||||
|
// Update unhandleMsg
|
||||||
|
sm3.unhandleMsg = msg[nblocks*sm3.BlockSize():]
|
||||||
|
|
||||||
|
return toWrite, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回SM3哈希算法摘要值
|
||||||
|
// Sum appends the current hash to b and returns the resulting slice.
|
||||||
|
// It does not change the underlying hash state.
|
||||||
|
func (sm3 *SM3) Sum(in []byte) []byte {
|
||||||
|
_, _ = sm3.Write(in)
|
||||||
|
msg := sm3.pad()
|
||||||
|
//Finalize
|
||||||
|
digest := sm3.update2(msg)
|
||||||
|
|
||||||
|
// save hash to in
|
||||||
|
needed := sm3.Size()
|
||||||
|
if cap(in)-len(in) < needed {
|
||||||
|
newIn := make([]byte, len(in), len(in)+needed)
|
||||||
|
copy(newIn, in)
|
||||||
|
in = newIn
|
||||||
|
}
|
||||||
|
out := in[len(in) : len(in)+needed]
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
binary.BigEndian.PutUint32(out[i*4:], digest[i])
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sm3Sum(data []byte) []byte {
|
||||||
|
var sm3 SM3
|
||||||
|
|
||||||
|
sm3.Reset()
|
||||||
|
_, _ = sm3.Write(data)
|
||||||
|
return sm3.Sum(nil)
|
||||||
|
}
|
64
sm3/sm3_test.go
Normal file
64
sm3/sm3_test.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sm3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func byteToString(b []byte) string {
|
||||||
|
ret := ""
|
||||||
|
for i := 0; i < len(b); i++ {
|
||||||
|
ret += fmt.Sprintf("%02x", b[i])
|
||||||
|
}
|
||||||
|
fmt.Println("ret = ", ret)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
func TestSm3(t *testing.T) {
|
||||||
|
msg := []byte("test")
|
||||||
|
err := ioutil.WriteFile("ifile", msg, os.FileMode(0644)) // 生成测试文件
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
msg, err = ioutil.ReadFile("ifile")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
hw := New()
|
||||||
|
hw.Write(msg)
|
||||||
|
hash := hw.Sum(nil)
|
||||||
|
fmt.Println(hash)
|
||||||
|
fmt.Printf("hash = %d\n", len(hash))
|
||||||
|
fmt.Printf("%s\n", byteToString(hash))
|
||||||
|
hash1 := Sm3Sum(msg)
|
||||||
|
fmt.Println(hash1)
|
||||||
|
fmt.Printf("%s\n", byteToString(hash1))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSm3(t *testing.B) {
|
||||||
|
t.ReportAllocs()
|
||||||
|
msg := []byte("test")
|
||||||
|
hw := New()
|
||||||
|
for i := 0; i < t.N; i++ {
|
||||||
|
|
||||||
|
hw.Sum(nil)
|
||||||
|
Sm3Sum(msg)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user