하하, 오랫동안 안 올라왔네요. 드디어 인증코드를 누르는 모습이 재미있어 보여서 직접 써보고 싶었습니다.
먼저 렌더링
이 효과에 끌리셨다면 계속 읽어주세요.
코드를 게시하기 전에 몇 가지 아이디어에 대해 이야기하겠습니다.
1. 한자 라이브러리가 있어야 하고 글리프에 따라 분류됩니다. (데이터베이스에 부수를 분류했습니다)
2. 인증코드 받기(즉, 몇 단어를 입력해서 인증코드를 만듭니다)
3. 를 바탕으로 비슷한 모양의 단어 찾기
4. 인증코드 텍스트와 비슷한 모양의 단어 정렬
5. 그림 그리기
6. 디스플레이
1. 캐릭터 라이브러리 획득
우리나라 문화가 깊고 심오한데, 그 많은 매운 캐릭터는 어디서 오는 걸까요? 물론 수동으로 추가할 수는 없어서 인터넷에서 한자를 검색해 다른 사람의 데이터를 캡쳐할 수 있는 웹사이트를 우연히 발견했다. 데이터를 캡처하려면 포털을 클릭하세요. 포털에 언급된 내용은 단지 생각의 흐름일 뿐입니다. 이해가 되지 않는 점이 있으면 말씀해 주세요. 아래에 글꼴 라이브러리를 공유하겠습니다.
2. 인증코드 받기
여기에 직접 코드를 붙여넣어보겠습니다. 4개의 데이터를 무작위로 뽑아서 가져옵니다. . 편의상 이렇게 썼습니다. 개인적으로는 먼저 ID를 무작위로 생성한 후, ID를 기반으로 직접 데이터를 가져오는 것이 다음 작성 방법보다 쿼리 속도가 더 빨라질 것이라고 생각합니다. (참고로 제가 사용하는 데이터베이스는 MySql입니다.)
/// <summary> /// 获取验证码 /// </summary> public List<VerificationCode.Model.WenZhi> GetCodeText() { const string sql = "SELECT * FROM wenzhi ORDER BY RAND() LIMIT 4"; var dataReader = dbHelper.GetDataReader(sql); var list = DataReaderToList(dataReader); dataReader.Close(); return list; }
3. 추출된 텍스트를 바탕으로 유사한 단어를 찾습니다
첫 번째 단계에서 부수를 저장했기 때문에 여기에서 직접 근수를 기준으로 현재 근수의 가까운 단어를 구합니다.
/// <summary> /// 获取答案备选 /// </summary> /// <param name="buShouCode">部首编码</param> /// <param name="id">当前文字ID</param> /// <param name="number">数量</param> /// <returns></returns> public List<VerificationCode.Model.WenZhi> GetAnswer(string buShouCode, int id,int number=1) { string sql = $"SELECT * FROM wenzhi where BuShouCode='{buShouCode}' and ID <> {id} ORDER BY RAND() LIMIT "+ number; var dataReader = dbHelper.GetDataReader(sql); var list = DataReaderToList(dataReader); dataReader.Close(); return list; }
4. 인증코드 텍스트 및 유사 단어 배열
다음 코드는 먼저 대체 답변과 인증코드를 세트에 넣은 후 세트를 정렬합니다
public Model.Code GetCode() { var wenzlist = _wenZhiDal.GetCodeText(); //获取验证码 var listAnsuwr = new List<Answer>();//实例化备选答案对象 var answerCode = string.Empty;//答案 var result = new Model.Code { Id = Guid.NewGuid().ToString() }; //根据验证码获取备选答案并把添加到答案添加到备选答案集合 foreach (var item in wenzlist) { answerCode += item.ID + ","; result.AnswerValue += item.Text; var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID); listAnsuwr.Add(new Answer { Id = item.ID.ToString(), Img = GetImage(item.Text) }); listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) })); } //如果答案个数不够就再去取几个 if (listAnsuwr.Count < 9) { var ran = new Random(); var randKey = ran.Next(0, 4); var item = wenzlist[randKey]; var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID, 9 - listAnsuwr.Count); listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) })); } result.CodeImg = GetImage(result.AnswerValue);//获取图片 result.AnswerValue = answerCode.TrimEnd(','); result.Answer = RandomSortList(listAnsuwr);//打乱正确答案与形近字的顺序 return result; }
컬렉션 정렬 코드입니다
/// <summary> /// 随机排列集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="listT"></param> /// <returns></returns> private static List<T> RandomSortList<T>(IEnumerable<T> listT) { var random = new Random(); var newList = new List<T>(); foreach (var item in listT) { newList.Insert(random.Next(newList.Count + 1), item); } return newList; }
5. 그림 그리기
다음은 그림 그리기에 대한 코드입니다. 인증 코드와 대체 답변은 두 가지 그림에 해당합니다. (내부 설명은 매우 명확합니다). 텍스트가 x° 회전된 후에는 인간이 차이를 구분할 수 없다고 걱정하지 마세요. 하하. 코드의 마지막 문장에서는 프런트엔드 호출을 용이하게 하기 위해 이미지를 Base64로 변환했습니다.
private static string GetImage(string text) { Image image; switch (text.Length) { case 1: image = new Bitmap(50, 40); break; case 4: image = new Bitmap(120, 40); break; default: image = new Bitmap(50, 40); break; } Brush brushText = new SolidBrush(Color.FromArgb(255, 0, 0, 0)); var graphics = Graphics.FromImage(image); graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.Clear(Color.White); var font = new Font(new FontFamily("华文彩云"), 20, FontStyle.Regular); if (text.Length > 1)//画验证码 { //先来两条直线做干扰 然后再画文字 graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(0, 10), new Random().Next(10, 40)), new Point(new Random().Next(100, 120), new Random().Next(10, 30))); graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(20, 50), new Random().Next(0, 10)), new Point(new Random().Next(100, 120), new Random().Next(30, 40))); graphics.DrawString(text, font, brushText, 0, 10); } else//画备选答案 { Point middle = new Point(25, 20); graphics.TranslateTransform(middle.X, middle.Y); //这里是360°随机旋转 graphics.RotateTransform(new Random().Next(0, 360)); var format = new StringFormat(StringFormatFlags.NoClip) { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; graphics.DrawString(text, font, brushText, 0, 0, format); } brushText.Dispose(); graphics.Dispose(); return ImageToBase64(image); }
6. 표시
GetCode 메서드를 직접 호출하면 인증 코드 개체를 반환할 수 있습니다
다음은 배경 코드입니다. 정답은 AnswerValue에 들어있기 때문에 먼저 꺼내서 Session에 넣은 뒤 값을 클리어한 뒤 json을 통해 브라우저에 돌려줍니다. <… 확인 아이디어: 각 사진은 ID에 해당하며, 선택한 사진의 ID를 쉼표로 구분하여 가져온 다음 Session의 값과 비교)
public string GetVerCode() { var code = new VerificationCode.Code().GetCode(); Session["VERCODE"] = code.AnswerValue; code.AnswerValue = ""; return JsonConvert.SerializeObject(code); }
이 시점에서 코드가 거의 완성되었습니다. 순수한 개인적인 생각일 뿐입니다. 관심 있는 친구들이 함께 토론해 보세요.
위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다.
asp.net 클릭 인증 코드 구현 아이디어와 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!