【API调用】腾讯云短信
在之前介绍的火车票查询工具中,利用邮件和短信将查询结果推送给用户。免费短信的条数只有5条,用完之后只能单独使用邮件提醒。
最近发现腾讯云的福利,简单的介绍一下用法。

腾讯云-》产品-》通信服务-》短信-》开通服务-》添加应用-》创建签名和模板-》等待审核通过-》按照Demo测试


在整个流程中,最耗时的就是创建签名和模板,对个人来说只能选择app、公众号或小程序的方式进行申请,多亏之前折腾过一点小程序,从而闯关成功。
接下来查看官方Demo https://github.com/qcloudsms/qcloudsms/tree/master/demo/csharp
整理后的测试Demo
调用代码:
using QcloudSms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConsoleTest
{
class SmsSDKDemo
{
/// <summary>
/// appId
/// </summary>
private static int appId = 140xxxxx;
/// <summary>
/// appKey
/// </summary>
private static string appKey = "xxxxxxxxxxxxxxx";
/// <summary>
/// 接收手机号
/// </summary>
private static string phoneNumber = "xxxxxxxx";
/// <summary>
/// 短信模板ID
/// </summary>
private static int tmplateId = xxxxxxx; static void Main(string[] args)
{
try
{
SmsSingleSenderResult singleResult;
SmsSingleSender singleSender = new SmsSingleSender(appId, appKey); singleResult = singleSender.Send(SmsType.普通短信, phoneNumber, "");
Console.WriteLine(singleResult); List<string> templParams = new List<string>();
templParams.Add("G2619");
templParams.Add("二等座:23 无座:128");
singleResult = singleSender.SendWithParam(phoneNumber, tmplateId, templParams);
Console.WriteLine(singleResult);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.Read();
}
}
}
namespace QcloudSms
{
#region 短信类型枚举
/// <summary>
/// 短信类型枚举
/// </summary>
public enum SmsType
{
普通短信 = ,
营销短信 =
}
#endregion #region 单发
/// <summary>
/// 单发
/// </summary>
class SmsSingleSender
{
#region 变量
/// <summary>
/// appId
/// </summary>
private int appId;
/// <summary>
/// appkey
/// </summary>
private string appkey;
/// <summary>
/// url
/// </summary>
private string url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
/// <summary>
/// util
/// </summary>
private SmsSenderUtil util = new SmsSenderUtil();
#endregion #region 构造
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sdkappid"></param>
/// <param name="appkey"></param>
public SmsSingleSender(int sdkappid, string appkey)
{
this.appId = sdkappid;
this.appkey = appkey;
}
#endregion #region 普通单发短信接口
/// <summary>
/// 普通单发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名
/// </summary>
/// <param name="type">短信类型,0 为普通短信,1 营销短信</param>
/// <param name="phoneNumber">不带国家码的手机号</param>
/// <param name="msg">信息内容,必须与申请的模板格式一致,否则将返回错误</param>
/// <param name="extend">短信码号扩展号,格式为纯数字串,其他格式无效。默认没有开通</param>
/// <param name="ext">服务端原样返回的参数,可填空</param>
/// <returns>SmsSingleSenderResult</returns>
public SmsSingleSenderResult Send(SmsType type, string phoneNumber, string msg, string extend = "", string ext = "")
{
long random = util.GetRandom();
long curTime = util.GetCurTime(); // 按照协议组织 post 请求包体
JObject tel = new JObject();
tel.Add("nationcode", SmsSenderUtil.nationCode);
tel.Add("mobile", phoneNumber);
JObject data = new JObject();
data.Add("tel", tel);
data.Add("msg", msg);
data.Add("type", (int)type);
data.Add("sig", util.StrToHash(string.Format("appkey={0}&random={1}&time={2}&mobile={3}", appkey, random, curTime, phoneNumber)));
data.Add("time", curTime);
data.Add("extend", extend);
data.Add("ext", ext); string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;
HttpWebRequest request = util.GetPostHttpConn(wholeUrl);
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
request.ContentLength = requestData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(requestData, , requestData.Length);
requestStream.Close(); // 接收返回包
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
string responseStr = streamReader.ReadToEnd();
streamReader.Close();
responseStream.Close();
SmsSingleSenderResult result;
if (HttpStatusCode.OK == response.StatusCode)
{
result = util.ResponseStrToSingleSenderResult(responseStr);
}
else
{
result = new SmsSingleSenderResult();
result.result = -;
result.errmsg = "http error " + response.StatusCode + " " + responseStr;
}
return result;
}
#endregion #region 指定模板单发
/// <summary>
/// 指定模板单发
/// </summary>
/// <param name="phoneNumber">不带国家码的手机号</param>
/// <param name="templId">模板 id</param>
/// <param name="templParams">模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数</param>
/// <param name="sign">短信签名,如果使用默认签名,该字段可缺省</param>
/// <param name="extend">扩展码,可填空</param>
/// <param name="ext">服务端原样返回的参数,可填空</param>
/// <returns>SmsSingleSenderResult</returns>
public SmsSingleSenderResult SendWithParam(string phoneNumber, int templId, List<string> templParams, string sign = "", string extend = "", string ext = "")
{
long random = util.GetRandom();
long curTime = util.GetCurTime(); // 按照协议组织 post 请求包体
JObject tel = new JObject();
tel.Add("nationcode", SmsSenderUtil.nationCode);
tel.Add("mobile", phoneNumber);
JObject data = new JObject();
data.Add("tel", tel);
data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumber));
data.Add("tpl_id", templId);
data.Add("params", util.SmsParamsToJSONArray(templParams));
data.Add("sign", sign);
data.Add("time", curTime);
data.Add("extend", extend);
data.Add("ext", ext); string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;
HttpWebRequest request = util.GetPostHttpConn(wholeUrl);
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
request.ContentLength = requestData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(requestData, , requestData.Length);
requestStream.Close(); // 接收返回包
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
string responseStr = streamReader.ReadToEnd();
streamReader.Close();
responseStream.Close();
SmsSingleSenderResult result;
if (HttpStatusCode.OK == response.StatusCode)
{
result = util.ResponseStrToSingleSenderResult(responseStr);
}
else
{
result = new SmsSingleSenderResult();
result.result = -;
result.errmsg = "http error " + response.StatusCode + " " + responseStr;
}
return result;
}
#endregion
}
#endregion #region 单发结果
/// <summary>
/// 单发结果
/// </summary>
class SmsSingleSenderResult
{
/// <summary>
/// 错误码,0 表示成功(计费依据),非 0 表示失败
/// </summary>
public int result { set; get; }
/// <summary>
/// 错误消息,result 非 0 时的具体错误信息
/// </summary>
public string errmsg { set; get; }
/// <summary>
/// 用户的 session 内容,腾讯 server 回包中会原样返回
/// </summary>
public string ext { set; get; }
/// <summary>
/// 本次发送标识 id,标识一次短信下发记录
/// </summary>
public string sid { set; get; }
/// <summary>
/// 短信计费的条数
/// </summary>
public int fee { set; get; }
/// <summary>
/// ToString()
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("SmsSingleSenderResult\nresult {0}\nerrMsg {1}\next {2}\nsid {3}\nfee {4}", result, errmsg, ext, sid, fee);
}
}
#endregion #region 群发
/// <summary>
/// 群发
/// </summary>
class SmsMultiSender
{
#region 变量
/// <summary>
/// appId
/// </summary>
private int appId;
/// <summary>
/// appkey
/// </summary>
private string appkey;
/// <summary>
/// url
/// </summary>
private string url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";
/// <summary>
/// util
/// </summary>
private SmsSenderUtil util = new SmsSenderUtil();
#endregion #region 构造
/// <summary>
/// 构造
/// </summary>
/// <param name="sdkappid"></param>
/// <param name="appkey"></param>
public SmsMultiSender(int sdkappid, string appkey)
{
this.appId = sdkappid;
this.appkey = appkey;
}
#endregion #region 普通群发短信接口
/// <summary>
/// 普通群发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名
///【注意】 海外短信无群发功能
/// </summary>
/// <param name="type">短信类型,0 为普通短信,1 营销短信</param>
/// <param name="nationCode"></param>
/// <param name="phoneNumbers">不带国家码的手机号列表</param>
/// <param name="msg">信息内容,必须与申请的模板格式一致,否则将返回错误</param>
/// <param name="extend">扩展码,可填空</param>
/// <param name="ext">服务端原样返回的参数,可填空</param>
/// <returns>SmsMultiSenderResult</returns>
public SmsMultiSenderResult Send(SmsType type, List<string> phoneNumbers, string msg, string extend = "", string ext = "")
{
long random = util.GetRandom();
long curTime = util.GetCurTime(); // 按照协议组织 post 请求包体
JObject data = new JObject();
data.Add("tel", util.PhoneNumbersToJSONArray(SmsSenderUtil.nationCode, phoneNumbers));
data.Add("type", (int)type);
data.Add("msg", msg);
data.Add("sig", util.CalculateSig(appkey, random, curTime, phoneNumbers));
data.Add("time", curTime);
data.Add("extend", extend);
data.Add("ext", ext); string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;
HttpWebRequest request = util.GetPostHttpConn(wholeUrl);
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
request.ContentLength = requestData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(requestData, , requestData.Length);
requestStream.Close(); // 接收返回包
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
string responseStr = streamReader.ReadToEnd();
streamReader.Close();
responseStream.Close();
SmsMultiSenderResult result;
if (HttpStatusCode.OK == response.StatusCode)
{
result = util.ResponseStrToMultiSenderResult(responseStr);
}
else
{
result = new SmsMultiSenderResult();
result.result = -;
result.errmsg = "http error " + response.StatusCode + " " + responseStr;
}
return result;
}
#endregion #region 指定模板群发
/// <summary>
/// 指定模板群发
/// 【注意】海外短信无群发功能
/// </summary>
/// <param name="phoneNumbers">不带国家码的手机号列表</param>
/// <param name="templId"> 模板 id</param>
/// <param name="templParams">模板参数列表</param>
/// <param name="sign"> 签名,如果填空,系统会使用默认签名</param>
/// <param name="extend">扩展码,可以填空</param>
/// <param name="ext">服务端原样返回的参数,可以填空</param>
/// <returns> SmsMultiSenderResult</returns>
public SmsMultiSenderResult SendWithParam(List<string> phoneNumbers, int templId, List<string> templParams, string sign = "", string extend = "", string ext = "")
{
long random = util.GetRandom();
long curTime = util.GetCurTime(); // 按照协议组织 post 请求包体
JObject data = new JObject();
data.Add("tel", util.PhoneNumbersToJSONArray(SmsSenderUtil.nationCode, phoneNumbers));
data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumbers));
data.Add("tpl_id", templId);
data.Add("params", util.SmsParamsToJSONArray(templParams));
data.Add("sign", sign);
data.Add("time", curTime);
data.Add("extend", extend);
data.Add("ext", ext); string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;
HttpWebRequest request = util.GetPostHttpConn(wholeUrl);
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
request.ContentLength = requestData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(requestData, , requestData.Length);
requestStream.Close(); // 接收返回包
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
string responseStr = streamReader.ReadToEnd();
streamReader.Close();
responseStream.Close();
SmsMultiSenderResult result;
if (HttpStatusCode.OK == response.StatusCode)
{
result = util.ResponseStrToMultiSenderResult(responseStr);
}
else
{
result = new SmsMultiSenderResult();
result.result = -;
result.errmsg = "http error " + response.StatusCode + " " + responseStr;
}
return result;
}
#endregion
}
#endregion #region 群发结果
/// <summary>
/// 群发结果
/// </summary>
class SmsMultiSenderResult
{
public class Detail
{
/// <summary>
/// 错误码,0 表示成功(计费依据),非 0 表示失败
/// </summary>
public int result { get; set; }
/// <summary>
/// 错误消息,result 非 0 时的具体错误信息
/// </summary>
public string errmsg { get; set; }
/// <summary>
/// 手机号码
/// </summary>
public string mobile { get; set; }
/// <summary>
/// 国家码
/// </summary>
public string nationcode { get; set; }
/// <summary>
/// 本次发送标识 id,标识一次短信下发记录
/// </summary>
public string sid { get; set; }
/// <summary>
/// 短信计费的条数
/// </summary>
public int fee { get; set; }
/// <summary>
/// ToString()
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format(
"\tDetail result {0} errmsg {1} mobile {2} nationcode {3} sid {4} fee {5}",
result, errmsg, mobile, nationcode, sid, fee);
}
} public int result;
public string errmsg = "";
public string ext = "";
public IList<Detail> detail; public override string ToString()
{
if (null != detail)
{
return String.Format(
"SmsMultiSenderResult\nresult {0}\nerrmsg {1}\next {2}\ndetail:\n{3}",
result, errmsg, ext, String.Join("\n", detail));
}
else
{
return String.Format(
"SmsMultiSenderResult\nresult {0}\nerrmsg {1}\next {2}\n",
result, errmsg, ext);
}
}
}
#endregion #region 公共类
/// <summary>
/// 公共类
/// </summary>
class SmsSenderUtil
{
/// <summary>
/// 国家码
/// </summary>
public static string nationCode = "";
/// <summary>
/// 随机数生成器
/// </summary>
private Random random = new Random(); #region GetPostHttpConn
/// <summary>
/// GetPostHttpConn
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public HttpWebRequest GetPostHttpConn(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
return request;
}
#endregion #region 生成随机数
/// <summary>
/// 生成随机数
/// </summary>
/// <returns></returns>
public long GetRandom()
{
return random.Next() % + ;
}
#endregion #region 获取请求发起时间
/// <summary>
/// 获取请求发起时间,
/// unix 时间戳(单位:秒),如果和系统时间相差超过 10 分钟则会返回失败
/// </summary>
/// <returns></returns>
public long GetCurTime()
{
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(, , ))).TotalSeconds;
return unixTimestamp;
}
#endregion #region 字符串转SHA256
/// <summary>
/// 字符串转SHA256
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public string StrToHash(string str)
{
SHA256 sha256 = SHA256Managed.Create();
byte[] resultByteArray = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str));
return ByteArrayToHex(resultByteArray);
} /// <summary>
/// 将二进制的数值转换为 16 进制字符串,如 "abc" => "616263"
/// </summary>
/// <param name="byteArray"></param>
/// <returns></returns>
private static string ByteArrayToHex(byte[] byteArray)
{
string returnStr = "";
if (byteArray != null)
{
for (int i = ; i < byteArray.Length; i++)
{
returnStr += byteArray[i].ToString("x2");
}
}
return returnStr;
}
#endregion #region 将单发回包解析成结果对象
/// <summary>
/// 将单发回包解析成结果对象
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public SmsSingleSenderResult ResponseStrToSingleSenderResult(string str)
{
SmsSingleSenderResult result = JsonConvert.DeserializeObject<SmsSingleSenderResult>(str);
return result;
}
#endregion #region 将群发回包解析成结果对象
/// <summary>
/// 将群发回包解析成结果对象
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public SmsMultiSenderResult ResponseStrToMultiSenderResult(string str)
{
SmsMultiSenderResult result = JsonConvert.DeserializeObject<SmsMultiSenderResult>(str);
return result;
}
#endregion #region List<string>转JArray
/// <summary>
/// List<string>转JArray
/// </summary>
/// <param name="templParams"></param>
/// <returns></returns>
public JArray SmsParamsToJSONArray(List<string> templParams)
{
JArray smsParams = new JArray();
foreach (string templParamsElement in templParams)
{
smsParams.Add(templParamsElement);
}
return smsParams;
}
#endregion #region PhoneNumbersToJSONArray
/// <summary>
/// PhoneNumbersToJSONArray
/// </summary>
/// <param name="nationCode"></param>
/// <param name="phoneNumbers"></param>
/// <returns></returns>
public JArray PhoneNumbersToJSONArray(string nationCode, List<string> phoneNumbers)
{
JArray tel = new JArray();
int i = ;
do
{
JObject telElement = new JObject();
telElement.Add("nationcode", nationCode);
telElement.Add("mobile", phoneNumbers.ElementAt(i));
tel.Add(telElement);
} while (++i < phoneNumbers.Count);
return tel;
}
#endregion #region 计算App凭证
/*
"sig" 字段根据公式 sha256(appkey=$appkey&random=$random&time=$time&mobile=$mobile)生成
*/
public string CalculateSigForTempl(string appkey, long random, long curTime, List<string> phoneNumbers)
{
string phoneNumbersString = phoneNumbers.ElementAt();
for (int i = ; i < phoneNumbers.Count; i++)
{
phoneNumbersString += "," + phoneNumbers.ElementAt(i);
}
return StrToHash(String.Format(
"appkey={0}&random={1}&time={2}&mobile={3}",
appkey, random, curTime, phoneNumbersString));
} public string CalculateSigForTempl(string appkey, long random, long curTime, string phoneNumber)
{
List<string> phoneNumbers = new List<string>();
phoneNumbers.Add(phoneNumber);
return CalculateSigForTempl(appkey, random, curTime, phoneNumbers);
} public string CalculateSig(string appkey, long random, long curTime, List<string> phoneNumbers)
{
string phoneNumbersString = phoneNumbers.ElementAt();
for (int i = ; i < phoneNumbers.Count; i++)
{
phoneNumbersString += "," + phoneNumbers.ElementAt(i);
}
return StrToHash(String.Format(
"appkey={0}&random={1}&time={2}&mobile={3}",
appkey, random, curTime, phoneNumbersString));
}
#endregion
}
#endregion
}
QcloudSms
demo下载路径为:https://files.cnblogs.com/files/LikeHeart/ConsoleTest.zip
【API调用】腾讯云短信的更多相关文章
- python调用腾讯云短信接口
目录 python调用腾讯云短信接口 账号注册 python中封装腾讯云短信接口 python调用腾讯云短信接口 账号注册 去腾讯云官网注册一个腾讯云账号,通过实名认证 然后开通短信服务,创建短信应用 ...
- Java调用腾讯云短信接口,完成验证码的发送(不成功你来砍我!!)
一.前言 我们在一些网站注册页面,经常会见到手机验证码的存在,这些验证码一般的小公司都是去买一些大的厂家的短信服务,自己开发对小公司的成本花费太大了!今天小编就带着大家来学习一下腾讯云的短信接口,体验 ...
- java 调用腾讯云短信api
依赖: <!--腾讯短信依赖--> <dependency> <groupId>com.github.qcloudsms</groupId> <a ...
- 反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习
反射实现Model修改前后的内容对比 在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 1 p ...
- ThinkPHP5——接入腾讯云短信API
接入腾讯云短信API相当简单,最重要的是第一次使用腾讯云短信的话有100条免费短信可以测试,对于开发人员是足够了,下面我就教大家接入腾讯云短信. 第一步:准备工作 首先要在腾讯云短信申请短信签名与短信 ...
- php腾讯云短信验证码
腾讯云短信控制台:https://console.cloud.tencent.com/sms 腾讯云短信 PHP SDK:https://github.com/qcloudsms/qcloudsms_ ...
- 基于tp3.2的腾讯云短信验证码的实现
新手小白在公司要完成短信验证码注册功能,最初由于没有经验,网上的教程又不是很全,便参考着官方API文档,进行开发 直接进入正题:使用composer下载腾讯云短信接口(记得添加依赖).在项目目录下新建 ...
- 腾讯云短信 nodejs 接入, 通过验证码修改手机示例
腾讯云短信 nodejs 接入, 通过验证码修改手机示例 参考:腾讯云短信文档国内短信快速入门qcloudsms Node.js SDK文档中心>短信>错误码 nodejs sdk 使用示 ...
- 腾讯云短信详细教程(C#,WinForm)
1.申请一个微信公众号(申请公众号是准备工作的第一步,必须先完成)(那为什么要用公众号呢?是因为这个条件对于学生党来说比较简单实现,不需要本人有上市的APP或是网站等) 2.百度搜索"腾讯云 ...
- 轻松集成腾讯云短信服务实现短信发送(Java实现)
不论是阿里云还是腾讯云,要想在网站上实现短信发送功能,首先得保证你的网站域名是通过备案的,因为短信签名是需要用到备案过的域名截图,所以域名通过了,申请很快就会审批成功了. (说点题外话,备案的话,需要 ...
随机推荐
- React 系列文章(1): npm 手动搭建React 运行实例 (新手必看)
摘 要 刚接触React 开发, 在摸索中构建react 运行环境,总会遇到各种坑:本文,将用最短时间解决webpack+react 环境搭建问题. 1.如果你还没有React基础 看这里. 2.如果 ...
- jdk自带的MD5进行数据的加密与解密
package com.tools.util; import java.io.IOException; import java.io.UnsupportedEncodingException; imp ...
- c#多线程,进度条,实时给前台发送数据
///做了一个wpf多线程,在实际场景中利用多线程保证程序不会卡死,性能上有所提高 //启动线程处理 Thread thread1 = new Thread(Update ...
- ConcurrentHashMap 源码分析
ConcurrentHashMap 源码分析 1. 前言 终于到这个类了,其实在前面很过很多次这个类,因为这个类代码量比较大,并且涉及到并发的问题,还有一点就是这个代码有些真的晦涩,不好懂.前前 ...
- js版九宫格拼图与启发式搜索(A*算法)
九宫格拼图游戏大家都很熟悉,这里给大家如介绍何应用状态空间搜索的方式求解拼图的最佳路径和一个游戏dome及自动求解方法: 本文分web版游戏的实现和启发式搜索算法两部分: 先看dome,直接鼠标点击要 ...
- 微信公众号报错 config:invalid signature
官方已经提供了微信 JS 接口签名校验工具(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign),填入相应的参数就能出来相应的signa ...
- java————面向对象概念
面向对象 OO:面向对象 OOP:面向对象编程 OOA:面向对象分析 OOD:面向对象设计 面向对象的特征 继承,封装,多态 什么是对象? 对象是存在的具体实体,具有明确定义的特征和行为. 万物皆对象 ...
- Leetcode 2——Range Sum Query - Mutable(树状数组实现)
Problem: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), ...
- 弹幕视频播放app案例分析
产品 哔哩哔哩动画 相对于其他视频播放软件来说,哔哩哔哩动画没有广告影响观看体验,而且内容更偏重于二次元,因此我更倾向于使用它. 第一部分 调研, 评测 #第一次上手体验 用起来还是比较方便,可以快速 ...
- choose the max from numbers, use scanf and if else (v1:21.9.2017,v2:23.9.2017)
#include<stdio.h> int main(){ int a,b,c,max; printf("请输入一个数值: "); scanf("%d&quo ...