1 #region 验证码相关 2 public class SmsSDK 3 { 4 5 #region 短信发送的必要参数 6 /// <summary> 7 /// appId 8 /// </summary> 9 private static int appId =自己的; 10 11 /// <summary> 12 /// appKey 13 /// </summary> 14 private static string appKey = "自己的"; 15 16 /// <summary> 17 /// 短信模板ID 18 /// </summary> 19 private static int tmplateId =自己的; 20 21 #endregion 22 23 #region 接收验证码的手机号 24 /// <summary> 25 /// 接受手机号 26 /// </summary> 27 private static string phoneNumber = ""; 28 #endregion 29 30 #region 获取验证码 31 /// <summary> 32 /// 获取验证码 33 /// </summary> 34 /// <param name="args"></param> 35 /// <param name="phone">手机号</param> 36 /// <returns></returns> 37 public bool GetMain(string phone) 38 { 39 var tel = phone; 40 phoneNumber = tel; 41 SmsSingleSenderResult singleResult; 42 List<string> templParams = new List<string>(); 43 SmsSingleSender singleSender = new SmsSingleSender(appId, appKey); 44 //获取随机码 45 var val = new SmsSenderUtil().GetRandom().ToString(); 46 SixNums = val; 47 48 templParams.Add(val); 49 templParams.Add("10"); 50 singleResult = singleSender.SendWithParam(phoneNumber, tmplateId, templParams); 51 if (singleResult.result == 0) 52 { 53 return true; 54 } 55 return false; 56 57 } 58 #endregion
1 #region 判断验证码 2 /// <summary> 3 /// 随机码 4 /// </summary> 5 private static string SixNums = ""; 6 7 /// <summary> 8 /// 判断验证码 9 /// </summary> 10 /// <param name="IfgCode">返回填写的验证码</param> 11 /// <returns></returns> 12 public bool JudgeIdentifyingCode(string IfgCode) 13 { 14 if (SixNums != IfgCode) 15 { 16 return false; 17 } 18 return true; 19 } 20 #endregion 21 } 22 #endregion 23 24 #region 腾讯云配置 25 #region 短信类型枚举 26 /// <summary> 27 /// 短信类型枚举 28 /// </summary> 29 public enum SmsType 30 { 31 普通短信 = 0, 32 营销短信 = 1 33 } 34 #endregion 35 36 #region 短信单发 37 /// <summary> 38 /// 单发 39 /// </summary> 40 class SmsSingleSender 41 { 42 #region 变量 43 /// <summary> 44 /// appId 45 /// </summary> 46 private int appId; 47 /// <summary> 48 /// appkey 49 /// </summary> 50 private string appkey; 51 /// <summary> 52 /// url 53 /// </summary> 54 private string url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms"; 55 /// <summary> 56 /// util 57 /// </summary> 58 private SmsSenderUtil util = new SmsSenderUtil(); 59 #endregion 60 61 #region 构造 62 /// <summary> 63 /// 构造函数 64 /// </summary> 65 /// <param name="sdkappid"></param> 66 /// <param name="appkey"></param> 67 public SmsSingleSender(int sdkappid, string appkey) 68 { 69 this.appId = sdkappid; 70 this.appkey = appkey; 71 } 72 #endregion 73 74 75 #region 指定模板单发 76 /// <summary> 77 /// 指定模板单发 78 /// </summary> 79 /// <param name="phoneNumber">不带国家码的手机号</param> 80 /// <param name="templId">模板 id</param> 81 /// <param name="templParams">模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数</param> 82 /// <param name="sign">短信签名,如果使用默认签名,该字段可缺省</param> 83 /// <param name="extend">扩展码,可填空</param> 84 /// <param name="ext">服务端原样返回的参数,可填空</param> 85 /// <returns>SmsSingleSenderResult</returns> 86 public SmsSingleSenderResult SendWithParam(string phoneNumber, int templId, List<string> templParams, string sign= "", string extend = "", string ext = "") 87 { 88 long random = util.GetRandom(); 89 long curTime = util.GetCurTime(); 90 // 按照协议组织 post 请求包体 91 JObject tel = new JObject(); 92 tel.Add("nationcode", SmsSenderUtil.nationCode); 93 tel.Add("mobile", phoneNumber); 94 JObject data = new JObject(); 95 data.Add("tel", tel); 96 data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumber)); 97 data.Add("tpl_id", templId); 98 data.Add("params", util.SmsParamsToJSONArray(templParams)); 99 data.Add("sign", sign); 100 data.Add("time", curTime); 101 data.Add("extend", extend); 102 data.Add("ext", ext); 103 string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random; 104 HttpWebRequest request = util.GetPostHttpConn(wholeUrl); 105 byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); 106 request.ContentLength = requestData.Length; 107 Stream requestStream = request.GetRequestStream(); 108 requestStream.Write(requestData, 0, requestData.Length); 109 requestStream.Close(); 110 // 接收返回包 111 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 112 Stream responseStream = response.GetResponseStream(); 113 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); 114 string responseStr = streamReader.ReadToEnd(); 115 streamReader.Close(); 116 responseStream.Close(); 117 SmsSingleSenderResult result; 118 if (HttpStatusCode.OK == response.StatusCode) 119 { 120 result = util.ResponseStrToSingleSenderResult(responseStr); 121 } 122 else 123 { 124 result = new SmsSingleSenderResult(); 125 result.result = -1; 126 result.errmsg = "http error " + response.StatusCode + " " + responseStr; 127 } 128 return result; 129 } 130 #endregion 131 } 132 #endregion
1 #region 单发结果 2 /// <summary> 3 /// 单发结果 4 /// </summary> 5 public class SmsSingleSenderResult 6 { 7 /// <summary> 8 /// 错误码,0 表示成功(计费依据),非 0 表示失败 9 /// </summary> 10 public int result { set; get; } 11 /// <summary> 12 /// 错误消息,result 非 0 时的具体错误信息 13 /// </summary> 14 public string errmsg { set; get; } 15 /// <summary> 16 /// 用户的 session 内容,腾讯 server 回包中会原样返回 17 /// </summary> 18 public string ext { set; get; } 19 /// <summary> 20 /// 本次发送标识 id,标识一次短信下发记录 21 /// </summary> 22 public string sid { set; get; } 23 /// <summary> 24 /// 短信计费的条数 25 /// </summary> 26 public int fee { set; get; } 27 /// <summary> 28 /// ToString() 29 /// </summary> 30 /// <returns></returns> 31 public override string ToString() 32 { 33 return string.Format("SmsSingleSenderResult result {0} errMsg {1} ext {2} sid {3} fee {4}", result, errmsg, ext, sid, fee); 34 } 35 } 36 #endregion 37 38 #region 公共类 39 /// <summary> 40 /// 公共类 41 /// </summary> 42 class SmsSenderUtil 43 { 44 /// <summary> 45 /// 国家码 46 /// </summary> 47 public static string nationCode = "86"; 48 /// <summary> 49 /// 随机数生成器 50 /// </summary> 51 private Random random = new Random(); 52 53 #region GetPostHttpConn 54 /// <summary> 55 /// GetPostHttpConn 56 /// </summary> 57 /// <param name="url"></param> 58 /// <returns></returns> 59 public HttpWebRequest GetPostHttpConn(string url) 60 { 61 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 62 request.Method = "POST"; 63 request.ContentType = "application/x-www-form-urlencoded"; 64 return request; 65 } 66 #endregion
1 #region 生成随机数 2 /// <summary> 3 /// 生成随机数 4 /// </summary> 5 /// <returns></returns> 6 public long GetRandom() 7 { 8 return random.Next(999999) % 900000 + 100000; 9 } 10 #endregion 11 12 #region 获取请求发起时间 13 /// <summary> 14 /// 获取请求发起时间, 15 /// unix 时间戳(单位:秒),如果和系统时间相差超过 10 分钟则会返回失败 16 /// </summary> 17 /// <returns></returns> 18 public long GetCurTime() 19 { 20 Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 21 return unixTimestamp; 22 } 23 #endregion 24 25 #region 字符串转SHA256 26 /// <summary> 27 /// 字符串转SHA256 28 /// </summary> 29 /// <param name="str"></param> 30 /// <returns></returns> 31 public string StrToHash(string str) 32 { 33 SHA256 sha256 = SHA256Managed.Create(); 34 byte[] resultByteArray = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str)); 35 return ByteArrayToHex(resultByteArray); 36 } 37 38 /// <summary> 39 /// 将二进制的数值转换为 16 进制字符串,如 "abc" => "616263" 40 /// </summary> 41 /// <param name="byteArray"></param> 42 /// <returns></returns> 43 private static string ByteArrayToHex(byte[] byteArray) 44 { 45 string returnStr = ""; 46 if (byteArray != null) 47 { 48 for (int i = 0; i < byteArray.Length; i++) 49 { 50 returnStr += byteArray[i].ToString("x2"); 51 } 52 } 53 return returnStr; 54 } 55 #endregion 56 57 #region 将单发回包解析成结果对象 58 /// <summary> 59 /// 将单发回包解析成结果对象 60 /// </summary> 61 /// <param name="str"></param> 62 /// <returns></returns> 63 public SmsSingleSenderResult ResponseStrToSingleSenderResult(string str) 64 { 65 SmsSingleSenderResult result = JsonConvert.DeserializeObject<SmsSingleSenderResult>(str); 66 return result; 67 } 68 #endregion 69 70 #region List<string>转JArray 71 /// <summary> 72 /// List<string>转JArray 73 /// </summary> 74 /// <param name="templParams"></param> 75 /// <returns></returns> 76 public JArray SmsParamsToJSONArray(List<string> templParams) 77 { 78 JArray smsParams = new JArray(); 79 foreach (string templParamsElement in templParams) 80 { 81 smsParams.Add(templParamsElement); 82 } 83 return smsParams; 84 } 85 #endregion 86 87 #region PhoneNumbersToJSONArray 88 /// <summary> 89 /// PhoneNumbersToJSONArray 90 /// </summary> 91 /// <param name="nationCode"></param> 92 /// <param name="phoneNumbers"></param> 93 /// <returns></returns> 94 public JArray PhoneNumbersToJSONArray(string nationCode, List<string> phoneNumbers) 95 { 96 JArray tel = new JArray(); 97 int i = 0; 98 do 99 { 100 JObject telElement = new JObject(); 101 telElement.Add("nationcode", nationCode); 102 telElement.Add("mobile", phoneNumbers.ElementAt(i)); 103 tel.Add(telElement); 104 } while (++i < phoneNumbers.Count); 105 return tel; 106 } 107 #endregion 108 109 #region 计算App凭证 110 /* 111 "sig" 字段根据公式 sha256(appkey=$appkey&random=$random&time=$time&mobile=$mobile)生成 112 */ 113 public string CalculateSigForTempl(string appkey, long random, long curTime, List<string> phoneNumbers) 114 { 115 string phoneNumbersString = phoneNumbers.ElementAt(0); 116 for (int i = 1; i < phoneNumbers.Count; i++) 117 { 118 phoneNumbersString += "," + phoneNumbers.ElementAt(i); 119 } 120 return StrToHash(String.Format( 121 "appkey={0}&random={1}&time={2}&mobile={3}", 122 appkey, random, curTime, phoneNumbersString)); 123 } 124 125 public string CalculateSigForTempl(string appkey, long random, long curTime, string phoneNumber) 126 { 127 List<string> phoneNumbers = new List<string>(); 128 phoneNumbers.Add(phoneNumber); 129 return CalculateSigForTempl(appkey, random, curTime, phoneNumbers); 130 } 131 132 public string CalculateSig(string appkey, long random, long curTime, List<string> phoneNumbers) 133 { 134 string phoneNumbersString = phoneNumbers.ElementAt(0); 135 for (int i = 1; i < phoneNumbers.Count; i++) 136 { 137 phoneNumbersString += "," + phoneNumbers.ElementAt(i); 138 } 139 return StrToHash(String.Format( 140 "appkey={0}&random={1}&time={2}&mobile={3}", 141 appkey, random, curTime, phoneNumbersString)); 142 } 143 #endregion 144 } 145 #endregion 146 #endregion
//使用时需要将配置里的内容换成自己的;