최근 직장에서 페이지 인증 코드 기능을 개발하라는 과제를 받았는데, 온라인 정보를 참고하고 이전 드로잉 지식을 결합하여 다음 솔루션을 구현했습니다. 생성된 인증 코드는 다음과 같습니다.
해결해야 할 문제:
1. 그림을 무작위로 생성하여 System. Drawing.Bitmap 개체를 생성하고 System. Drawing.Graphics를 사용하여 비트맵 개체에 그리는
방법
.2. WebService 메소드의 매개변수를 통해 이미지 데이터를 전달하여
Bitmap 객체를 바이트 스트림으로 출력하는 방법과 WebMothod는 바이트 배열을 사용하여 바이트 스트림을 반환합니다.
예:
1. VS.NET 2003을 사용하여 ASP.NET Webservice 프로젝트를 만듭니다. 기본 서비스 이름은 MyService이고, GeneratorVerifyImage라는 WebMethod가 MyService에 추가됩니다. 이 메소드의 코드는 다음과 같습니다.
/// <summary>
/// 이미지 인증코드 생성
/// </summary>
/// <param name="nLen">인증코드 길이</param>
/// <param name="strKey">출력 매개변수, 인증코드 내용</param>
/// <returns>이미지 바이트 스트림</returns>
[웹방법]
공개 바이트[] 생성VerifyImage(int nLen,ref string strKey)
{
int nBmpWidth = 13*nLen+5;
int nBmpHeight = 25;
System.드로잉.Bitmap bmp = new System.드로잉.Bitmap(nBmpWidth,nBmpHeight)
// 1. 임의의 배경색을 생성합니다.
int nRed,nGreen,nBlue; // 배경의 삼원색
System.Random rd = new Random((int)System.DateTime.Now.Ticks);
nRed = rd.Next(255)%128+128;
nGreen = rd.Next(255)%128+128;
nBlue = rd.Next(255)%128+128;
// 2. 비트맵 배경 채우기
시스템.드로잉.그래픽 그래프 = 시스템.드로잉.그래픽.FromImage(bmp);
graph.FillRectangle(new SolidBrush(System.드로잉.Color.FromArgb(nRed,nGreen,nBlue)))
,0
,0
,nBmp폭
,nBmp높이);
// 3. 배경보다 약간 어두운 색상을 사용하여 간섭선을 그립니다.
int nLines = 3;
System.드로잉.펜 펜 = 새로운 System.드로잉.펜(System.드로잉.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
for(int a =0;a< nLines;a++)
{
int x1 = rd.Next() % nBmpWidth;
int y1 = rd.Next() % nBmpHeight;
int x2 = rd.Next() % nBmpWidth;
int y2 = rd.Next() % nBmpHeight;
graph.DrawLine(펜,x1,y1,x2,y2);
}
// 사용되는 문자 세트는 언제든지 확장 가능하며 문자 등장 확률도 제어할 수 있습니다.
string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 4. 문자를 가져와서 그립니다.
문자열 strResult = "";
for(int i=0;i<nLen;i++)
{
int x = (i*13 + rd.Next(3));
int y = rd.Next(4) + 1
// 글꼴 결정
System.드로잉.Font 글꼴 = 새 System.드로잉.Font("Courier New",
12 + rd.다음()%4,
시스템.드로잉.글꼴스타일.볼드);
char c = strCode[rd.Next(strCode.Length)]; // 임의의 문자 가져오기
strResult += c.ToString()
// 문자 그리기
graph.DrawString(c.ToString(),
세례반,
새로운 SolidBrush(System.드로잉.Color.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)),
엑스,
와이);
}
// 5. 출력 바이트 스트림
System.IO.MemoryStream bstream = new System.IO.MemoryStream();
bmp.Save(bstream,System.드로잉.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
graph.Dispose();
strKey = strResult;
byte[] byteReturn = bstream.ToArray();
bstream.Close();
반환 byteReturn;
}
2. WebMethod를 테스트하고 WebForm을 추가한 후 위의 WebService를 참조하고 참조 이름은 Imagesvr입니다. Page_Load에 코드 추가:
...
Imagesvr.MyService imgsvr = 새로운 이미지vr.MyService();
문자열 strKey = "";
byte[] 데이터 = imgsvr.GenerateVerifyImage(5,ref strKey);
Response.OutputStream.Write(data,0,data.Length);
...
3. 실행합니다. WebForm이 새로고침될 때마다 새로 생성된 이미지 인증코드가 표시되며, 함수의 출력 매개변수 strKey는 인증코드의 실제 내용을 저장하며, 인증을 위해 세션에 저장할 수 있습니다.
지난번 사진 인증코드를 개발한 후, 몇몇 친구들의 제안을 바탕으로 인증코드는 (사람에게) 인식하기 쉽고, 해독하기 어렵고, 아름답다는 원칙을 바탕으로 인증코드 생성 알고리즘을 개선했으며, 이미지 필터 방법을 사용하여 사진을 필터링했습니다. 인증 코드는 크랙 방지 간섭을 받으며 결과 사진 예는 다음과 같습니다.
필터효과는 주로 X축과 Y축의 사인파형을 처리하여 중첩효과를 내는 Wave 알고리즘을 사용한다. 알고리즘의 주요 설명은 다음과 같습니다.
private const double PI = 3.1415926535897932384626433832795;
private const double PI2 = 6.283185307179586476925286766559
/// <요약>
/// 정현파 왜곡된 그림
/// </summary>
/// <param name="srcBmp"></param>
/// <param name="bXDir"></param>
/// <param name="nMultValue">파형의 진폭 배수</param>
/// <param name="dPhase">파형의 시작 위상, 값 범위 [0-2*PI)</param>
/// <반환></반환>
공개 System.드로잉.Bitmap TwistImage(Bitmap srcBmp,bool bXDir,double dMultValue,double dPhase)
{
System.드로잉.Bitmap destBmp = new Bitmap(srcBmp.Width,srcBmp.Height)
// 비트맵 배경을 흰색으로 채웁니다.
System.드로잉.그래픽 그래프 = System.드로잉.그래픽.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(System.드로잉.Color.White),0,0,destBmp.Width,destBmp.Height);
그래프.Dispose();
double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
for(int i=0;i<destBmp.Width;i++)
{
for(int j=0;j<destBmp.Height;j++)
{
더블 dx = 0;
dx = bXDir ? (PI2*(double)j)/dBaseAxisLen : (PI2*(double)i)/dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// 현재 지점의 색상을 가져옵니다.
int nOldX = 0,nOldY = 0;
nOldX = bXDir ? i + (int)(dy*dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy*dMultValue);
System.드로잉.Color = srcBmp.GetPixel(i,j);
if(nOldX >= 0 && nOldX < destBmp.Width
&& nOldY >=0 && nOldY < destBmp.Height)
{
destBmp.SetPixel(nOldX,nOldY,color);
}
}
}
destBmp를 반환합니다.
}
시작 부분의 예시 그림은 두 개의 파형 효과가 각각 X축 방향과 Y축 방향에 대한 중첩입니다. 가장자리 배경색 채우기를 취소하면 효과를 볼 수 있습니다. 아래와 같이 그래픽의 알고리즘:
이렇게 생성된 인증코드는 구글 사이트의 인증코드와 많이 유사해 보입니다. 물론, 관심이 있으시면 늘이기, 회전, 모자이크 등의 다른 필터 효과를 추가하실 수도 있습니다. 하지만 웹사이트 인증 코드는 복잡할수록 속도와 보안 사이의 균형을 찾아야 합니다.