
# 自定义模板内部函数
#### 使用说明
华为云IoTDA提供了多个内部函数供用户在模板中使用，使用时请认真阅读每个函数的功能定义，包括入参类型，参数长度，返回值类型等。
![](https://support.huaweicloud.com/devg-iothub/public_sys-resources/note_3.0-zh-cn.png)
- 整个函数必须是合法的Json格式。
- 函数中可使用${}变量占位符或者"Ref"函数引用入参定义的参数值。
- 函数所使用的参数必须在模板参数中声明。
- 单一入参的函数后面直接跟参数，比如："Fn::Base64Decode": "${iotda::mqtt::username}"。
- 多个入参的函数后面接数组格式，比如："Fn::HmacSHA256": \["${iotda::mqtt::username}", "${iotda::device::secret}"\]。
- 函数可以嵌套使用，即一个函数的参数可以是另一个函数，注意嵌套函数的返回值必须跟当前函数参数类型一致，比如：{"Fn::HmacSHA256": \["${iotda::mqtt::username}", {"Fn::Base64Encode": "${iotda::device::secret}"}\]}
- 整个鉴权模板中hash函数（Fn::HmacSHA256）最多出现两次
- 整个鉴权模板中BASE64函数（Fn::Base64Decode Fn::Base64Encode）个数的和 不能超过2个
- 鉴权模板中密码进行HmacSHA256Function之后的结果不允许 在进行Fn::Split（字符串拆分函数）Fn::SplitSelect（字符串拆分选取函数）Fn::SubStringAfter（字符串拆分函数，截取分隔符后面字符） Fn::SubStringBefor（字符串拆分函数，截取分隔符前面字符）操作。
 
#### Fn::ArraySelect
内部函数Fn::ArraySelect返回一个字符串数组中索引为index的字符串元素。
**JSON**
```
{"Fn::ArraySelect": [index, [StringArray]]}
```
表1参数说明 
| 参数名称        | 类型         | 说明                 |
|:---|:---|:---|
| index       | int        | 整型，数组元素索引值，从0开始计算。 |
| StringArray | String\[\] | 字符串数组元素。           |
| 返回值         | String     | 索引为index的元素。       |
   
示例如下：
```
{
"Fn::ArraySelect": [1, ["123", "456", "789"]]
}
return: "456"
```
#### Fn::Base64Decode
内部函数Fn::Base64Decode将一个字符串按BASE64解码成一个字节数组。
**JSON**
```
{ "Fn::Base64Decode" : "content" }
```
表2参数说明 
| 参数名称    | 类型       | 说明              |
|:---|:---|:---|
| content | String   | 待解码的字符串。        |
| 返回值     | byte\[\] | base64解码后的字节数组。 |
   
示例如下：
```
{
"Fn::Base64Decode": "123456"]
}
return: d76df8e7 //为了方便展示，此处转化为16进制字符串
```
#### Fn::Base64Encode
内部函数Fn::Base64Encode将一个字符串按BASE64编码。
**JSON**
```
{"Fn::Base64Encode": "content"}
```
表3参数说明 
| 参数名称    | 类型     | 说明             |
|:---|:---|:---|
| content | String | 待编码的字符串。       |
| 返回值     | String | base64编码后的字符串。 |
   
示例如下：
```
{
"Fn::Base64Encode": "testvalue"
}
return: "dGVzdHZhbHVl"
```
#### Fn::GetBytes
内部函数Fn::GetBytes返回一个字符串UTF-8编码的字节数组。
**JSON**
```
{"Fn::GetBytes": "content"}
```
表4参数说明 
| 参数名称    | 类型       | 说明                |
|:---|:---|:---|
| content | String   | 待编码的字符串。          |
| 返回值     | byte\[\] | 字符串UTF-8编码后的字节数组。 |
   
示例如下：
```
{
"Fn::GetBytes": "testvalue"
}
return: "7465737476616c7565" //为了方便展示，此处转化为16进制字符串
```
#### Fn::HmacSHA256
内部函数Fn::HmacSHA256将一个字符串按给定密钥进行HmacSHA256算法加密。
**JSON**
```
{"Fn::HmacSHA256": ["content", "secret"]}
```
表5参数说明 
| 参数名称    | 类型                | 说明                   |
|:---|:---|:---|
| content | String            | 待加密的字符串。             |
| secret  | String 或 byte\[\] | 加密密钥，可以是字符串或者字节数组类型  |
| 返回值     | String            | 使用HmacSHA256算法加密后的值。 |
   
示例如下：
```
{
"Fn::HmacSHA256": ["testvalue", "123456"]
}
return: "0f9fb47bd47449b6ffac1be951a5c18a7eff694940b1a075b973ff9054a08be3"
```
#### Fn::Join
内部函数Fn::Join可将多个字符串（数量最大值为10）拼接成一个字符串。
**JSON**
```
{"Fn::Join": ["element", "element"...]}
```
表6参数说明 
| 参数名称    | 类型     | 说明              |
|:---|:---|:---|
| element | String | 需拼接的字符串。        |
| 返回值     | String | 子字符串拼接在一起后的字符串。 |
   
示例如下：
```
{
"Fn::Join": ["123", "456", "789"]
}
return: "123456789"
```
#### Fn::MathAdd
内部函数Fn::MathAdd将两个整数进行数学加法运算。
**JSON**
```
{"Fn::MathAdd": [X, Y]}
```
表7参数说明 
| 参数名称 | 类型   | 说明        |
|:---|:---|:---|
| X    | long | 加数。       |
| Y    | long | 加数。       |
| 返回值  | long | 和，X+Y后的值。 |
   
示例如下：
```
{
"Fn::MathAdd": [1, 1]
}
return: 2
```
#### Fn::MathDiv
内部函数Fn::MathDiv将两个整数进行数学除法运算。
**JSON**
```
{"Fn::MathDiv": [X, Y]}
```
表8参数说明 
| 参数名称 | 类型   | 说明       |
|:---|:---|:---|
| X    | long | 被除数。     |
| Y    | long | 除数。      |
| 返回值  | long | X 除Y后的值。 |
   
示例如下：
```
{
"Fn::MathDiv": [10, 2]
}
return: 5
{
"Fn::MathDiv": [10, 3]
}
return: 3
```
#### Fn::MathMod
内部函数Fn::MathMod将两个整数进行数学取余运算。
**JSON**
```
{"Fn::MathMod": [X, Y]}
```
表9参数说明 
| 参数名称 | 类型   | 说明         |
|:---|:---|:---|
| X    | long | 被取余数。      |
| Y    | long | 取余数。       |
| 返回值  | long | X 取余 Y后的值。 |
   
示例如下：
```
{
"Fn::MathMod": [10, 3]
}
return: 1
```
#### Fn::MathMultiply
内部函数Fn::MathMultiply将两个整数进行数学乘法运算。
**JSON**
```
{"Fn::MathMultiply": [X, Y]}
```
表10参数说明 
| 参数名称 | 类型   | 说明         |
|:---|:---|:---|
| X    | long | 乘数。        |
| Y    | long | 乘数。        |
| 返回值  | long | X 乘以 Y后的值。 |
   
示例如下：
```
{
"Fn::MathMultiply": [3, 3]
}
return: 9
```
#### Fn::MathSub
内部函数Fn::MathSub将两个整数进行数学减法运算。
**JSON**
```
{"Fn::MathSub": [X, Y]}
```
表11参数说明 
| 参数名称 | 类型   | 说明        |
|:---|:---|:---|
| X    | long | 被减数。      |
| Y    | long | 减数。       |
| 返回值  | long | X 减 Y后的值。 |
   
示例如下：
```
{
"Fn::MathSub": [9, 3]
}
return: 6
```
#### Fn::ParseLong
内部函数Fn::ParseLong可将一个数字字符串转化为整数。
**JSON**
```
{"Fn::ParseLong": "String"}
```
表12参数说明 
| 参数名称   | 类型     | 说明           |
|:---|:---|:---|
| String | String | 待转换的字符串。     |
| 返回值    | long   | 字符串转换为数字后的值。 |
   
示例如下：
```
{
"Fn::ParseLong": "123"
}
return: 123
```
#### Fn::Split
内部函数Fn::Split将一个字符串按指定的分隔符分割成字符串数组。
**JSON**
```
{ "Fn::Split" : ["String", "Separator"] }
```
表13参数说明 
| 参数名称      | 类型         | 说明                                |
|:---|:---|:---|
| String    | String     | 被分割的字符串。                          |
| Separator | String     | 分隔符。                              |
| 返回值       | String\[\] | 原始参数String被分隔符Separator拆分后的字符串数组。 |
   
示例如下：
```
{
"Fn::Split": ["a|b|c", "|"]
}
return: ["a", "b", "c"]
```
#### Fn::SplitSelect
内部函数Fn::SplitSelect将一个字符串按指定的分隔符分割成字符串数组，然后返回数组指定索引的元素。
**JSON**
```
{ "Fn::SplitSelect" : ["String", "Separator", index] }
```
表14参数说明 
| 参数名称      | 类型     | 说明                     |
|:---|:---|:---|
| String    | String | 被分割的字符串。               |
| Separator | String | 分隔符。                   |
| index     | int    | 返回元素在数组中的索引值，从0开始。     |
| 返回值       | String | 字符串按特定分隔符分割后指定索引的子字符串。 |
   
示例如下：
```
{
"Fn::SplitSelect": ["a|b|c", "|", 1]
}
return: "b"
```
#### Fn::Sub
内部函数Fn::Sub将输入字符串中的变量替换为指定的值。在模板中您可以使用此函数来构造一个动态的字符串。
**JSON**
```
{ "Fn::Sub" : [ "String", { "Var1Name": Var1Value, "Var2Name": Var2Value } ] }
```
表15参数说明 
| 参数名称     | 类型     | 说明                         |
|:---|:---|:---|
| String   | String | 一个包含变量的字符串，变量使用"${}"占位符定义。 |
| VarName  | String | 变量名称，必须在参数"String"中定义。     |
| VarValue | String | 变量的取值，支持函数嵌套。              |
| 返回值      | String | 返回原始"String"参数字符串变量替换后的值。  |
   
示例如下：
```
{
"Fn::Sub": ["${token};hmacsha256", {
"token": {
"Fn::HmacSHA256": ["${iotda::mqtt::username}", {
"Fn::Base64Decode": "${iotda::mqtt::client_id}"
}]
}
}]
}
当变量
${iotda::mqtt::username}="test_device_username"
${iotda::device::client_id}="OozqTPlCWTTJjEH/5s+T6w=="
return："0773c4fd6c92902a1b2f4a45fdcdec416b6fc2bc6585200b496e460e2ef31c3d"
```
#### Fn::SubStringAfter
内部函数Fn::SubStringAfter截取字符串指定分隔符后的子字符串。
**JSON**
```
{ "Fn::SubStringAfter" : ["content", "separator"] }
```
表16参数说明 
| 参数名称      | 类型     | 说明                 |
|:---|:---|:---|
| content   | String | 待截取的字符串。           |
| separator | String | 分隔符。               |
| 返回值       | String | 字符串被指定分隔符分割后的子字符串。 |
   
示例如下：
```
{
"Fn::SubStringAfter": ["content:123456", ":"]
]
return: "123456"
```
#### Fn::SubStringBefore
内部函数Fn::SubStringBefore截取字符串指定分隔符前的子字符串。
**JSON**
```
{ "Fn::SubStringBefore" : ["content", "separator"] }
```
表17参数说明 
| 参数名称      | 类型     | 说明                 |
|:---|:---|:---|
| content   | String | 待截取的字符串。           |
| separator | String | 分隔符。               |
| 返回值       | String | 字符串被指定分隔符分割前的子字符串。 |
   
示例如下：
```
{
"Fn::SubStringBefore": ["content:123456", ":"]
]
return: "content"
```
#### Fn::ToLowerCase
内部函数Fn::ToLowerCase将指定字符串转的所有字符转化成小写。
**JSON**
```
{ "Fn::ToLowerCase" : content }
```
表18参数说明 
| 参数名称    | 类型     | 说明           |
|:---|:---|:---|
| content | String | 待转换的字符串。     |
| 返回值     | String | 字符串被转为小写后的值。 |
   
示例如下：
```
{
"Fn::ToLowerCase": "ABC"
]
return: "abc"
```
#### Fn::ToUpperCase
内部函数Fn::ToUpperCase将字符串转大写函数。
**JSON**
```
{ "Fn::ToUpperCase" : content }
```
表19参数说明 
| 参数名称    | 类型     | 说明           |
|:---|:---|:---|
| content | String | 待转换的字符串。     |
| 返回值     | String | 字符串被转为大写后的值。 |
   
示例如下：
```
{
"Fn::ToUpperCase": "abc"
]
return: "ABC"
```
#### Ref
内部函数Ref将返回指定引用参数的值，引用参数必须在模板中有声明。
**JSON**
```
{ "Ref" : "paramName" }
```
表20参数说明 
| 参数名称      | 类型     | 说明        |
|:---|:---|:---|
| paramName | String | 引用的参数名称。  |
| 返回值       | String | 引用参数对应的值。 |
   
示例如下：
```
{
"Ref": "iotda::mqtt::username"
}
当参数iotda::mqtt::username="device_123"
return: "device_123"
```
