From e3fd6326dc7cc8810db2cd5481f2614c7bf5d95c Mon Sep 17 00:00:00 2001 From: zhuxianglong <56494565@qq.com> Date: Thu, 16 Jan 2025 00:24:06 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AD=BE=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/sign.go | 116 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/sdk/sign.go b/sdk/sign.go index 5591071..9c73496 100644 --- a/sdk/sign.go +++ b/sdk/sign.go @@ -9,57 +9,68 @@ import ( "sync" ) -// Order represents an order object used for signing parameters +// Order 表示订单对象,用于签名参数 type Order struct { - Uid string - BsTradeNo string - Role string - RoleId string - ServerId string - GoodsName string - OutTradeNo string - Body string - CpExtraInfo string - TradeState string - TotalFee string - PayFee string - PayTime string + Uid string // 用户ID + BsTradeNo string // 交易编号 + Role string // 用户角色 + RoleId string // 角色ID + ServerId string // 服务器ID + GoodsName string // 商品名称 + OutTradeNo string // 外部交易编号 + Body string // 商品描述 + CpExtraInfo string // 扩展信息 + TradeState string // 交易状态 + TotalFee string // 总费用 + PayFee string // 支付费用 + PayTime string // 支付时间 } -// Config holds the configuration for SDK, such as appId and secret keys +// Config 用于保存SDK的配置信息,例如appId和secretKey type Config struct { - SecretKey string + SecretKey string // 秘钥 } -// SDK struct encapsulates SDK configuration and utility functions +// SDK结构体封装了SDK的配置和工具函数 type SDK struct { - SecretKey string + SecretKey string // 秘钥 } -// Singleton instance and mutex for thread safety +// 单例实例和互斥锁,确保线程安全 var instance *SDK -var once2 sync.Once +var onces sync.Once -// New initializes a new SDK with the given configuration, but ensures that only one instance exists. +// New 返回一个SDK单例实例,初始化时传入秘钥 func New(secretKey string) *SDK { - once2.Do(func() { + onces.Do(func() { instance = &SDK{ SecretKey: secretKey, } }) - return instance + return instance // 返回单例实例 } -// Md5String generates MD5 hash of a given string +// Md5String 生成给定字符串的MD5哈希值并返回十六进制字符串 func (s *SDK) Md5String(str string) string { - hash := md5.Sum([]byte(str)) // Use md5.Sum for fixed size output - return hex.EncodeToString(hash[:]) + hash := md5.Sum([]byte(str)) // 计算MD5哈希 + return hex.EncodeToString(hash[:]) // 转为十六进制字符串并返回 } -// SignParam generates a signed URL-encoded string for the provided Order object +// SignParam 为提供的Order对象生成签名 func (s *SDK) SignParam(order *Order) (string, error) { - // Create a map of the parameters to be signed - paramMap := map[string]string{ + // 创建待签名参数映射 + paramMap := s.createParamMap(order) + + // 按照字典顺序排序并生成待签名字符串 + signStr := s.buildSignString(paramMap) + + // 计算最终签名并返回 + return s.Md5String(signStr), nil +} + +// createParamMap 构建参数映射,跳过 "sign" 和 "-" 键 +func (s *SDK) createParamMap(order *Order) map[string]string { + return map[string]string{ "uid": order.Uid, "bs_trade_no": order.BsTradeNo, "role": order.Role, @@ -73,43 +84,46 @@ func (s *SDK) SignParam(order *Order) (string, error) { "total_fee": order.TotalFee, "pay_fee": order.PayFee, "pay_time": order.PayTime, - "sign": "", + "sign": "", // 初始化签名为空 } - - // Generate the signed value - signStr := s.SortMapString(paramMap) + s.SecretKey - - // Return the MD5 hash - return s.Md5String(signStr), nil } -// SortMapString sorts the keys of a map and returns a concatenated string -func (s *SDK) SortMapString(params map[string]string) string { +// buildSignString 按照字典顺序排序参数并拼接成签名字符串 +func (s *SDK) buildSignString(params map[string]string) string { var builder strings.Builder - keys := make([]string, 0, len(params)) + keys := s.getSortedKeys(params) // 获取排序后的键 + + // 拼接所有键对应的值 + for _, k := range keys { + builder.WriteString(params[k]) + } + + // 将秘钥追加到签名字符串后 + builder.WriteString(s.SecretKey) + + return builder.String() +} - // Avoid sorting the "sign" and "-" keys +// getSortedKeys 返回排除 "sign" 和 "-" 键后的排序键列表 +func (s *SDK) getSortedKeys(params map[string]string) []string { + var keys []string for k := range params { + // 跳过 "sign" 和 "-" 键 if k == "sign" || k == "-" { continue } keys = append(keys, k) } - sort.Strings(keys) // Sort the keys - - // Efficiently concatenate the values - for _, k := range keys { - builder.WriteString(params[k]) - } - - return builder.String() + sort.Strings(keys) // 排序键 + return keys } -// ToJson converts an interface{} to JSON string +// ToJson 将一个接口类型转换为JSON字符串 func (s *SDK) ToJson(item interface{}) (string, error) { + // 使用json.Marshal将对象转换为JSON res, err := json.Marshal(item) if err != nil { - return "", err // Simplified error handling + return "", err // 返回错误 } - return string(res), nil + return string(res), nil // 返回JSON字符串 }