この記事では、1: 小文字のピンイン、2: 大文字のピンイン、4: 中国語の文字を統合する検証コード 生成クラスを共有します。この章の例には、mvc が検証コード検証を使用するシナリオも含まれます。ある程度の参考値があるので、以下のエディタで見てみましょう
今回共有するのは、1:小文字ピンイン2:大文字ピンイン3:数字4:漢字、を統合した検証コード生成クラスです。タイトルから判断すると、非常に普通のことのように思えますが、この検証コード クラスを生成する際に、パラメータを通じて検証コードの返される形式の規則を指定できることは、ある程度の実用性をもたらすことを願っています。この章の例には、mvc で検証コード検証を使用するシナリオもあります。
» 検証コード生成フローチャート
» 検証コード生成プールコードの解析
» 画像上に検証コードを描画
» mvcログイン動作テスト検証コードの正しさ
を以下に見てみましょうステップごとに共有します:
» 検証コード生成フローチャート
まずは、今回共有する検証コード生成クラスの生成フローチャートを見てみましょう:
の説明が見られます。この画像 エンコード生成プールは、いくつかの異なるエンコード コンテンツに対応しています。ここでは、主に、テキスト、ピンイン、中国語の文字の組み合わせを決定するために、パラメーター設定に従って異なるエンコード コンテンツを同時に取得することができます。検証コードを形成します。具体的なルール設定はパラメータによって決定されます。
» 検証コード生成プールコードの分析
まず、上記のフローチャートの分析から、この検証コードは次のようになります。生成プールは、結合された検証コードを満たすために、さまざまな種類の検証コード データを並行して取得する必要があるため、次のコードがあります:
/// <summary> /// 创建验证码 /// </summary> /// <param name="codeType">1:小写拼音 2:大写拼音 3:数字 4:汉字</param> /// <returns></returns> public static string CreateCode(string codeType = "1|2|3|4") { var code = string.Empty; try { if (string.IsNullOrWhiteSpace(codeType) || codeType.IndexOf('|') < 0) { codeType = "1|2|3|4"; } var codeTypeArr = codeType.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); var strLen = codeTypeArr.Length; //任务 Task<string>[] taskArr = new Task<string>[strLen]; for (int i = 0; i < strLen; i++) { var val = codeTypeArr[i]; switch (val) { case "1": //小写拼音 taskArr[i] = Task.Factory.StartNew<string>(() => { return GetPinYinOrUpper(false); }); break; case "2": //大写拼音 taskArr[i] = Task.Factory.StartNew<string>(() => { return GetPinYinOrUpper(); }); break; case "3": //数字 taskArr[i] = Task.Factory.StartNew<string>(() => { return GetShuZi(); }); break; case "4": //汉字 taskArr[i] = Task.Factory.StartNew<string>(() => { return GetHanZi(); }); break; default: break; } } //等待完成 30s Task.WaitAll(taskArr, TimeSpan.FromSeconds(30)); foreach (var item in taskArr) { code += item.Result; } } catch (Exception ex) { code = "我爱祖国"; } return code; }
キーワード タスクは、ここでも引き続き使用され、タスクを分散して異なる検証コードを取得します目次 個人的には、検証コードの組み合わせを決定するパラメータ string codeType = "1|2|3|4 " を設定することが最も重要であると考えており、これにより検証コード形式の多様性も実現されます。 ;
» 画像に確認コードを描画します
まず、特定の画像にテキストを描画する必要があることを明確にする必要があります。グラフィックス キーワードを使用してキャンバスを作成し、画像上の認証コードです。最初にコードを示します。
/// <summary> /// 生成验证码图片流 /// </summary> /// <param name="code">验证码文字</param> /// <returns>流</returns> public static byte[] CreateValidateCodeStream(string code = "我爱祖国", int fontSize = 18, int width = 0, int height = 0, string fontFamily = "华文楷体") { var bb = new byte[0]; //初始化画布 var padding = 2; var len = code.Length; width = width <= 0 ? fontSize * 2 * (len - 1) + padding * 4 : width; height = height <= 0 ? fontSize * 2 : height; var image = new Bitmap(width, height); var g = Graphics.FromImage(image); try { var random = new Random(); //清空背景色 g.Clear(Color.White); //画横向中间干扰线 var x1 = 0; var y1 = height / 2; var x2 = width; var y2 = y1; g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2); //字体 var font = new Font(fontFamily, fontSize, (FontStyle.Bold | FontStyle.Italic)); var brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1f, true); //画文字 var stringFomart = new StringFormat(); //垂直居中 stringFomart.LineAlignment = StringAlignment.Center; //水平居中 stringFomart.Alignment = StringAlignment.Center; var rf = new Rectangle(Point.Empty, new Size(width, height)); g.DrawString(code, font, brush, rf, stringFomart); //画图片的前景干扰点 for (int i = 0; i < 100; i++) { var x = random.Next(image.Width); var y = random.Next(image.Height); image.SetPixel(x, y, Color.FromArgb(random.Next())); } //画图片的边框线 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1); //保存图片流 var stream = new MemoryStream(); image.Save(stream, ImageFormat.Jpeg); //输出图片流 bb = stream.ToArray(); } catch (Exception ex) { } finally { g.Dispose(); image.Dispose(); } return bb; }
これは、画像の高さと幅を設定する必要があることを示しています。さまざまな
ページ レイアウト方法に依存するため、ここでは高さと幅が渡すパラメーターとして使用されます2. 干渉ライン: 通常、検証コード画像は 1 つまたは 2 つです。干渉ラインは主に、一部の悪意のあるユーザーが使用するのを防ぐために使用されます。ここでは、
g.DrawLine(new Pen(Color.DarkRed), x1 , y1, x2, y2); のような水平方向中央の直線コードのみを設定します。 3. フォント: 見栄えの良いフォントは通常、ユーザー エクスペリエンスにも影響するため、必要なパラメーターに従ってフォントがここに渡されます。
4. 検証コードは画像の垂直方向と水平方向の中央にあります。コードは次のとおりです:
var stringFomart = new StringFormat(); //垂直居中 stringFomart.LineAlignment = StringAlignment.Center; //水平居中 stringFomart.Alignment = StringAlignment.Center;
5.
主に画像上にテキストを描画するために使用され、これは最も重要な部分です6。通常、実際に物理的な検証コード イメージを生成してサーバーに保存するのではなく、検証コードをイメージ ストリームに変換します。そうしないと、サーバーのディスクがすぐに不足してしまうため、
//保存图片流 var stream = new MemoryStream(); image.Save(stream, ImageFormat.Jpeg); //输出图片流 bb = stream.ToArray();
この文は重要です。パフォーマンスが低下する可能性があります。主なことは、簡単に使用できるようにペイント コンテンツをストリームに保存することです
»
上記の検証により、コード生成クラスが適切な検証コード イメージを生成した場合、その正確さと効果をテストして検証する必要があります。以下では、mvc アーキテクチャを使用してテストを行い、最初に検証コード テスト アクションを作成します。対応する ValidCode.cshtml ファイルを生成し、カスタマイズします。アクションを取得するには、いくつかの異なる形式の検証コードが使用されます。コードは次のとおりです。
public FileResult GetValidateCode() { //返回的验证码文字 var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode01() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "1|2|3|4"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode02() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "4|3|2|1"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode03() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "2|2|2|2"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode04() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "4|4|4|4"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode05() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "1|1|1|1"); return File(bb_code, "image/jpeg"); }
見た目はほぼ同じですが、対応するパラメータが異なります。ここで使用するメソッドは GetValidateCodeStream パラメーターの codeType 形式です。空は自由な組み合わせを意味します。1: 小文字のピンイン 2: 大文字のピンイン 3: 数字 4: 中国語の文字。次に、図に次のコードを入力します。 、次のようにプロジェクトを生成してレンダリングを見てみましょう:
能从图中看到我们验证码格式的不同之处,这也是文章开头说的验证码格式的多样性,当然可能还有其他组成格式请允许我暂时忽略,下面我们来做一个点击图片获取新验证码的功能和点击登录按钮去后台程序判断验证码是否匹配的例子,先来修改试图界面代码如下:
@{ ViewBag.Title = "ValidtCode"; } <h2>神牛 - 验证码实例</h2> <p class="container " id="appVue"> <table class="table table-bordered text-left"> <tbody> <tr> <td>全部随机</td> <td> <img src="/home/GetValidateCode" src="/home/GetValidateCode" id="imgCode" /> <input type="text" name="code" placeholder="请输入验证码" class="form-control" /> <button class="btn btn-default">登 录</button> <span id="msg" style="color:red"></span> </td> </tr> <tr> <td>小写|大写|数字|汉字</td> <td><img src="/home/GetValidateCode01" src="/home/GetValidateCode01" /></td> </tr> <tr> <td>汉字|数字|大写|小写</td> <td><img src="/home/GetValidateCode02" src="/home/GetValidateCode02" /></td> </tr> <tr> <td>全部大写</td> <td><img src="/home/GetValidateCode03" src="/home/GetValidateCode03" /></td> </tr> <tr> <td>全部汉字</td> <td><img src="/home/GetValidateCode04" src="/home/GetValidateCode04" /></td> </tr> <tr> <td>全部小写</td> <td><img src="/home/GetValidateCode05" src="/home/GetValidateCode05" /></td> </tr> </tbody> </table> </p> <script src="~/Scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript"> $(function () { $("img").on("click", function () { var nowTime = new Date().getTime(); var src = $(this).attr("src") + "?t=" + nowTime; if (src.length <= 0) { return; } $(this).attr("src", src); }); $("button").on("click", function () { var msg = $("#msg"); var code = $("input[name='code']").val(); if (code.length <= 0) { msg.html("请输入验证码!"); return; } $.post("/home/UserLogin", { code: code }, function (result) { if (result) { msg.html(result.Msg); if (!result.IsOk) { $("#imgCode").click(); } } }); }) }) </script>
然后在Controller中增加如下登录验证代码:
public JsonResult UserLogin(string code) { var data = new Stage.Com.Extend.StageModel.MoData(); if (string.IsNullOrWhiteSpace(code)) { data.Msg = "验证码不能为空"; return Json(data); } var compareCode = Session["code"]; if (!compareCode.Equals(code)) { data.Msg = "验证码错误"; return Json(data); } data.IsOk = true; data.Msg = "验证码验证成功"; return Json(data); } public FileResult GetValidateCode() { //返回的验证码文字 var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code); var key = "code"; if (Session[key] != null) { Session.Remove(key); } Session[key] = code; return File(bb_code, "image/jpeg"); }
由于我这里无法截动态图,所点击测试获取验证码我这里直接给出线上的一个例子,各位可以试试:http://lovexins.com:1001/home/ValidCode,点击获取新验证码的关键代码是: $(this).attr("src", src); 重新给img元素的scr赋值,不过这里要注意由于浏览器缓存的原因,这里赋值的时候需要加上一个动态参数,我这里是使用时间作为请求参数,因此有了以下的代码: $(this).attr("src") + "?t=" + nowTime; 这是特别的地方需要注意;好了咋们来直接测试登陆是否能从后端判断验证码是否正确匹配吧,这里用的是session来保存获取验证码图片返回的验证代码,然后在登陆时候判断用户数据的验证码是否和后台session的验证一样:
验证失败:
验证成功:
好了测试用例就这么多,如果您觉得我这个验证码生成例子还可以并且您希望使用那么请注意,参数的传递,不同得到的验证码格式不同,主要方法是:
/// <summary> /// 获取验证码图片流 /// </summary> /// <param name="codeLen">验证码个数(codeType设置 > codeLen设置)</param> /// <param name="codeType">为空表示自由组合 1:小写拼音 2:大写拼音 3:数字 4:汉字</param> /// <returns></returns> public static byte[] GetValidateCodeStream(ref string code, string codeType = "", int codeLen = 0, int fontSize = 18, int width = 120, int height = 30) { //为空自由组合 if (string.IsNullOrWhiteSpace(codeType)) { for (int i = 0; i < codeLen; i++) { codeType += rm.Next(1, 5) + "|"; } } code = CreateCode(codeType); return CreateValidateCodeStream(code, fontSize, width: width, height: height); }
具体参数各位可以看下备注,我这里顺便打包下代码,方便分享和使用:验证码生成示例
以上が検証コード生成クラスの実装 (数字、ピンイン、漢字を含む)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。