签名算法代码实例

为了帮助理解签名规则,这里提供了部分语言的签名算法实现以供参考。目前支持三种语言:Python、Go和PHP。
入参payload为需要签名的数据字典。请求的json里第一层参数和值的组合。 理论上应该仅包含参与计算的kv,但是程序也做了过滤。

其他参数请根据实际情况替换

Python

import json
import time
import hashlib
import requests


def create_headers(payload):
    """
    创建验签所需信息
    :param payload: 需要签名的数据字典,其中不应包含列表、字典或长于1024个字符的字符串。
    :return:
    """
    sid = 123456
    secret = 'XXXXXX'
    time_stamp = int(time.time())

    # 过滤掉列表、字典或过长的字符串和数值
    filtered_data = {k: v for k, v in payload.items() if not isinstance(v, (list, dict)) and len(str(v)) <= 1024}
    filtered_data['sid'] = sid
    filtered_data['timeStamp'] = time_stamp

    sorted_items = sorted(filtered_data.items())  # 将字典项排序
    sign_string = "&".join(f"{key}={value}" for key, value in sorted_items)   # 构建用于签名的字符串

    # 拼接签名密钥
    sign_string += "&key={}".format(secret)
    sign = hashlib.md5(sign_string.encode('utf-8')).hexdigest()

    headers = {
        'X-EEO-SIGN': sign,
        'X-EEO-UID': f'{sid}',
        'X-EEO-TS': f'{time_stamp}',
        'Content-Type': 'application/json'
    }
    print(f'headers: {headers}')
    return headers

Go

import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "sort"
    "strconv"
    "strings"
    "time"
)

func createHeaders(payload map[string]interface{}) map[string]string {
    sid := 123456
    secret := "XXXXXX"
    timeStamp := strconv.FormatInt(time.Now().Unix(), 10)

    // 过滤掉列表、字典或过长的字符串和数值
    var filteredData []string
    for k, v := range payload {
        switch v.(type) {
        case []interface{}, map[string]interface{}, string:
            if str, ok := v.(string); ok && len(str) <= 1024 {
                filteredData = append(filteredData, fmt.Sprintf("%s=%v", k, v))
            }
        default:
            if num, ok := v.(int); ok {
                filteredData = append(filteredData, fmt.Sprintf("%s=%d", k, num))
            }
        }
    }

    // 添加 sid 和 timeStamp
    filteredData = append(filteredData, "sid="+strconv.Itoa(sid))
    filteredData = append(filteredData, "timeStamp="+timeStamp)

    // 将字典项排序
    sort.Strings(filteredData)

    // 构建用于签名的字符串
    signString := strings.Join(filteredData, "&")
    signString += "&key=" + secret
    fmt.Printf("signString: %s\n", signString)
    // 使用MD5算法生成签名
    hash := md5.Sum([]byte(signString))
    sign := hex.EncodeToString(hash[:])

    headers := map[string]string{
        "X-EEO-SIGN":   sign,
        "X-EEO-UID":    strconv.Itoa(sid),
        "X-EEO-TS":     timeStamp,
        "Content-Type": "application/json",
    }

    return headers
}

PHP

<?php
function createHeaders($payload) {
    $sid = 123456;
    $secret = 'XXXXXX';
    $timeStamp = time();

    // 过滤掉数组、对象或过长的字符串
    $filteredData = array_filter($payload, function ($value) {
        return !is_array($value) && !is_object($value) && strlen($value) <= 1024;
    });

    // 将 sid 和 timeStamp 添加到过滤后的数据中
    $filteredData['sid'] = $sid;
    $filteredData['timeStamp'] = $timeStamp;

    // 将数组项按键排序
    ksort($filteredData);

    // 构建用于签名的字符串
    $signString = http_build_query($filteredData) . "&key=" . $secret;

    // 计算签名
    $sign = md5($signString);

    $headers = array(
        'X-EEO-SIGN: ' . $sign,
        'X-EEO-UID: ' . $sid,
        'X-EEO-TS: ' . $timeStamp,
        'Content-Type: application/json'
    );

    // 输出 headers 信息,实际使用时可以去掉
    echo 'headers: '; print_r($headers);

    return $headers;
}

?>

results matching ""

    No results matching ""