package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/des"
"fmt"
"github.com/xxtea/xxtea-go/xxtea"
"io/ioutil"
"os"
"runtime"
"time"
)
func zeroPadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{0}, padding)
return append(ciphertext, padtext...)
}
func zeroUnPadding(origData []byte) []byte {
return bytes.TrimFunc(origData,
func(r rune) bool {
return r == rune(0)
})
}
func checkError(err error) {
if err != nil {
fmt.Println("Error:", err)
}
}
func getRunTime(fn func([]byte, []byte) []byte, data []byte, key []byte, method string, suffix string) ([]byte, float64) {
start := time.Now()
result := fn(data, key)
end := time.Now()
//fmt.Println(method, suffix, "cost:", end.Sub(start))
return result, end.Sub(start).Seconds()
}
func desEncrypt(data, key []byte) []byte {
block, err := des.NewCipher(key)
checkError(err)
data = zeroPadding(data, block.BlockSize())
//初始向量使用key
blockMode := cipher.NewCBCEncrypter(block, key)
blockMode.CryptBlocks(data, data)
return data
}
func desDecrypt(data, key []byte) []byte {
block, err := des.NewCipher(key)
checkError(err)
blockMode := cipher.NewCBCDecrypter(block, key)
blockMode.CryptBlocks(data, data)
data = zeroUnPadding(data)
return data
}
func tdesEncrypt(data, key []byte) []byte {
block, err := des.NewTripleDESCipher(key)
checkError(err)
data = zeroPadding(data, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key[:8])
blockMode.CryptBlocks(data, data)
return data
}
func tdesDecrypt(data, key []byte) []byte {
block, err := des.NewTripleDESCipher(key)
checkError(err)
blockMode := cipher.NewCBCDecrypter(block, key[:8])
blockMode.CryptBlocks(data, data)
data = zeroUnPadding(data)
return data
}
func aesEncrypt(data, key []byte) []byte {
block, err := aes.NewCipher(key)
checkError(err)
data = zeroPadding(data, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key)
blockMode.CryptBlocks(data, data)
return data
}
func aesDecrypt(data, key []byte) []byte {
block, err := aes.NewCipher(key)
checkError(err)
blockMode := cipher.NewCBCDecrypter(block, key)
blockMode.CryptBlocks(data, data)
data = zeroUnPadding(data)
return data
}
func xxteaEncrypt(data, key []byte) []byte {
data = xxtea.Encrypt(data, key)
return data
}
func xxteaDecrypt(data, key []byte) []byte {
data = xxtea.Decrypt(data, key)
return data
}
var (
deskey = []byte(`12345678`)
tdeskey = []byte(`123456781234567812345678`)
aeskey = []byte(`1234567812345678`)
xxteakey = []byte(`1234567812345678`)
)
func main() {
if len(os.Args) < 2 {
fmt.Println("plz input filename of orignal data")
os.Exit(-1)
}
start := time.Now()
content, err := ioutil.ReadFile(os.Args[1])
checkError(err)
originalSize := len(content)
fmt.Println("orignal file size = ", originalSize)
fmt.Println("read file cost: ", time.Since(start))
encryptFuncs := []func([]byte, []byte) []byte{tdesEncrypt, aesEncrypt, desEncrypt, xxteaEncrypt}
decryptFuncs := []func([]byte, []byte) []byte{tdesDecrypt, aesDecrypt, desDecrypt, xxteaDecrypt}
keys := [][]byte{tdeskey, aeskey, deskey, xxteakey}
methods := []string{"3des", "aes", "des", "xxtea"}
suffix := []string{"encrypt", "decrypt"}
for i, encryptFunc := range encryptFuncs {
data, cost := getRunTime(encryptFunc, content, keys[i], methods[i], suffix[0])
//ioutil.WriteFile("/tmp/benchmark_"+methods[i]+"_"+suffix[0], data, 0666)
encryptedSize := len(data)
fmt.Printf("%s\t%s rate: %.2fM/s\t%f\t", methods[i], suffix[0], float64(originalSize)/cost/1000000, cost)
//data, err = ioutil.ReadFile("/tmp/benchmark_" + methods[i] + "_" + suffix[0])
checkError(err)
data, cost = getRunTime(decryptFuncs[i], data, keys[i], methods[i], suffix[1])
//ioutil.WriteFile("/tmp/benchmark_"+methods[i]+"_"+suffix[1], data, 0666)
content = data
fmt.Printf("\t%s rate:%.2fM/s\t%f\t%dM\t%dM\n", suffix[1], float64(encryptedSize)/cost/1000000, cost, originalSize/1024/1024, encryptedSize/1024/1024)
runtime.GC()
}
}
评论