云服务器内容精选

  • 约束与限制 使用自定义鉴权功能,要求设备必须使用TLS同时支持SNI(Server Name Indication),SNI中需要携带平台分配的域名。 每个用户默认最多支持10个自定义鉴权的配置。 自定义鉴权的函数最大处理时间为5秒,5秒内函数没返回结果,则认为鉴权失败。 每个用户总鉴权请求的TPS限制参考产品规格说明,自定义鉴权为总鉴权TPS的50%(不包含设备自注册)。 若用户开启了缓存FunctionGraph的鉴权结果,则在相同参数下,函数服务的修改生效时间需在缓存超期后才能生效。 在所有的设备接入鉴权方式中,当满足自定义鉴权条件时(匹配到设备携带的自定义鉴权器名称或用户配置了默认自定义鉴权器),优先采用自定义鉴权方式进行设备接入。
  • 概述 自定义鉴权是指用户可以通过函数服务自定义实现鉴权逻辑,以对接入平台的设备进行身份认证。 在设备接入物联网平台前,用户可以通过应用服务调用控制台配置自定义鉴权信息,然后通过调用函数服务(FunctionGraph入门简介)配置自定义鉴权函数。在设备接入物联网平台时,物联网平台会获取设备ID和自定义鉴权函数名称等参数,并向FunctionGraph发起发起鉴权请求,由用户实现鉴权逻辑以完成设备的接入鉴权。
  • 用户名密码认证模式 本地安装完成ModelArts SDK后,可通过用户名密码认证模式进行Session鉴权。示例代码如下: 使用账号认证 “username”填写您的账号名。 1 2 3 4 5 6 7 from modelarts.session import Session # 认证用的password硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以password保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_PASSWORD。 __PASSWORD = os.environ["HUAWEICLOUD_SDK_PASSWORD"] # 如果进行了加密还需要进行解密操作 session = Session(username='***', password=__PASSWORD, region_name='***', project_id='***') 使用IAM用户认证 “account”填写您的账号名,“username”填写您的IAM用户名。 1 2 3 4 5 6 7 from modelarts.session import Session # 认证用的password硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以password保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_PASSWORD。 __PASSWORD = os.environ["HUAWEICLOUD_SDK_PASSWORD"] # 如果进行了加密还需要进行解密操作 session = Session(account='***', username='***', password=__PASSWORD, region_name='***', project_id='***') 账号与用户的概念介绍,请参见IAM基本概念。获取您的账号、用户名等信息,请参见获取用户名、用户ID、项目名称、项目ID。 如果您的华为云账号已经升级为华为账号,则账号认证方式将不可用,请创建一个IAM用户,使用IAM用户认证。
  • Session鉴权概述 Session模块的主要作用是实现与公有云资源的鉴权,并初始化ModelArts SDK Client、OBS Client。当成功建立Session后,您可以直接调用ModelArts的SDK接口。 ModelArts开发环境Notebook不需要Session鉴权,可以直接使用。示例代码如下: 1 2 from modelarts.session import Session session = Session() 本地PC使用ModelArts SDK时,需要进行Session鉴权。鉴权方式可参考如下认证方式,选择其中一种方式进行认证即可。 用户名密码认证模式: 支持OBS管理、数据管理、训练管理、模型管理、服务管理的鉴权。 用户AK-SK认证模式: 支持OBS管理、数据管理、训练管理、模型管理、服务管理的鉴权。
  • 示例2 设备ID格式为:${ProductId}_${NodeId}。 表2 鉴权参数 参数 说明 Client ID 固定格式: ${ClientId}|securemode=2,signmethod=hmacsha256|timestamp=${timestamp}| ${ClientId}: 固定格式 ${ProductId}.${NodeId}。 ${NodeId}: 设备标识码。 ${ProductId}:产品ID。 ${timestamp}:Unix时间戳,毫秒。 User Name 由设备标识码和产品ID组成,固定格式: ${NodeId}&${ProductId} Password 以设备密码为密钥,将设备参数与参数值拼接后的字符串为加密串进行hmacsha256算法加密。 加密串格式: clientId${clientId}deviceName${nodeId}productKey${productId}timestamp${timestamp} ${ClientId}: 固定格式 ${ProductId}.${NodeId}。 ${NodeId}: 设备标识码。 ${ProductId}:产品ID。 ${timestamp}:时间戳。 鉴权模板: { "template_name": "template2", "description": "template2", "template_body": { "parameters": { "iotda::mqtt::client_id": { "type": "String" }, "iotda::mqtt::username": { "type": "String" }, "iotda::device::secret": { "type": "String" } }, "resources": { "device_id": { "Fn::Join": [{ "Fn::SplitSelect": [ "${iotda::mqtt::username}", "&", 1 ] }, "_", { "Fn::SplitSelect": [ "${iotda::mqtt::username}", "&", 0 ] }] }, "timestamp": { "type": "UNIX", "value": { "Fn::MathDiv": [{ "Fn::ParseLong": { "Fn::SplitSelect": [{ "Fn::SplitSelect": ["${iotda::mqtt::client_id}", "|", 2] }, "=", 1] } }, 1000] } }, "password": { "Fn::HmacSHA256": [{ "Fn::Sub": [ "clientId${clientId}deviceName${deviceName}productKey${productKey}timestamp${timestamp}", { "clientId": { "Fn::SplitSelect": [ "${iotda::mqtt::client_id}", "|", 0 ] }, "deviceName": { "Fn::SplitSelect": [ "${iotda::mqtt::username}", "&", 0 ] }, "productKey": { "Fn::SplitSelect": [ "${iotda::mqtt::username}", "&", 1 ] }, "timestamp": { "Fn::SplitSelect": [{ "Fn::SplitSelect": ["${iotda::mqtt::client_id}", "|", 2] }, "=", 1] } } ] }, "${iotda::device::secret}" ] } } } }
  • 示例1 证书认证设备,不限制UserName与ClientId参数取值,从设备证书通用名称(Common Name)中取值设备ID。 表1 鉴权参数 参数 说明 Client ID 任意值 User Name 任意值 Password 空值 鉴权模板: { "template_name": "template1", "description": "template1", "template_body": { "parameters": { "iotda::certificate::common_name": { "type": "String" } }, "resources": { "device_id": { "Ref": "iotda::certificate::common_name" } } } }
  • 示例3 设备ID格式为:${productId}${nodeId}。 表3 鉴权参数 参数 说明 Client ID 固定格式: ${productId}${nodeId} ${productId}:产品ID。 ${nodeId}: 设备标识码。 User Name 固定格式: ${productId}${nodeId};12010126;${connid};${expiry} ${productId}: 产品ID。 ${nodeId}: 设备标识码。 ${connid}:一个随机字符串。 ${expiry}:Unix时间戳,单位秒。 Password 固定格式: ${token};hmacsha256 ${token}:以BASE64解码后的设备密码为密钥,对User Name字段进行hmacsha256算法加密后的值。 鉴权模板: { "template_name": "template3", "description": "template3", "template_body": { "parameters": { "iotda::mqtt::client_id": { "type": "String" }, "iotda::mqtt::username": { "type": "String" }, "iotda::device::secret": { "type": "String" } }, "resources": { "device_id": { "Ref": "iotda::mqtt::client_id" }, "timestamp": { "type": "UNIX", "value": { "Fn::ParseLong": { "Fn::SplitSelect": ["${iotda::mqtt::username}", ";", 3] } } }, "password": { "Fn::Sub": [ "${token};hmacsha256", { "token": { "Fn::HmacSHA256": [ "${iotda::mqtt::username}", { "Fn::Base64Decode": "${iotda::device::secret}" } ] } } ] } } } }
  • 使用密钥接入的鉴权流程 通过调用注册接口向物联网平台发送注册请求或者在控制台上注册设备。 注册时需要填写设备标识码,通常使用MAC地址,Serial No或IMEI作为nodeId。 物联网平台向设备分配全局唯一的设备ID (deviceId)和密钥(secret)。 密钥可以在注册设备时自定义,如果没有定义,平台将自动分配密钥。 用户将设备ID(deviceId)和密钥(secret)烧录到设备硬件或软固件中。 设备侧需集成预置CA证书(仅针对MQTTS协议接入的鉴权流程)。 设备上电后,携带设备ID(deviceId)和密钥(secret)发起接入鉴权请求。 平台验证通过后,返回成功响应,设备连接物联网平台成功。
  • 鉴权方式D 鉴权方式D主要通过Key、timestamp和StreamName计算鉴权串。 鉴权URL格式 原始URL?hwSecret=hmac_sha256(Key, StreamName + hwTime)&hwTime=hex(timestamp) 表5 鉴权字段描述 字段 描述 hwTime 播放URL的有效时间,为Unix时间戳的十六进制结果。 如果当前hwTime+时长的值大于当前请求的时间则可以正常播放,否则播放会被后台拒绝。 示例:5eed5888(即2020.06.20 08:30:00) Key 在控制台设置的防盗链Key值,具体请参见开启Key防盗链。 hwSecret URL中的加密参数。 以Key和StreamName+hwTime为参数进行HMAC-SHA256加密算法得出。 hwSecret = hmac_sha256(Key, StreamName + hwTime) 时长 鉴权URL的有效时间长度。 若hwTime设置为当前时间,有效时间设置为1249s,则播放URL过期时间为当前时间+ 1249s。 鉴权URL示例 标准直播场景 以生成播放鉴权地址为例,推流鉴权地址的生成与播放鉴权地址的生成同理。 原始URL:http://test-play.example.com/livetest/huawei1.flv Key:GCTbw44s6MPLh4GqgDpnfuFHgy25Enly StreamName:huawei1 hwTime:5eed5888 时长:1249s 根据计算公式,得到hwSecret。 hwSecret = hmac_sha256(GCTbw44s6MPLh4GqgDpnfuFHgy25Enly, huawei15eed5888) = ce201856a0957413319e883c8ccae13602f01d3d91e21daf5161964cf708a6a8 则鉴权播放地址为: http://test-play.example.com/livetest/huawei1.flv?hwSecret=ce201856a0957413319e883c8ccae13602f01d3d91e21daf5161964cf708a6a8&hwTime=5eed5888
  • 鉴权方式A 鉴权方式A主要通过Key、timestamp、rand(随机数)、uid(设置为0)和URL计算鉴权串。 鉴权URL格式 原始URL?auth_key={timestamp}-{rand}-{uid}-{md5hash} md5hash的计算公式: sstring = "{URI}-{Timestamp}-{rand}-{uid}-{Key}" HashValue = md5sum(sstring) 表2 鉴权字段描述 字段 描述 timestamp 用户定义的有效访问时间起始点,值为1970年1月1日以来的当前时间秒数 。十进制或者十六进制整数。 示例:1592639100(即2020-06-20 15:45) 时长 鉴权URL有效的时间长度。 若设置的有效时间为1800s,则用户可在从timestamp开始的1800s内允许访问直播地址。超出该区间,鉴权失败。 示例:若设置的访问时间为2020-6-30 00:00:00,则链接真正失效时间为2020-6-30 00:30:00。 rand 随机数,建议使用UUID,不能包含中划线"-"。 示例:477b3bbc253f467b8def6711128c7bec uid userID。暂未使用,直接设置成0即可。 md5hash 通过md5算法计算出来的验证串,数字0-9和小写英文字母a-z混合组成,固定长度32。 sstring = "{URI}-{Timestamp}-{rand}-{uid}-{Key}" HashValue = md5sum(sstring) URI 指原始URL中从域名后开始到最后的路径。 标准直播场景 示例:/livetest/huawei1.flv 低时延直播场景 示例:/livetest/huawei1.sdp Key 在控制台设置的防盗链Key值,具体请参见开启Key防盗链。 鉴权URL示例 标准直播场景 以生成播放鉴权地址为例,推流鉴权地址的生成与播放鉴权地址的生成方法相同。 原始URL:http://test-play.example.com/livetest/huawei1.flv timestamp:1592639100 时长:1800s Key:GCTbw44s6MPLh4GqgDpnfuFHgy25Enly rand:477b3bbc253f467b8def6711128c7bec uid:0 URI:/livetest/huawei1.flv 根据计算公式,得到md5hash。 HashValue = md5sum("/livetest/huawei1.flv-1592639100-477b3bbc253f467b8def6711128c7bec-0-GCTbw44s6MPLh4GqgDpnfuFHgy25Enly") = dd1b5ffa00cf26acec0c169ae1cfabea 则鉴权播放地址为: http://test-play.example.com/livetest/huawei1.flv?auth_key=1592639100-477b3bbc253f467b8def6711128c7bec-0-dd1b5ffa00cf26acec0c169ae1cfabea
  • 鉴权方式B 鉴权方式B主要通过Key、timestamp和StreamName计算鉴权串。 鉴权URL格式 原始URL?txSecret=md5(Key + StreamName + txTime)&txTime=hex(timestamp) 表3 鉴权字段描述 字段 描述 txTime 播放URL的有效时间,为Unix时间戳的十六进制结果。 如果当前txTime的值大于当前请求的时间则可以正常播放,否则播放会被后台拒绝。 示例:5eed5888(即2020.06.20 08:30:00) Key 在控制台设置的防盗链Key值,具体请参见开启Key防盗链。 txSecret URL中的加密参数。 通过将key,StreamName,txTime依次拼接的字符串进行MD5加密算法得出。 txSecret = md5(Key + StreamName + txTime) 时长 鉴权URL的有效时间长度。 若txTime设置为当前时间,有效时间设置为1249s,则播放URL过期时间为当前时间+ 1249s。 鉴权URL示例 标准直播场景 以生成播放鉴权地址为例,推流鉴权地址的生成与播放鉴权地址的生成同理。 原始URL:http://test-play.example.com/livetest/huawei1.flv Key:GCTbw44s6MPLh4GqgDpnfuFHgy25Enly StreamName:huawei1 txTime:5eed5888 时长:1249s 根据计算公式,得到txSecret。 txSecret = md5(GCTbw44s6MPLh4GqgDpnfuFHgy25Enlyhuawei15eed5888) = 5cdc845362c332a4ec3e09ac5d5571d6 则鉴权播放地址为: http://test-play.example.com/livetest/huawei1.flv?txSecret=5cdc845362c332a4ec3e09ac5d5571d6&txTime=5eed5888
  • 注意事项 该功能为可选项,默认不启用。启用该功能后,原始直播加速URL将无法使用,需要按规则生成合法的防盗链URL。 建议推流与播放鉴权使用不同的Key值,以增强安全性。若防盗链URL过期,或者签名不能通过,直播流将播放失败,并返回“403 Forbidden”信息。 针对RTMP、FLV这类长连接业务,只有服务端收到用户请求时,才进行防盗链参数校验,校验通过后可以持续播放。 针对HLS这类业务,用户播放后会携带相同的防盗链参数,持续发起请求。一旦防盗链参数过期,服务端便会因校验不通过,而拒绝访问,导致播放中断。 所以建议这类业务,适当调整鉴权过期时间,避免因时间过短,而中途就播放失败。示例:如果预估HLS播放时长每次都在1小时以内,可设置过期时间为3600秒。
  • 在配置服务级条件键billing:cloudServiceType后,接口调用返回CBC.0151 配置服务级条件键billing:cloudServiceType如图所示: 目前服务级条件键billing:cloudServiceType仅支持退订权限项billing:subscription:unsubscribe。 如果配置此条件键后出现以下情况报错: { "error_code": "CBC.0151", "error_msg": "user access denied.checkCustomerPermission,correct permission code is billing:order:view" } 可用以下办法解决: 单独设置退订权限项billing:subscription:unsubscribe和服务级条件键billing:cloudServiceType,与其他权限项配置分开。 登陆新版控制台。 对原有策略进行修改,配置退订权限项。 确保策略内容列为允许,云服务列为billing,操作列写操作勾选billing:subscription:unsubscribe。如下图所示。 退订权限项下配置云服务级条件键。 选择请求条件(可选)列,单击添加条件。添加请求条件弹框中填写如下内容: 条件键:billing:cloudServiceType 运算符:StringEquals 值:hws.service.type.ebs 复制策略,配置其他不受云服务级条件键影响的权限。 单击克隆键,复制一条新的策略。删除新策略特定条件列中的条件。 取消勾选新策略操作列写操作billing:subscription:unsubscribe。单击确定,修改完成。 父主题: 细粒度鉴权
  • 请求和Policy示例 下面的几张表提供了一些请求和Policy的例子。 示例1:在examplebucket桶中上传testfile.txt对象,并且设置对象ACL为公共可读。 请求 policy POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=7e32233530b26 Content-Length: 1250 --7e32233530b26 Content-Disposition: form-data; name="key" testfile.txt --7e32233530b26 Content-Disposition: form-data; name="x-obs-acl" public-read --7e32233530b26 Content-Disposition: form-data; name="content-type" text/plain --7e32233530b26 Content-Disposition: form-data; name="AccessKeyId" UDSIAMSTUBTEST000002 --7e32233530b26 Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMTktMDctMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0IiB9LAogICAgWyJlcSIsICIka2V5IiwgInRlc3RmaWxlLnR4dCJdLAoJeyJ4LW9icy1hY2wiOiAicHVibGljLXJlYWQiIH0sCiAgICBbImVxIiwgIiRDb250ZW50LVR5cGUiLCAidGV4dC9wbGFpbiJdLAogICAgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDYsIDEwXQogIF0KfQo= --7e32233530b26 Content-Disposition: form-data; name="signature" xxl7bZs/5FgtBUggOdQ88DPZUo0= --7e32233530b26 Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 --7e32233530b26 Content-Disposition: form-data; name="submit" Upload --7e32233530b26-- { "expiration": "2019-07-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket" }, ["eq", "$key", "testfile.txt"], {"x-obs-acl": "public-read" }, ["eq", "$Content-Type", "text/plain"] ] } 示例2:在examplebucket桶中上传file/obj1对象,并且设置对象的四个自定义元数据。 请求 policy POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=7e329d630b26 Content-Length: 1597 --7e3542930b26 Content-Disposition: form-data; name="key" file/obj1 --7e3542930b26 Content-Disposition: form-data; name="AccessKeyId" UDSIAMSTUBTEST000002 --7e3542930b26 Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMTktMDctMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0IiB9LAogICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgImZpbGUvIl0sCiAgICB7Ingtb2JzLW1ldGEtdGVzdDEiOiJ2YWx1ZTEifSwKICAgIFsiZXEiLCAiJHgtb2JzLW1ldGEtdGVzdDIiLCAidmFsdWUyIl0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiR4LW9icy1tZXRhLXRlc3QzIiwgImRvYyJdLAogICAgWyJzdGFydHMtd2l0aCIsICIkeC1vYnMtbWV0YS10ZXN0NCIsICIiXQogIF0KfQo= --7e3542930b26 Content-Disposition: form-data; name="signature" HTId8hcaisn6FfdWKqSJP9RN4Oo= --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test1" value1 --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test2" value2 --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test3" doc123 --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test4" my --7e3542930b26 Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 --7e3542930b26 Content-Disposition: form-data; name="submit" Upload --7e3542930b26-- { "expiration": "2019-07-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket" }, ["starts-with", "$key", "file/"], {"x-obs-meta-test1":"value1"}, ["eq", "$x-obs-meta-test2", "value2"], ["starts-with", "$x-obs-meta-test3", "doc"], ["starts-with", "$x-obs-meta-test4", ""] ] }
  • Conditions Conditions是一个用于验证本次请求合法的一种机制,可以使用这些条件限制请求中必须包含的内容。实例中的条件要求请求的桶名必须是book,对象名必须以user/为前缀,对象的acl必须是公共可读。除了AccessKeyId、signature、file、policy、token、field names以及前缀为x-ignore-外的表单中的所有项,都需要包含在policy中。下表是conditions中应该包含的项: 表1 policy中应该包含的条件元素 元素名称 描述 x-obs-acl 请求中的ACL。 支持精确匹配和starts-with条件匹配。 content-length-range 设置上传对象的最大最小长度,支持range匹配。 Cache-Control, Content-Type, Content-Disposition, Content-Encoding, Expires REST请求特定头域。 支持精确匹配和starts-with条件匹配。 key 上传对象的名字。 支持精确匹配和starts-with条件匹配。 bucket 请求桶名。 支持精确匹配。 success_action_redirect 上传对象成功后重定向的URL地址。具体描述请参见5.4.2-POST上传。 支持精确匹配和starts-with条件匹配。 success_action_status 如果未指定success_action_redirect,则成功上传时返回给客户端的状态码。具体描述请参见5.4.2-POST上传。 支持精确匹配。 x-obs-meta-* 用户自定义元数据。 元素中的关键字不允许含有非ASCII码或不可识别字符,如果一定要使用非ASCII码或不可识别字符,需要客户端自行做编解码处理,可以采用URL编码或者Base64编码,服务端不会做解码处理。 支持精确匹配和starts-with条件匹配。 x-obs-* 其他以x-obs-为前缀的头域。 支持精确匹配和starts-with条件匹配。 x-obs-security-token 请求消息头中字段名。 临时AK/SK和securitytoken鉴权必加字段名。如何获取临时AK/SK和securitytoken请参考通过token获取临时访问密钥和securitytoken。 Policy条件匹配的方式如下: 表2 policy条件匹配方式 条件 描述 Exact Matches 默认是完全匹配,post表单中该项的值必须和policy的conditions中设置的值完全一样。例如:上传对象的同时设置对象ACL为public-read,表单中x-obs-acl元素的值为public-read,policy中的conditions可以设置为 {"x-obs-acl": "public-read" }或者[ "eq", "$x-obs-acl", "public-read"],这两者是等效的。 Starts With 如果使用该条件,则post表单中对应元素的值必须是固定字符串开始。例如:上传对象名以user/为前缀,表单中key元素的值可以是user/test1、user/test2,policy的conditions中该条件如下: ["starts-with", "$key", "user/"] Matching Any Content post表单中对应元素的值可以是任意值。例如:请求成功后重定向的地址可以是任意地址,表单中success_action_redirect元素的值可以是任意值,policy的conditions中该条件如下: ["starts-with", "$success_action_redirect", ""] Specifying Ranges post表单中file元素文件的内容长度可以是一个指定的范围,只用于限制对象大小。例如上传对象大小为1-10MB,表单中file元素的内容长度可以是1048576-10485760,policy的conditions中该条件如下,注意值没有双引号: ["content-length-range", 1048576, 10485760] policy使用json格式,conditions可以支持 { } 和 [ ] 两种方式,{ }中包含表单元素的key和value两项,以冒号分隔;[ ]中包含条件类型、key、value三项,以逗号分隔,元素key之前使用$字符表示变量。 Policy中必须转义的字符如下: 表3 policy中必须转义的字符 转义后的字符 真实字符 \\ 反斜杠(\) \$ 美元符号($) \b 退格 \f 换页 \n 换行 \r 回车 \t 水平制表 \v 垂直制表 \uxxxx 所有Unicode字符