Maison > Article > développement back-end > Implémenter une classe de génération de code de vérification (comprenant des chiffres, du pinyin et des caractères chinois)
Cet article partage avec vous une classe de génération de code de vérification qui intègre 1 : Pinyin minuscule ; 2 : Pinyin majuscule ; 3 : chiffres 4 : caractères chinois ; Les exemples de ce chapitre incluront également un scénario dans lequel mvc utilise la vérification du code de vérification. Il a une certaine valeur de référence, jetons un œil avec l'éditeur ci-dessous
Ce que je partage avec vous cette fois est une classe de génération de code de vérification qui intègre 1 : Pinyin minuscule 2 : Pinyin majuscule 3 : Numéro 4 : Chinois Caractères, À en juger par le titre, cela semble très ordinaire. Oui, c'est très ordinaire. Cependant, lors de la génération de cette classe de code de vérification, vous pouvez spécifier les règles du format de retour du code de vérification via des paramètres. un peu de praticité pour tout le monde. Les exemples de ce chapitre incluront également un scénario dans lequel MVC utilise le code de vérification pour la vérification. J'espère que vous l'aimerez.
» Organigramme de génération de code de vérification
» Analyse du code du pool de génération de code de vérification
» Tirage au sort de vérification le code sur l'image
» Opération de connexion mvc pour tester l'exactitude du code de vérification
Partagez-le étape par étape ci-dessous :
» Organigramme de génération de code de vérification
Tout d'abord, jetons un coup d'œil à l'organigramme de génération de la classe de génération de code de vérification partagé cette fois :
Vous pouvez voir que le pool de génération d'encodage décrit dans cette image correspond à plusieurs contenus d'encodage différents. Ici, il est principalement permis d'obtenir différents contenus d'encodage en même temps en fonction des réglages des paramètres. arrivez au code de vérification qui est combiné avec du texte, du pinyin et des caractères chinois. Plus précisément, Les paramètres des règles sont déterminés par des paramètres ;
» Analyse du code du pool de génération de code de vérification
Tout d'abord, il ressort de l'analyse de l'organigramme ci-dessus que, ce pool de génération de code de vérification doit obtenir différents types de données de code de vérification en parallèle pour répondre au code de vérification combiné, donc le code suivant est disponible :/// <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; }Continuer à être utilisé ici Le mot-clé Task est utilisé pour répartir les tâches afin d'obtenir différents contenus de code de vérification. Personnellement, je pense que le plus important est de. déterminez-le via le paramétrage
string codeType = "1|2|3|4" La combinaison de codes de vérification permet également d'obtenir la diversité des formats de codes de vérification
» Dessinez le code de vérification sur l'imageTout d'abord, nous devons être clairs. Si vous souhaitez dessiner du texte sur une image, vous devez utiliser le mot-clé Graphics pour créer un canevas et dessinez notre code de vérification sur l'image. Voici le code :
/// <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; }
1. La hauteur et la largeur de l'image doivent être définies, ce qui dépend des différentes méthodes de
mise en page, donc ici la hauteur et la largeur sont utilisées comme paramètres pour passer 2. Lignes d'interférence : généralement les images de code de vérification ont une ou deux lignes d'interférence, principalement pour empêcher certains utilisateurs malveillants d'utiliser un logiciel de reconnaissance d'image pour faire des demandes de craquage irrégulières. La ligne d'interférence ici, je n'ai configuré qu'un code de ligne droite centré horizontalement tel que :
g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2);Police : Une belle police est généralement aussi une police. expérience utilisateur, la police est donc transmise ici selon les paramètres requis ;
4. Le code de vérification est situé au centre vertical et horizontal de l'image. Le code clé ici est : .
5.
var stringFomart = new StringFormat(); //垂直居中 stringFomart.LineAlignment = StringAlignment.Center; //水平居中 stringFomart.Alignment = StringAlignment.Center;g.DrawString(code, font, brush, rf, stringFomart
est principalement utilisé pour dessiner du texte sur le l'image est la partie la plus critique 6. Nous transformons généralement le code de vérification en flux d'images au lieu de générer réellement une image de code de vérification d'entité et de l'enregistrer sur le serveur, sinon de cette façon, le serveur fonctionnera bientôt est à court de disque, donc l'importance de
ne peut pas être ignorée. L'essentiel est de sauvegarder le contenu de la peinture dans le flux pour une utilisation facile
//保存图片流 var stream = new MemoryStream(); image.Save(stream, ImageFormat.Jpeg); //输出图片流 bb = stream.ToArray();» opération de connexion mvc pour tester l'exactitude du code de vérification
Avec la vérification ci-dessus La classe générée par le code génère une bonne image de code de vérification, nous devons ensuite tester et vérifier l'exactitude et l'effet ; ci-dessous, nous utilisons l'architecture mvc pour effectuer le test, créons d'abord une action de test de code de vérification et générons le fichier ValidCode.cshtml correspondant, puis personnalisez quelques codes de vérification dans différents formats pour obtenir l'action. Le code est le suivant :
C'est presque exactement la même chose, sauf que les paramètres correspondants sont. différent. La méthode suivie ici est le format codeType du paramètre GetValidateCodeStream. : Vide signifie combinaison libre 1 : Pinyin minuscule 2 : Pinyin majuscule 3 : Chiffre 4 : Caractère chinois Ensuite, nous remplissons le code suivant dans le diagramme :
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"); }D'accord Générons le projet et regardons les rendus comme suit :
<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>
能从图中看到我们验证码格式的不同之处,这也是文章开头说的验证码格式的多样性,当然可能还有其他组成格式请允许我暂时忽略,下面我们来做一个点击图片获取新验证码的功能和点击登录按钮去后台程序判断验证码是否匹配的例子,先来修改试图界面代码如下:
@{ 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>
然后在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); }
具体参数各位可以看下备注,我这里顺便打包下代码,方便分享和使用:验证码生成示例
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!