签名生成方法如下：

- 对所有请求参数（包括公有参数和私有参数，但不包括 `signature` 参数），按照参数名 ASCII 码表升序顺序排序。如：foo=1， bar=2， foo_bar=3， baz=4 排序后的顺序是bar=2，baz=4，foo=1，foo_bar=3。
- 将排序好的参数名和参数值构造成字符串，格式为：key1+value1+key2+value2…。根据上面的示例得到的构造结果为：bar2baz4foo1foo_bar3。
- 选择与 `secretId` 配对的 `secretKey`，加到上一步构造好的参数字符串之后，如secretKey=6308afb129ea00301bd7c79621d07591 ，则最后的参数字符串为bar2baz4foo1foobar_36308afb129ea00301bd7c79621d07591。
- 把以上拼装好的字符串采用 UTF-8 编码，使用 `MD5` 算法对字符串进行摘要，计算得到`signature` 参数值，将其加入到接口请求参数中即可。`MD5` 是 128 位长度的摘要算法，用 16 进制表示，一个十六进制的字符能表示 4 个位，所以签名后的字符串长度固定为 32 位十六进制字符。

签名生成示例代码：

<md-tab>

<md-pane md-title="java">

```java
详细签名方法见：https://github.com/yidun/antispam-java-demo/blob/master/src/main/java/com/netease/is/antispam/demo/utils/SignatureUtils.java

/**
 * 生成签名信息
 * @param secretKey 产品私钥
 * @param params 接口请求参数名和参数值map，不包括signature参数名
 * @return
 */
public static String genSignature(String secretKey, Map<String, String> params){
    // 1. 参数名按照ASCII码表升序排序
    String[] keys = params.keySet().toArray(new String[0]);
    Arrays.sort(keys);

    // 2. 按照排序拼接参数名与参数值
    StringBuilder sb = new StringBuilder();
    for (String key : keys) {
        sb.append(key).append(params.get(key));
    }
    // 3. 将secretKey拼接到最后
    sb.append(secretKey);

    // 4. MD5是128位长度的摘要算法，转换为十六进制之后长度为32字符
    return DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
}
```

</md-pane>

<md-pane md-title="python">

```python
详细签名方法见：https://github.com/yidun/antispam-python-demo/blob/master/mediasolution/mediasolution_submit.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""生成签名信息
Args:
    secretKey 产品私钥
    params 接口请求参数，不包括signature参数
"""
def gen_signature(secretKey, params=None):
        params_str = ""
        for k in sorted(params.keys()):
            params_str += str(k)+ str(params[k])

        params_str += secretKey
        return hashlib.md5(params_str.encode("utf8")).hexdigest()
```

</md-pane>

<md-pane md-title="PHP">


```PHP
详细签名方法见：https://github.com/yidun/antispam-php-demo/blob/master/util.php

/**
 * 生成签名信息
 * $secretKey 产品私钥
 * $params 接口请求参数，不包括signature参数
 */
function gen_signature($secretKey,$params){
	ksort($params);
	$buff="";
	foreach($params as $key=>$value){
		$buff .=$key;
		$buff .=$value;
	}
	$buff .= $secretKey;
	return md5(mb_convert_encoding($buff, "utf8", "auto"));
}
```

</md-pane>

<md-pane md-title="C#">

```csharp
详细签名方法见：https://github.com/yidun/antispam-csharp-demo/blob/master/Utils.cs

// 生成签名信息
public static String genSignature(String secretKey, Dictionary<String, String> parameters)
{
    parameters = parameters.OrderBy(o => o.Key,StringComparer.Ordinal).ToDictionary(o => o.Key, p => p.Value);

    StringBuilder builder = new StringBuilder();
    foreach (KeyValuePair<String, String> kv in parameters)
    {
        builder.Append(kv.Key).Append(kv.Value);
    }
    builder.Append(secretKey);
    String tmp = builder.ToString();
    MD5 md5 = new MD5CryptoServiceProvider();
    byte[] result = md5.ComputeHash(Encoding.UTF8.GetBytes(tmp));
    builder.Clear();
    foreach (byte b in result)
    {
        builder.Append(b.ToString("x2").ToLower());
    }
    return builder.ToString();
}
```

</md-pane>

<md-pane md-title="JS">


```js
详细签名方法见：https://github.com/yidun/antispam-nodejs-demo/blob/master/utils.js

var genSignature=function(secretKey,paramsJson){
    var sorter=function(paramsJson){
        var sortedJson={};
        var sortedKeys=Object.keys(paramsJson).sort();
        for(var i=0;i<sortedKeys.length;i++){
            sortedJson[sortedKeys[i]] = paramsJson[sortedKeys[i]]
        }
        return sortedJson;
    }
    var sortedParam=sorter(paramsJson);
    var needSignatureStr="";
    for(var key in sortedParam){
        var value=sortedParam[key];
        needSignatureStr=needSignatureStr+key+value;
    }
    needSignatureStr+=secretKey;
    var md5er = crypto.createHash('md5');//MD5加密工具
    md5er.update(needSignatureStr,"UTF-8");
    return md5er.digest('hex');
};
```
</md-pane>

<md-pane md-title="go">

```go
详细签名方法见：https://github.com/yidun/antispam-go-demo/blob/master/mediasolution/submit/mediasolution_submit.go
	
// 生成签名信息
func genSignature(params url.Values) string {
	var paramStr string
	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, key := range keys {
		paramStr += key + params[key][0]
	}
	paramStr += secretKey
	if params["signatureMethod"] != nil && params["signatureMethod"][0] == "SM3" {
		sm3Reader := sm3.New()
		sm3Reader.Write([]byte(paramStr))
		return hex.EncodeToString(sm3Reader.Sum(nil))
	} else {
		md5Reader := md5.New()
		md5Reader.Write([]byte(paramStr))
		return hex.EncodeToString(md5Reader.Sum(nil))
	}
}
```
</md-pane>

</md-tab>