Baru-baru ini, saya menerima tugas di tempat kerja untuk mengembangkan fungsi kode verifikasi halaman. Saya berkonsultasi dengan beberapa informasi online dan dikombinasikan dengan pengetahuan menggambar saya sebelumnya, saya menerapkan solusi berikut. Kode verifikasi yang dihasilkan terlihat seperti ini:
Masalah yang harus dipecahkan:
1. Cara membuat gambar secara acak
untuk menghasilkan objek System.Drawing.Bitmap, dan menggunakan System.Drawing.Graphics untuk menggambar ke dalam objek bitmap.
2. Cara meneruskan data gambar melalui parameter dalam metode WebService
untuk mengeluarkan objek Bitmap ke dalam aliran byte, dan WebMothod menggunakan array byte untuk mengembalikan aliran byte.
Contoh:
1. Gunakan VS.NET 2003 untuk membuat proyek Layanan Web ASP.NET. Nama Layanan default adalah MyService, dan Metode Web bernama GenerateVerifyImage ditambahkan ke MyService. Kode metode ini adalah sebagai berikut:
/// <ringkasan>
/// Buat kode verifikasi gambar
/// </ringkasan>
/// <param name="nLen">Panjang kode verifikasi</param>
/// <param name="strKey">Parameter keluaran, isi kode verifikasi</param>
/// <returns>Aliran byte gambar</returns>
[Metode Web]
byte publik[] GenerateVerifyImage(int nLen,ref string strKey)
{
int nBmpLebar = 13*nLen+5;
int nBmpTinggi = 25;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth,nBmpHeight);
// 1. Menghasilkan warna latar belakang acak
int nMerah,nHijau,nBiru; // Warna ternary latar belakang
System.Random rd = new Random((int)System.DateTime.Now.Ticks);
nMerah = rd.Berikutnya(255)%128+128;
nHijau = rd.Berikutnya(255)%128+128;
nBlue = rd.Next(255)%128+128;
// 2. Isi latar belakang bitmap
Grafik Sistem.Gambar.Grafik = Sistem.Gambar.Grafik.FromImage(bmp);
graph.FillRectangle(SolidBrush baru(Sistem.Gambar.Warna.DariArgb(nMerah,nHijau,nBiru))
,0
,0
,nBmpLebar
,nBmpTinggi);
// 3. Gambarlah garis interferensi, dengan menggunakan warna yang sedikit lebih gelap dari latar belakang
int nGaris = 3;
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
untuk(int a =0;a< nGaris;a++)
{
int x1 = rd.Berikutnya() % nBmpLebar;
int y1 = rd.Berikutnya() % nBmpTinggi;
int x2 = rd.Berikutnya() % nBmpLebar;
int y2 = rd.Berikutnya() % nBmpTinggi;
grafik.DrawLine(pena,x1,y1,x2,y2);
}
// Kumpulan karakter yang digunakan dapat diperluas kapan saja dan kemungkinan kemunculan karakter dapat dikontrol
string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 4. Ulangi untuk mendapatkan karakter dan menggambarnya
string strHasil = "";
untuk(int i=0;i<nLen;i++)
{
int x = (i*13 + rd.Berikutnya(3));
int y = rd.Berikutnya(4) + 1;
// Tentukan fontnya
System.Drawing.Font font = new System.Drawing.Font("Kurir Baru",
12 + rd.Berikutnya()%4,
Sistem.Gambar.FontStyle.Bold);
char c = strCode[rd.Next(strCode.Length)]; // Dapatkan karakter acak
strResult += c.ToString();
// Menggambar karakter
grafik.DrawString(c.ToString(),
huruf,
SolidBrush baru(Sistem.Gambar.Warna.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)),
X,
kamu);
}
// 5. Aliran byte keluaran
System.IO.MemoryStream bstream = Sistem.IO.MemoryStream() baru;
bmp.Simpan(bstream,Sistem.Gambar.Pencitraan.ImageFormat.Jpeg);
bmp.Buang();
grafik.Buang();
strKey = strHasil;
byte[] byteReturn = bstream.ToArray();
bstream.Tutup();
kembalikan byteReturn;
}
2. Uji WebMethod, tambahkan WebForm, referensikan WebService di atas, dan nama referensinya adalah imagesvr. Tambahkan kode di Page_Load:
...
imagesvr.MyService imgsvr = gambar baruvr.MyService();
string strKey = "";
byte[] data = imgsvr.GenerateVerifyImage(5,ref strKey);
Respon.OutputStream.Write(data,0,data.Panjang);
...
3. Lari. Setiap kali WebForm disegarkan, kode verifikasi gambar yang baru dibuat akan ditampilkan, dan parameter keluaran strKey dari fungsi tersebut menyimpan konten sebenarnya dari kode verifikasi, yang dapat disimpan di Sesi untuk verifikasi.
Setelah pengembangan kode verifikasi gambar terakhir kali, berdasarkan saran dari beberapa teman, berdasarkan prinsip bahwa kode verifikasi mudah dikenali (bagi orang), sulit untuk dipecahkan, dan indah, algoritma pembuatan kode verifikasi telah diperbaiki, dan metode filter gambar telah digunakan untuk memfilter gambar. Kode verifikasi dikenakan gangguan anti-crack, dan contoh gambar hasilnya adalah sebagai berikut:
Efek filter terutama menggunakan algoritma gelombang, yang menghasilkan efek superposisi dengan memproses bentuk gelombang sinus dari sumbu X dan sumbu Y. Deskripsi utama dari algoritma ini adalah sebagai berikut:
private const double PI = 3.1415926535897932384626433832795;
private const double PI2 = 6.283185307179586476925286766559;
/// <ringkasan>
/// Gambar terdistorsi gelombang sinusoidal
/// </ringkasan>
/// <param nama="srcBmp"></param>
/// <param nama="bXDir"></param>
/// <param name="nMultValue">Kelipatan amplitudo bentuk gelombang</param>
/// <param name="dPhase">Fase awal bentuk gelombang, rentang nilai [0-2*PI)</param>
/// <pengembalian></pengembalian>
Sistem publik.Gambar.Bitmap TwistImage(Bitmap srcBmp,bool bXDir,dMultValue ganda,dPhase ganda)
{
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width,srcBmp.Height);
// Isi latar belakang bitmap dengan warna putih
Grafik Sistem.Gambar.Grafik = Sistem.Gambar.Grafik.FromImage(destBmp);
graph.FillRectangle(New SolidBrush(System.Drawing.Color.White),0,0,destBmp.Width,destBmp.Height);
grafik.Buang();
double dBaseAxisLen = bXDir ? (ganda)destBmp.Height : (ganda)destBmp.Width;
for(int i=0;i<destBmp.Width;i++)
{
untuk(int j=0;j<destBmp.Tinggi;j++)
{
dx ganda = 0;
dx = bXDir ? (PI2*(ganda)j)/dBaseAxisLen : (PI2*(ganda)i)/dBaseAxisLen;
dx += dFase;
double dy = Math.Sin(dx);
// Mendapatkan warna titik saat ini
int nLamaX = 0,nLamaY = 0;
nOldX = bXDir ? saya + (int)(dy*dMultValue) : saya;
nOldY = bXDir ? j : j + (int)(dy*dMultValue);
Sistem.Gambar.Warna = srcBmp.GetPixel(i,j);
if(nOldX >= 0 && nOldX < destBmp.Lebar
&& nLama >=0 && nLama < tujuanBmp.Tinggi)
{
destBmp.SetPixel(nOldX,nOldY,color);
}
}
}
kembalikan tujuanBmp;
}
Contoh gambar di awal adalah superposisi dua efek bentuk gelombang. Kedua efek tersebut masing-masing untuk arah sumbu X dan arah sumbu Y. Jika Anda membatalkan pengisian warna latar tepi, Anda dapat melihat dampaknya algoritma pada grafik, seperti yang ditunjukkan di bawah ini:
Kode verifikasi yang dihasilkan dengan cara ini sangat mirip dengan kode verifikasi di situs Google. Tentunya jika tertarik, Anda juga dapat menambahkan efek filter lain seperti peregangan, rotasi, mosaik, dll. Namun perlu diingat bahwa semakin rumit kode verifikasi situs web, semakin baik Anda harus menemukan keseimbangan antara kecepatan dan keamanan.