Xây dựng thành phần sinh ảnh chống đăng nhập tự động

Phần mở đầu Ngày nay để có một tài khoản thư điện tử, điều đó thật dễ dàng, chúng ta chỉ cần vào một hệ thống nào đó cho phép tạo thư điện tử như yahoo, hotmail, google, vnn và đăng ký một tài khoản. Vậy là chúng ta đã có một tài khoản để có thể gửi thư, chát và sử dụng các tiện ích của thư điện tử. Tuy nhiên đối với hệ thống mailserver, để có thể quản lý tốt hàng triệu tài khoản thực và để tránh cho các chương trình đăng ký, đăng nhập tự động vào hệ thống thực hiện các hành vi phạm pháp của mình thì việc bảo mật cho hệ thống là điều rất quan trọng. Một trong những biện pháp không cho các chương trình đăng ký, đăng nhập tự động có thể đăng ký tài khoản được mà các hệ thống gần đây thường sử dụng là khi muốn đăng ký một tài khoản hay đăng nhập vào hệ thống thì người dùng phải nhập một mã ngẫu nhiên mà hệ thống đưa ra cho người dùng. Nhận thấy đây là một vần đề còn mới và có tính thực tiễn cao nên em đã chọn để làm đề tài trong khoá luận của mình. Với nội dung như trên, cấu trúc của khoá luận gồm những phần chính sau đây: Phần mở đầu Phần này trình bày tại sao chúng tôi chọn đề tài “Xây dựng thành phần sinh ảnh chống đăng nhập tự động” để nghiên cứu trong khoá luận của mình. Cũng trong phần này chúng tôi sẽ giới thiệu nội dung và cấu trúc của khoá luận. Chương 1: Giới thiệu bài toán và giải pháp Nội dung của chương này là trình bày về vấn đề đăng nhập tự động và tác hại của nó đối với các hệ thống khi bị đăng nhập tự động. Sau đó chúng tôi đưa ra giải pháp để chống lại sự đăng nhập tự động. Đồng thời chương này cũng giới thiệu một số giải pháp tương tự mà một số hệ thống đã triển khai và những ưu, nhược điểm của các giải pháp đó. Chương 2: Cơ sở lý thuyết Chương này sẽ tập trung vào một số thuật toán là cơ sở để giải quyết bài toán đó là các vấn đề sau: ã Thuật toán sinh chuỗi ảnh ngẫu nhiên. ã Các thuật toán sinh nền. ã Các thuật toán biến đổi chuỗi ảnh. ã Các thuật toán gây nhiễu bề mặt chuỗi ảnh. Chương 3: Triển khai thành phần Chương này trình bày các vấn đề cần thiết trong khi triển khai chương trình như cấu trúc của ảnh, các thủ tục hỗ trợ và cách viết các thủ tục. Đồng thời chương này cũng nêu ra cách tạo ra thành phần phục vụ, sử dụng thành phần phục vụ từ trang web và cách viết các trang tin sử dụng thành phần. Chương 4: Thử nghiệm Chương này trình bày các kết quả thử nghiệm và các vấn đề phát sinh trong khi triển khai thành phần. Phần kết luận Trong phần này tổng kết lại những kết quả đã đạt được và chưa đạt được. Từ đó nêu lên những hướng nghiên cứu, phát triển tiếp theo. Các phần phụ lục Các phần phụ lục sẽ cung cấp thông tin về tài liệu tham khảo, danh mục các thuật toán, các hình.

doc57 trang | Chia sẻ: lvcdongnoi | Lượt xem: 2294 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Xây dựng thành phần sinh ảnh chống đăng nhập tự động, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
a? Thực hiện như thế nào và có thể sử dụng lại được không? 1.4.1. Giải pháp đã có của yahoo, hotmail, gmail Việc sử dụng thành phần sinh ảnh tự động để chống đăng nhập đã có một số hệ thống thực hiện mà điển hình là yahoo, google, hotmail tuy nhiên chúng là các chương trình gắn liền với các hệ thống đó. Do đó các hệ thông khác muốn sử dụng lại đều không được. Yahoo đã triển khai giải pháp sinh ảnh tự động từ rất sớm, họ đã ứng dụng việc này vào hai nơi đó là Thứ nhất: Khi đăng ký một tài khoản email, người dùng sau khi đăng ký tên tài khoản, mật khẩu và một số thông tin cần thiết khác, họ cần phải nhập mã xác nhận đăng ký được sinh ngẫu nhiên trước khi hoàn thành việc đăng ký. Mã xác nhận mà người dùng cần nhập Hình 4: Ảnh xác nhận được Yahoo sử dụng khi người dùng đăng ký tài khoản mới Thứ hai: Để vào hòm thư yahoo của mình, người dùng cần phải nhập tên tài khoản, mật khẩu. Nếu người dùng nhập tài khoản và mật khẩu không đúng khoảng 8 lần, hệ thống tự động sinh ra chuỗi ngẫu nhiên yêu cầu người dùng phải nhập chuỗi đó vào ô xác nhận ảnh. Giao diên đăng nhập vào hòm thư mà yahoo áp dụng thành phần sinh ảnh tự động Hình 5: Ảnh xác nhận được Yahoo sử dụng mà người dùng vào hòm thư Chúng ta thấy rằng ảnh xác nhận được yahoo xây dựng dựa trên một nền đen hoặc trắng, chuỗi ngẫu nhiên thì được làm cong theo các kiểu khác nhau. Đồng thời các chuỗi ngẫu nhiên này đã được gây nhiễu để các chương trình nhận dạng dù rất nhạy cũng không thể nhận dạng đúng được chuỗi ký tự, tuy nhiên người dùng vẫn hoàn toàn xác định chính xác chuỗi ký tự đã được sinh ra. Ví dụ trong hình 5, ký tự tại vị trí thứ 2 là chữ “d”, nhưng do việc gây nhiễu đã làm cho chữ “d” đó vừa có nét giống chữ “d” lại vừa có nét giống chữ “q”. Tại vị trí thứ 5, đó là chữ “p” và cũng do gây nhiễu nó trở nên vừa giống chữ “p” vừa giống chữ “d” đối với các hệ nhận dạng. Khi đó hệ nhận dạng sẽ không xác định được đó là chữ gì. Giống như yahoo, gmail và hotmail cũng đã triển khai việc sử dụng thành phần sinh ảnh tự động để chống đăng nhập tự động và họ cũng áp dụng khi người dùng muốn vào hòm thư của mình. Giao diện đăng nhập vào hòm thư áp dụng thành phần sinh ảnh của hotmail và gmail Hình 6: Giải pháp của hotmail và gmail Trong ảnh xác nhận của hotmail thì chuỗi ảnh đã được làm biến dạng và gây nhiễu bằng các đường thẳng và đường cong. Đồng thời hotmail đã cải tiến việc nhận dạng ảnh đối với những người dùng bằng việc đối với ảnh xác nhận người dùng không nhận dạng được thì họ có thể nghe hệ thống đọc các ký tự vừa sinh để điền vào ô xác nhận. Đối với gmail, ảnh xác nhận mà họ xây dựng mới chỉ dừng lại ở việc chuỗi ký tự ngẫu nhiên sinh ra đã được biến dạng, còn việc gây nhiễu thì chưa được thực hiện. 1.4.2. Giải pháp có mã nguồn mở Ngoài yahoo, hotmail, gmail thực hiện giải pháp sinh ảnh tự động để chống đăng nhập tự động, hiện nay cũng có một số chương trình xây dựng thành phần sinh ảnh tự động để chống đăng ký tự động. Họ triển khai giải pháp này bằng mã nguồn viết bằng PHP[21]. Có thể tóm tắt giải pháp của họ như sau: Trước tiên [21] sinh một chuỗi ngẫu nhiên gồm 6 ký tự. Các ký tự được sinh ra là các chữ hoa trong bảng chữ cái alphabe và các chữ số từ 0 đến 9. Giải thuật sinh chuỗi ngẫu nhiên mà [21] viết như sau: function gen_random_string($length = 5, $str = ' ') { for($i =1; $i<=length; $i++) { $ord = rand(48, 90); if((($ord>=48) && ($ord=65) && ($ord<=90))) { $str.=chr($ord); } else $str.=gen_random_string(1); } return $str; } Cùng với việc sinh chuỗi ngẫu nhiên, họ sinh nền ngẫu nhiên dựa trên các hàm có sẵn của PHP, có thể tóm tắt sơ qua giải thuật đó như sau: function Gen_rand_img() { Định nghĩa font của file Định nghĩa một số màu ngẫu nhiên { Xác định màu nền ngẫu nhiên //$bg_colors = array(BACKGROUND COLORS); Xác định màu của font //$font_colors = array(FONT COLORS); } Định nghĩa chiều dài, chiều rộng của ảnh Xác định kích cỡ chữ, khoảng cách giữa các chữ Độ dài chuỗi Gọi hàm sinh chuỗi ngẫu nhiên Thực hiện việc lấy chuỗi ngẫu nhiên Tạo ảnh băng việc sử dụng thư viện của PHP Xác định nền và màu của chữ Ghi chuỗi vào ảnh } Kết quả của chương trình đó như sau: Hình 7: Minh hoạ giải pháp được viết bằng PHP Nhận xét: Mỗi lần chạy chương trình đều sinh ra được một nền với màu khác nhau và các chuỗi cũng được sinh ngẫu nhiên. Tuy nhiên đối với những ảnh ngẫu nhiên này, các chương trình nhận dạng chuyên nghiệp hoàn toàn có thể nhận dạng ra các ký tự đó bởi các ký tự trong những chuỗi đó không được làm biến dạng. Đồng thời những nền được sinh ra rất đơn giản, dễ dàng bị tách cạnh và các ảnh sinh ra lại không được gây nhiễu. Do đó nếu hệ thống nào sử dụng chương trình này để sinh mã xác nhận thì khả năng bị đăng nhập tự động là vẫn có thể. Mặt khác do sự sắp xếp của các ký tự gần như trên hai dòng, nên có thể hiểu chuỗi gồm “FUD4N1” cũng có thể hiểu là “FDN” ở dòng trên và “U41” ở dòng dưới. Do đó người dùng sẽ không biết nhập thế nào. Chương 2: Cơ sở lý thuyết Quá trình xây dựng thành phần sinh ảnh tự động là sự kết hợp của nhiều thuật toán. Đó là quá trình sinh chuỗi ngẫu nhiên, biến chuỗi ngẫu nhiên thành ảnh, sinh nền, ghép chuỗi ảnh vào nền, thực hiện biến đổi chuỗi ảnh theo các hình khác nhau, sử dụng các kỹ thuật để gây nhiều bề mặt ảnh. 2.1. Thuật toán sinh chuỗi ngẫu nhiên Mô tả thuật toán Đầu vào: Rỗng Đầu ra: Chuỗi gồm từ 6 đến 12 ký tự ngẫu nhiên Các bước thực hiện: Bước1: Khởi tạo một từ điển gồm các chữ cái trong bảng mã alphabel và các chữ số từ 0 đến 9 Bước 2: Xác định ngẫu nhiên số các ký tự sẽ được sinh ra Bước 3: Để sinh từng ký tự, lấy ngẫu nhiên môt ký tự trong từ điển. Bước 4: Lặp lại việc lấy ngẫu nhiên đó đến khi nào sinh đủ số ký tự thì dừng lại Thuật toán có thể được viết bằng ngôn ngữ C như sau void GenRanString(char *){ dict[] ="abcdefghijklmnopqrstuvxywz0123456789"; ndict = sizeof(dict)/sizeof(*dict); n = 6 +rand()%9; for(i=6; i<n; i++) s[i] = dict[rand()%ndict]; s[i] = 0; } 2.1.1. Tại sao lại sinh chuỗi gồm từ 6 đến 12 ký tự? Chúng tôi sinh ra chuỗi ngẫu nhiên gồm từ 6 đến 12 kỹ tự bởi nếu ít hơn 6 kỹ tự thì chương trình dò tìm tự động dễ dàng phát hiện được tổ hợp bộ ký tự sinh ra, còn nếu nhiều hơn 12 ký tự thì người dùng phải nhập nhiều ký tự làm tốn thời gian của người dùng. Vì vậy chúng tôi nghĩ rằng bộ chuỗi ngẫu nhiêu gồm từ 6 đến 12 ký tự là phù hợp, các chương trình dò tự động cũng rất khó dò được bộ ký tự đó và người dùng cũng không tốn thời gian cho việc nhập số ký tự đó. 2.1.2. Kỹ thuật biến đổi chuỗi thành ảnh Trong kỹ thuật biến đổi này chúng tôi sử dụng một bộ nhớ thiết bị ngữ cảnh - Memory Device Context(DC) để triển khai. Device Context là một cấu trúc chứa thông tin về thiết bị. Sử dụng DC để lưu trữ, khôi phục và thay đổi thuộc tính của đối tượng đồ hoạ Thuật toán Đầu vào: Một chuỗi ngẫu nhiên Đầu ra: Một ảnh chứa chuỗi ngẫu nhiên trên void TextToImage( image, string) { HDC dc = CreateDC("DISPLAY", NULL, NULL, NULL); HDC memdc = CreateCompatibleDC(dc); HBITMAP bmp = CreateCompatibleBitmap(dc, GetDeviceCaps(dc, HORZRES), GetDeviceCaps(dc, VERTRES)); SelectObject(memdc, bmp); SetFontForText(memdc, fontname, fontsize); SetTextColor(memdc, RGB(0,0,0)); GetTextExtentPoint(memdc, str, strlen(str), &sz); TextOut(memdc, 0, 0, str, strlen(str)); for(i=0; iheight; i++) for(k=0; kwidth; k++) { img->a[i][k] = GetPixel(memdc, k, i); } } Trong đó: HDC: Con trỏ tới thiết bị ngữ cảnh Hàm CreateDC("DISPLAY", NULL, NULL, NULL) tạo một thiết bị ngữ cảnh Hàm CreateCompatibleDC(dc) tạo một bộ nhớ thiết bị ngữ cảnh tương thích với thiết bị theo danh nghĩa CreateCompatibleBitmap(dc,GetDeviceCaps(dc,HORZRES), GetDeviceCaps(dc, VERTRES)) tạo một ảnh bitmap tương ứng với chiều rộng và chiều cao của thiết bị ngữ cảnh Hàm GetDeviceCaps(dc, HORZRES) trả về thông tin chiều ngang của thiết bị ngữ cảnh Hàm GetDeviceCaps(dc, VERTRES) trả về thông tin chiều cao của thiết bị ngữ cảnh Hàm SelectObject(memdc, bmp) chọn một ảnh bitmap đưa vào bộ nhớ thiết bị ngữ cảnh, ảnh mới sẽ thay thế ảnh cũ Hàm SetFontForText(memdc, fontname, fontsize) xác định kiểu chữ và kích cỡ cho chuỗi ảnh Hàm SetTextColor(memdc, RGB(0,0,0)) xác định màu của chuỗi ảnh Hàm GetTextExtentPoint(memdc, str, strlen(str), &sz) trả về chiều dài chuỗi ký tự Hàm TextOut(memdc, 0, 0, str, strlen(str)) ghi chuỗi ký tự ra bộ nhớ thiết bị ngữ cảnh GetPixel(memdc, k, i): trả về mầu của điểm ảnh (i, k) cho bộ nhớ thiết bị ngữ cảnh sz: kích cỡ của chuỗi ngẫu nhiên 2.2. Các thuật toán sinh ảnh nền 2.2.1. Tại sao phải sinh ảnh nền? Với những ảnh đơn giản, chương trình nhận dạng dễ dàng thực hiện việc tách cạnh, tìm biên, tách chuỗi ảnh ra khỏi nền để sau đó có thể thực hiện việc dò chuỗi ảnh ngẫu nhiên được sinh ra. Vì vậy để làm cho các thuật toán tách cạnh, tìm biên không hiệu quả chúng tôi sẽ cho sinh ra những nền có cấu trúc phức tạp hơn. 2.2.2. Sinh ảnh nền dạng dải màu (ribbon) Các dải màu được tạo ra rất đơn giản bằng cách sử dụng hàm tuyến tính hai biến. Phương pháp sinh là duyệt tất cả các điểm. Với mỗi điểm ta thay giá trị màu bằng giá trị của hàm số. Hàm số để sinh dải màu như sau: f(x, y) = 255 – a*x – b*y Trong chương trình, chúng tôi sử dụng ảnh 256 màu do đó phương trình chỉ cần cho hệ số 255. Trong trường hợp tổng quát, chúng ta có thể sử dụng phương trình đường thẳng: f(x, y) = a*x + b*y + c Có thể viết đơn giản thuật toán sinh dưới ngôn ngữ tựa lập trình như sau void GenRibbon(left, right, top, bottom) { for(x=left; x<right; x++) for(y=top; y<bottom; y++){ t = 255 – 8x – 6y; SetPixel(x, y, RGB(t+rand()%128, t+rand()%128, t)); } } Kết quả sau khi áp dụng thuật toán: Hình 8: Ảnh nền dạng dải màu 2.2.3. Sinh ảnh nền dạng vải sợi(Fabric) Miếng vải thường được trang trí với mẫu khác nhau. Các mẫu này được tạo ra bằng cách lặp lại một mẫu nguyên tố nào đó. Chúng tôi không dùng phương pháp này mà sử dụng hàm sin và cos vì bản thân hai hàm này tuần hoàn dẫn đến việc các mẫu tự động lặp lại. Công thức để sinh nền vải sợi như sau: Có thể viết đơn giản thuật toán sinh dưới ngôn ngữ tựa lập trình như sau: void GenFabric(left, right, top, bottom) { for(x=left; x<=right; x++) for(y= top;y<=bottom; y++){ pixel= SetPixel(x, y, RGB(pixel, pixel, pixel)); } } Kết quả sau khi áp dụng thuật toán Hình 9: Ảnh nền dạng vải sợi 2.2.4. Sinh ảnh nền dạng bàn cờ(Checkboard) Bàn cờ caro là bàn cờ gồm các ô đỏ và đen xen kẽ nhau. Để sinh ra bàn cờ caro chúng ta cần duyệt tất cả các điểm x, y theo chiều ngang và chiều dọc màn hình sau đó xác định vị trí của những ô mầu đỏ và đen để tô mầu tương ứng. Ở đây chúng tôi sử dụng hàm floor để xác định vị trí của các ô đỏ và đen. Công thức để sinh bàn cờ như sau: () Trong đó Hàm là hàm tìm số nguyên lớn nhất dưới Hàm là hàm tìm số nguyên lớn nhất dưới Ở đây độ lớn của các ô cờ phục thuộc vào hệ số của k. Nếu trị tuyệt đối của k càng nhỏ thì độ lớn của các ô cờ càng lớn. Ngược lại, trị tuyệt đối của k lớn độ lớn của các ô cờ càng nhỏ. Tuy nhiên việc lựa chọn các giá trị cho hàm RGB() cũng rất quan trọng, nó sẽ quyết định màu sắc của bàn cờ. Có thể viết đơn giản thuật toán dưới ngôn ngữ giả lập trình như sau void GenCheckboard(left, right, top, bottom) { for(x<left; x<right; x++) for(y=top; y<bottom; y++){ t = floor(x*0.7/12 ) + floor(y*0.7/12); SetPixel(x, y, RGB(t*256, t*256,t*128)); } } Kết quả sau khi áp dụng thuật toán Hình 10: Ảnh nền dạng bàn cờ 2.2.5. Sinh ảnh nền dạng tổ ong(Beehive) Xuất phát từ ý tưởng là các tổ ong thường gồm các ô tròn được sắp xếp rất đều nhau. Chúng ta có thể sinh ra kiểu nền này bằng cách sinh một mẫu tròn rồi sao chép lại nhiều lần mẫu này theo một hệ số nào đó. Tuy nhiên chúng tôi có thể tạo ra kiểu nền này bằng cách kết hợp hai hàm sin và cos bởi các hàm này là các hàm tuần hoàn dẫn đến khi kết hợp với nhau tạo thành các mẫu tròn tự động lặp. Công thức để sinh nền tổ ong như sau: Trong công thức này việc lựa chọn các giá trị của a và b cũng quyết định độ lớn và mức độ tròn của tổ ong. Trong quá trình triển khai chúng tôi chọn giá trị của b nằm trong khoảng (-1,1) và giá trị của b thường lớn hơn 1. Thuật toán để sinh nền kiểu tổ ong có thể được viết dưới ngôn ngữ tựa lập trình như sau: void GenBeehive(left, right, top, bottom) { for(x<left; x<right; x++) for(y<top; y<bottom; y++){ t = sin(x*cos(2)/3 ) + cos(y*cos(2)/3); SetPixel(x,y, RGB(t*10, t*16, t*40)); } } Kết quả sau khi áp dụng thuật toán Hình 11: Ảnh nền kiểu tổ ong 2.2.6. Sinh ảnh nền dạng sóng(Wave) Các con sóng được tạo ra đơn giản bằng cách duyệt tất cả các điểm, mỗi điểm ta thay giá trị màu bằng giá trị của hàm số. Hàm số là tổng của một hàm sin và toạ độ chiều cao của của ảnh. Các toạ độ ứng với chiều ngang của ảnh cho làm đối số của hàm sin. Công thức để vẽ con sóng: Công thức có thể được triển khai dưới ngôn ngữ tựa lập trình như sau: void GenWave(left, right, top, bottom) { for(x= left; x<right; x++) for(y= top; y<bottom; y++) { t = sin(x*sin(-1)/12 ) + (y*sin(-1)/15); SetPixel(x, y, RGB(t*19,t*12, t*256)); } } Kết quả sau khi áp dụng thuật toán Hình 12: Ảnh nền dạng sóng 2.2.7. Sinh ảnh nền dạng các hình chữ nhật(Rectangle) Chúng tôi sử dụng công thức để sinh các hình chữ nhật như sau: Trong đó là hàm tính sine hyperbolic của là hàm xác định số nguyên bé nhất trên Công thức được triển khai như sau: void GenRectangle(left, right, top, bottom) { for(x= left; x<right; x++) for(y= top; y<bottom; y++) { t = sinh(x*tan(128)/25 ) + ceil(y*tan(128)/5); SetPixel(x, y, RGB(t*128,t*128, t*128)); } } Kết quả sau khi áp dụng thuật toán Hình 13: Ảnh nền dạng hình chữ nhật 2.2.8. Sinh ảnh nền dạng các đường tròn đồng tâm(HomoCentricCircle) Công thức để sinh đường tròn đồng tâm Thuật toán có thể được triển khai dưới dạng giả mã như sau: void GenHoCenCirlce(left, right, top, bottom) { for(x = left; x<right; x++) for(y = top; y<bottom; y++) { t = floor(x*y*tan(122)/12); SetPixel(x, y, RGB(t*128, t*128,t*128)); } } Trong quá trình triển khai công thức chúng tôi thấy rằng việc lựa chọn các giá trị cho hàm RGB() rất quan trọng, vì vậy chúng tôi đã chọn các giá trị của hàm RGB() như trên Kết quả sau khi áp dụng thuật toán Hình 14: Ảnh nền các đường tròn đồng tâm 2.2.9. Sinh ảnh nền dạng các đường tròn ngẫu nhiên(RandCircle) Sinh các đường tròn ngẫu nhiên đơn giản chỉ là tại các vị trí ngẫu nhiên nào đó trong không gian của bức tranh cần vẽ ta tô màu cho các đường tròn với bán kính khác nhau. Trong chương trình chúng tôi sử dụng hàm Ellipse để vẽ các đường tròn. Có thể viết thuật toán như sau: void GenRanCircle(HDC dc, int width, int height) { for(int i=0; i<150; i++) { int x = rand()%(width); int y = rand()%(height); int r = 10 + rand()%10; Ellipse(dc, x-r, y-r, x+r, y+r); } } Kết quả sau khi áp dụng thuật toán Hình 15: Ảnh nền là các đường tròn ngẫu nhiên 2.2.10. Sinh ảnh nền dạng đá hoa cương (Granite) Đá hoa cương là một mảnh đá được tạo ra từ các hạt cát có các màu khác nhau. Do đó chúng ta có thể tạo ra đá hoa cương bằng cách đơn giản là đưa ra ngẫu nhiên các điểm có màu khác nhau. void granite(left, right, top, bottom) { for(x=left; x<=right; x++) for(y=top; y<=bottom; y++) { t = 120 + rand()%128; SetPixel(x,y, RGB(t*rand()%128, t*rand()%128, t*rand()%128)); } } Kết quả sau khi áp dụng thuật toán Hình 16: Ảnh nền dạng đá hoa cương 2.2.11. Sinh ảnh nền dạng thác nước (waterfall) Thác nước theo cách nhìn đơn giản chỉ là tập hợp các giọt nước song song đi từ đỉnh ảnh xuống đáy ảnh. Trong đó độ dài các giọt cũng như vị trí xuất phát của các giọt là ngẫu nhiên. Để tạo ra thác nước cần duyệt theo chiều ngang ảnh trước. Tại mỗi vị trí chiều ngang ta sẽ xây dựng giọt nước từ trên đỉnh ảnh xuống đáy ảnh. Tất nhiên là số điểm từ đỉnh tới đáy phải bằng đúng độ cao ảnh cần sinh. Do đó chúng ta cần duyệt theo chiều dọc của ảnh. Nhưng màu bắt đầu vẽ là một màu ngẫu nhiên r và độ lặp lại của màu hay độ dài của giọt nước là s ngẫu nhiên. Do vậy thuật toán của chúng ta như sau void waterfall(left, right, top, bottom) { for(x=left; x<=right; x++) { s = (rand()%256)<<10; r = 256+rand()%128<<3; for(y=top; y<=bottom; y++, r+=s); SetPixel(x, y, RGB(r + y, r + y, r + y)); } } Kết quả sau khi áp dụng thuật toán Hình 17: Ảnh nền Waterfall 2.3. Các thuật toán biến đổi bề mặt 2.3.1. Tại sao phải biến đổi bề mặt? Ngày nay có rất nhiều hệ nhận dạng rất nhạy, chúng có thể nhận dạng được chuỗi ảnh nếu kiểu của chuỗi là kiểu có sẵn trong hệ thống windows như chuỗi được làm béo, chuỗi nghiêng theo kiểu italic hay chuỗi được gạch chân. Do đó để tránh cho hệ nhận dạng này có thể phát hiện, chúng tôi đã thực hiện việc biến đổi bề mặt các chuỗi theo các cách khác nhau như biến bề mặt chuỗi thành dạng cong hình sin, biến chuỗi ảnh thành dạng hình thang, hình bình hành. Mỗi khi chuỗi ảnh được sinh ra, chúng sẽ được làm biến đổi bề mặt ngẫu nhiên có thể cong theo hình sin, hoặc có thể biến dạng theo kiểu hình thang hoặc cũng có thể biến dạng thành hình bình hành. 2.3.2. Thuật toán biến đổi theo hình sin Tư tưởng của thuật toán rất đơn giản, từ chuỗi ảnh ban đầu, copy chuỗi ảnh đến vị trí đã được làm cong sẵn. Như ta đã biết hàm sin, cos khi biểu diễn trên mặt phẳng toạ độ nó là một đường cong. Do đó ta sẽ copy chuỗi ảnh ban đầu và ghi lại dưới dạng một hàm của sin. Kết quả là sau khi thực hiện việc copy như trên chuỗi mà chúng ta ghi lại trên nền là một chuỗi cong theo dạng hình sin. Trong quá trình triển khai chúng tôi thực hiện việc biến đổi trên bộ nhớ DC, đây là kiểu bộ nhớ lưu trữ các ảnh vào trong bộ nhớ trước khi gửi chúng tới thiết bị ra, do đó toạ độ các điểm mới sẽ được tính theo công thức: x ‘= x y’ = y + a*sin(x/b) Trong đó: (x, y) là toạ độ ban đầu mà chuỗi được sinh ra ( x ‘, y’ ) là toạ độ sau khi được biến đổi Quá trình biến đổi ảnh thành dạng hình sin đã được triển khai như sau: Chúng tôi sử dụng vùng nhớ DC khi xuất ra màn hình có kích thước (400, 400). Trước tiên chúng tôi sinh chuỗi ngẫu nhiên trên vùng nhớ DC đó tại toạ độ (10, 300), đồng thời một ảnh nền có kích thước (400, 200) cũng được sinh trên DC tại toạ độ (0,0). Sau đó chúng tôi thực hiện việc copy chuỗi vừa sinh ra lên vùng nhớ có chứa ảnh nền theo công thức như trên. Do ảnh nền có kích thước (400, 200) nên khi lưu lại chúng ta chỉ nhận được ảnh với chuỗi đã được làm cong. Thuật toán được viết dưới ngôn ngữ lập trình như sau: void VariWithSin(){ CreateDC(400, 400) //Tạo vùng nhớ DC RandomString(str) //Sinh chuỗi ngẫu nhiên GenHoCenCircle(memdc, 400, 200); //Sinh nền TextOut(memdc, 10, 300, str, strlen(str)); //Ghi chuỗi ra bộ nhớ memdc for(i=0; i<str.width; i++) { for(k=0; k<str.height; k++) { long t = GetPixel(memdc, 10+k, 300+i); SetPixel(memdc, k+10, i+10*sin(k/18.0)+75, t); } } Quá trình thực hiện biến đổi được minh hoạ theo hình dưới đây Hình 18: Minh hoạ quá trình thực hiện biến đổi chuỗi ảnh theo hình sin Sau khi triển khai chương trình chúng tôi thu được kết quả như sau: Hình 19: Chuỗi ảnh cong theo hình sin Nhận xét: Với việc làm cong như trên, các hệ nhận dạng mặc dù có thể đọc được chuỗi ảnh trên nhưng rất dễ bị nhầm giữa các ký tự. Chúng sẽ không thể phân biệt được số 2 tại vị trí thứ 2 là chữ số “2” hay là chữ “z”, chữ “o” tại vị trị thứ 3 là chữ “o” hay số “0”, chữ o tại vị trí thứ 6 là chữ o hay chữ “D”, chữ s tại vị trí thứ 7 là chữ “s” hay số “5”. Do đó việc đăng nhập tự động rất khó thực hiện được. 2.3.3. Thuật toán biến đổi hình thang Công thức biến đổi tứ giác chúng tôi sử dụng được tính theo chiều trải xuống y trước và chiều ngang x sau. Các điểm mới (x', y') sẽ được tính theo công thức Trong đó các hệ số (xAy, yAy) và (xBy, yBy) là các đầu đường thẳng nằm ngang phụ thuộc vào y theo công thức sau Trong quá trình triển khai chúng tôi đã thực hiện việc biến đổi hình thang theo hai trường hợp: Trường hợp 1: Đáy lớn ở dưới, đáy nhỏ ở trên Trường hợp 2: Đáy lớn ở trên, đáy nhỏ ở dưới Sau khi áp dụng thuật toán ta thu được kết quả như sau: Hình 20a: Đáy nhỏ ở trên, đáy lớn ở dưới Hình 20b: Đáy lớn ở trên, đáy nhỏ ở dưới Hình 20: Minh hoạ biến đổi theo hình thang Nhận xét: Việc biến đổi chuỗi ảnh theo dạng hình thang làm cho các chữ bị nghiêng không theo một hướng nhất định, mà ta biết rằng việc nhận dạng chữ phải theo một mẫu nhất định do đó khi hướng hoặc độ nghiêng luôn luôn thay đổi thì việc nhận dạng không thể thực hiện được. Đồng thời khi biến đổi theo kiểu hình thang, nhiều chữ bị biến đổi đi làm cho hệ nhận dạng không thể xác định đó là chữ gì, ví dụ số “1” và số “7”, chữ “p” và “D”, chữ “g” và số “9” khi biến đổi đi trông khá giống nhau, tuy nhiên người dùng vẫn nhận được ra đó là chữ gì. 2.3.4. Thuật toán biến đổi hình bình hành Biến đổi bình hành là phép biến đổi vị trí theo công thức của hình bình hành. Một ảnh hình chữ nhật sẽ được biến đổi thành hình bình hành xác định bởi ba toạ độ. Công thức các toạ độ biến đổi như sau (x', y') = (x0, y0) + (a1, b1)x + (a2, b2)y Trong đó (x, y) là toạ độ của điểm trên ảnh cũ. x<width và y<height còn (x', y') là toạ độ của điểm trên ảnh mới tương ứng của điểm (x, y). Điểm gốc (x0, y0) là một điểm trên ảnh mới Điểm (x1, y1) xác định đường kéo theo chiều ngang của ảnh mới. Điểm (x2, y2) là điểm xác định đường trải xuống bên dưới của ảnh mới Sau khi triển khai thuật toán ta thu được kết quả: Hình 21a: Ảnh nghiêng sang phải theo kiểu hình bình hành Hình 21b: Ảnh nghiêng sang trái theo kiểu hình bình hành Hình 21: Minh hoạ biến đổi ảnh theo hình bình hành Nhận xét : Trong hình 21b, ta thấy rằng hệ nhận dạng sẽ không thể nhận dạng được đâu là số “9” và đâu là chữ “g” hoặc chữ nào là số “0” và chữ nào là chữ “o”. 2.4. Các thuật toán gây nhiễu bề mặt 2.4.1. Tại sao phải gây nhiễu bề mặt ? Cũng giống như biến đổi bề mặt, gây nhiễu bề mặt nhằm làm cho hệ nhận dạng khó tách riêng chuỗi ra để nhận dạng do đó nó không thể nhận dạng được chuỗi ảnh hoặc nhận dạng nhầm kỹ tự này sang ký tự khác. Có rất nhiều thuật toán để gây nhiễu bề mặt nhưng trong khoá luận này chúng tôi chú trong đến bốn thuật toán chính đó là gây nhiễu bằng các điểm, gây nhiễu bằng các đường thẳng ngẫu nhiên, gây nhiễu bằng các đường cong ngẫu nhiên và gây nhiễu bằng các đường tròn. 2.4.2. Gây nhiễu bằng các điểm ngẫu nhiên Thuât toán này rất đơn giản, chúng ta chỉ cần lấy ngẫu nhiên một điểm và tô màu điểm đó Thuật toán có thể viết lại như sau void GenRanPoint(int x, int y, unsigned char color) { SetPixel(x, y, color) ; } Kết quả sau khi triển khai chương trình : Hình 22: Gây nhiễu ảnh bằng các điểm ngẫu nhiên Ta thấy rằng, với việc gây nhiễu như trên, các hệ nhận dạng rất khó nhận dạng ra có chuỗi xuất hiện bên trên. Hơn nữa việc các điểm gây nhiễu còn có tác dụng đánh lừa hệ nhận dạng bởi với việc làm nhiễu như trên, các chữ tại vị trí thứ 4 và thứ 5 là chữ r và v gần như dính vào nhau trở thành một chữ. Do đó hệ nhận dạng không thể xác định được đó là chữ gì. 2.4.3. Gây nhiễu bằng các đường thẳng ngẫu nhiên Để sinh đường thẳng chúng tôi sử dụng thuật toán DDA(Digital Differential Analizer) Có thể miêu tả ngắn gọn thuật toán như sau Xét phương trình tham số theo t (x1, y1) x(t) = x1 + t*(x2-x1); (x2, y2) y(t) = y1 + t*(y2-y1); Bắt đầu với t = 0; Tại mỗi bước tăng t một lượng dt xmới = xcũ + ymới = ycũ + Chọn giá trị thích hợp cho dt sao cho không bỏ mất điểm nào nghĩa là cần <1 và <1; Chọn dt là giá trị max của dx và dy Có thể viết đơn giản thuật toán sinh dưới ngôn ngữ tựa lập trình như sau: void GenRanDdaLine(x1, y1, x2, y2) { a = (x2-x1); b = (y2-y1); dt = 1.0 / ( fabs(a)>fabs(b) ? fabs(a)+1 : fabs(b)+1 ); for( t=0; t<=1; t+=dt) { x = x1 + a*t; y = y1 + b*t; SetPixel(x, y, random(256)); } } Kết quả sau khi áp dụng thuật toán: Hình 23: Gây nhiễu ảnh bằng các đường thẳng Nhận xét : Khi nhận dạng các hệ nhận dạng sẽ bị nhầm chữ “u” tại vị trí thứ 4 thành chữ “o” bởi đường thẳng đã đè lên đầu chữ “u” nên khi nhận dạng chúng chỉ xác định được tại vị trí đó có những điểm ảnh tạo thành một vòng tròn giống chữ  “o”. Chữ s tại vị trí thứ 6 chắc chắn sẽ bị nhầm thành số 8 bởi đường thẳng đi ngang qua hai đầu chữ “s” tạo thành một ký tự trông giống số 8. Tuy nhiên đối với người dùng, họ sẽ xác định được chính xác đó là chữ “s”. Do đó việc gây nhiễu bằng đường thẳng để tránh nhận dạng có hiệu quả khá cao. 2.4.4. Gây nhiễu bằng các đường cong ngẫu nhiên Chúng tôi sử dụng công thức Bezier – Berstain để sinh các đường cong ngẫu nhiên. Công thức được xác định như sau : p(u) = Bi, n(u)pi Trong đó Bi, n(u) = C(n, i)*ui*(i-u)n-i C(n,i) = p0...pn: Vector vị trí của đa giác n+1 đỉnh Triển khai thuật toán dưới dạng chương trình như sau: void Bezier_curve(const int *cp) { for( u=0.0005;u<=1;u+=0.0005) { x=0; y=0; for(k=0;k<=3;k++) { x+=(cp[(k*2)]*nCr(3,k)*pow(u,k)*powl((1-u),(3-k))); y+=(cp[((k*2)+1)]*nCr(3,k)*pow(u,k)*powl((1-u),(3-k))); } SetPixel((int)(x+0.5),(int)(y+0.5),color); } } Trong đó nCr(3, k) là tổ hợp chập k của 3 pow(u, k) là hàm tính u mũ k Kết quả sau khi áp dụng thuật toán: Hình 24: Gây nhiễu ảnh bằng các đường cong Việc gây nhiễu bằng các đường cong là một trong những biện pháp gây nhiễu nhằm làm cho các hệ nhận dạng không thể nhận dạng chính xác các ký tự được sinh ra. Trong hình 24, chính sự gây nhiễu đã che mất đặc điểm nhận dạng của chữ “e” tại vị trí thứ 7. Khi đó các hệ nhận dạng sẽ bị nhầm thành chữ “c” bởi vòng tròn trên đầu chữ “e” đã bị đường cong che mất. Hơn nữa nhiều đường cong được sinh ngẫu nhiên trông rất giống các chữ cái như chữ “c”, chữ “s”, chữ “z”, chữ “g”, hay số “9”. Vì thế các hệ nhận dạng không thể biết được đó là ký tự trong chuỗi xác nhận hay là đường cong gây nhiễu. 2.4.5. Gây nhiễu bằng các đường tròn ngẫu nhiên Để làm nhiễu ảnh bằng các đường tròn ngẫu nhiên, chúng tôi sử dụng thuật toán Bresenham để vẽ các đường tròn[4] Phương trình đường tròn có toạ độ tâm là xt và yt: (x - xt)2 + (y - yt)2 = R2 Xét đường tròn có tâm tại gốc toạ độ. Cho x thay đổi mỗi bước một đơn vị từ 0 đến R. giả sử nếu bắt đầu từ điểm xi thì giá trị của xi+1 = xi + 1 Từ phương trình đường tròn, giá trị y thực sự thuộc đường tròn với giá trị toạ độ xi+1 là: y2 = R2 – (xi + 1)2 Đặt d1 và d2 là khoảng cách từ vị trí nguyên yi và yi+1 đến vị trí y thật của đường tròn khi x = xi+1. Ta có: d1 = yi2 – y2 = yi2 – R2 + (xi+1)2 d2 = y2 – (yi - 1)2 = R2 – (xi + 1)2 – (yi - 1)2 Việc xét chọn điểm yi hay yi+1 phụ thuộc vào kết quả so sánh giữa hai giá trị d1 và d2. Giả sử đặt pi = d1 – d2. Lúc này việc so sánh d1 và d2 được thay bằng việc so sánh pi với 0. pi = 2*(xi + 1)2 + yi2 + (yi - 1)2 – 2*R2 Có 3 trường hợp xảy ra: - Trường hợp 1: d1<d2 nên pi < 0, điểm chọn là yi(đường tròn nằm hoàn toàn trên với giá trị yi) - Trường hợp 2: d1>d2 nên pi >0, điểm chọn là yi-1(đường tròn nằm dưới với giá trị yi-1) - Trường hợp 3: đường tròn nằm giữa yi và yi-1 Thuật toán được viết dưới dạng giả mã như sau: void BresenhamCircle(Radius) { p = p -2*Radius x = 0, y = Radius for x =0 to R if p<0 then p = p + 4*x +6; else if p>=0 then y = y-1; p = p + 4*x +10; SetPixel(x, y); Lặp lại bước trên cho đến khi x = y } Kết quả sau khi áp dụng thuật toán: Hình 25: Gây nhiễu ảnh bằng các đường tròn Nhận xét: Trong quá trình nhận dạng các hệ nhận dạng không thể phân biệt các đường tròn gây nhiễu có phải là một phần của chuỗi xác nhận hay không, bởi các đường tròn này trông giống chữ “o” và số “0”. Tuy nhiên con người vẫn có thể phân biệt được đâu là đường tròn gây nhiễu, đâu là chữ “o” hoặc số “0”. Trong hình 25, chữ “f” và số “7” đứng cạnh nhau tại vị trí 1, 2, khi nhận dạng các chương trình nhận dạng sẽ bị nhầm là một ký tự “n”. Khi đọc đến vị trí số 5, chúng không thể biết được đó là ký tự gì, số “0” hay chữ “o” hay số “6”. 2.4.6. Kết hợp các kiểu gây nhiễu Với mỗi kiểu gây nhiễu chúng tôi nhận thấy rằng cũng khá đảm bảo cho các hệ nhận dạng không thể nhận dạng được chuỗi ảnh. Tuy nhiên trong triển khai, để đảm bảo chắc chắn hơn chúng tôi đã kết hợp các kiểu gây nhiễu lại với nhau đối với mỗi lần chuỗi ngẫu nhiên sinh ra, có thể là kết hợp giữa các điểm với đường thẳng, có thể là kết hợp giữa đường thẳng và đường cong, có thể kết hợp giữa đường thẳng với đường tròn hoặc có thể kết hợp ba hoặc cả bốn kiểu gây nhiễu lại với nhau. Đồng thời chuỗi lại được biến đổi theo các kiểu khác nhau. Khi đó chúng tôi nghĩ rằng các hệ nhận dạng dù rất nhạy cũng khó có thể xác định được đúng chuỗi ngẫu nhiên vừa sinh ra. Kết quả sau khi áp dụng các kiểu gây nhiễu: Hình 26a: Kết hợp các kiểu gây nhiễu Nhận xét: Đối với người dùng việc nhận dạng chuỗi ảnh trên là hoàn toàn dễ dàng, tuy nhiên đối với các hệ nhận dạng, chúng sẽ bị nhầm chữ “z” tại vị trí thứ 2 thành chữ “N”, chữ “g” tại vị trí thứ 6 sẽ bị nhầm thành số “8”. Bởi khi muốn nhận dạng một ký tự có phải là số 8 không, các hệ nhận dạng sẽ kiểm tra xem trên ký tự đó có hai vòng tròn ở trên và ở dưới dính vào nhau không, nếu có đặc điểm như thế, chúng sẽ nhận là số 8, mà chữ “g” ở hình trên, do đường thẳng gây nhiễu đã đi qua đuôi của chữ g tạo thành hai vòng tròn ở trên và dưới có dính vào nhau, nên chúng sẽ nhận thành số “8”, còn số “5” tại vị trí thứ 7 chúng sẽ nhận thành số 6 Hình 26b: Minh hoạ kết hợp các kiểu gây nhiễu Với việc làm nhiễu và biến đổi chuỗi ảnh như trên, hệ nhận dạng sẽ không thể nhận dạng đúng được chữ “p” tại vị trí 3 và thứ 6, chúng sẽ nhận dạng nhầm thành chữ “D”, số “8” chúng sẽ nhận dạng thành chữ 2 chữ là chữ “E”và số “3”, còn chữ “o” sẽ nhận là số “8”. Do đó nếu hệ nhận dạng có thể phân tích được chuỗi ký tự và nhập chuỗi mà chúng phân tích vào ô xác nhận thì cũng không chính xác, vì vậy hệ thống ngăn chặn được việc đăng nhập tự động. Chương 3: Triển khai thành phần 3.1. Cấu trúc của tập tin ảnh bitmap Do chúng tôi dùng ảnh bitmap để triển khai chương trình vì vậy sau đây chúng tôi sẽ trình bày cấu trúc của ảnh bitmap. Mỗi tập tin bitmap gồm tiêu đề chứa thông tin chung về tệp tin, thông tin bitmap chứa các thông tin về ảnh bitmap, một bảng màu và một mảng dữ liệu ảnh. Khuôn dạng được cho như sau : Tiêu đề (header) Thông tin ảnh (bitmap infor) Bảng màu (palette) có thể có hoặc không Dữ liệu ảnh (image data) 3.1.1. Tiêu đề ảnh Gồm năm trường lưu các thông tin như kích thước tập tin, địa chỉ bắt đầu dữ liệu ảnh, và chữ ký của ảnh. Có thể mô tả thông tin về phần đầu của ảnh như sau : typedef struct tagBITMAPFILEHEADER { UINT bfType; DWORD bfSize; UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits; }BITMAPFILEHEADER; Dưới đây là giải thích chi tiết: Tên trường Kích thươc tính bằng Byte Mô tả bfType 2 Xác định kiểu của tệp tin. bfType sẽ luôn trả lại “19778”, đây là mã của 2 ký tự “BM”. Tất cả các tệp tin ảnh bitmap đều bắt đầu với 2 ký tự trên bfSize 4 Xác định kích thước của tệp tin tính bằng byte bfReserved1 2 Đây là vùng không gian dành riêng, chưa được dùng đến- được đặt bằng 0 bfReserved2 2 Đây là vùng không gian dành riêng, chưa được dùng đến- được đặt bằng 0 bfOffBits 4 Xác định offset từ phần đầu của tệp tin tới dữ liệu ảnh, thường là 1078 3.1.2. Thông tin ảnh Có rất nhiều thông tin trong phần thông tin ảnh. Tuy nhiên chúng ta quan tâm đến độ rộng (width), độ cao (height), số bit cho điểm ảnh (bitcount). typedef struct tagBITMAPINFOHEADER{ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; Dưới đây là giải thích chi tiết: Tên trường Kích thước tính bằng Byte Mô tả biSize 4 Kích thước của BITMAPINFOHEADER, ít nhất phải bằng 40 biWidth 4 Chiều rộng của ảnh tính bằng số điểm ảnh biHeight 4 Chiều cao của ảnh, tính bằng số điểm ảnh biPlanes 2 Số plane cho thiết bị đích, được đặt bằng 1 biBitCount 2 Số bit trên 1 điểm ảnh – 1, 4, 8, 24 biCompression 4 Kiểu nén, bằng 0 nếu ảnh không nén biSizeImage 4 Kích thước của ảnh tính bằng byte - bằng 0 cho trường hợp ảnh không nén biXPelsPerMeter 4 Độ phân giải được ưu tiên theo chiều ngang, tính bằng điểm ảnh trên mét biYPelsperMeter 4 Độ phân giải được ưu tiên theo chiều dọc, tính bằng điểm ảnh trên mét biClrUsed 4 Số lượng màu thực sự được sử dụng biClrImportant 4 Số lượng màu cần thiết cho việc hiển thị, bằng 0 nếu tất cả các màu đều cần để hiển thị Trong đó biBitCount xác định độ phân giải màu của tệp tin bitmap. Nếu biBitCount giá trị bằng: 1 bit Ảnh bitmap có 2 màu đen và trắng, bảng màu trong file chứa 2 điểm vào, mỗi bit trong mảng bitmap biểu diễn 1 điểm ảnh. Nếu bit trong dữ liệu ảnh là clear, điểm ảnh có màu của điểm vào đầu tiên trong bảng màu. Nếu bit là set, điểm ảnh có màu của điểm vào thứ hai trong bảng màu 4 bit Ảnh bitmap có tối đa 16 mầu, bảng màu chứa 16 điểm vào. Mỗi byte trong dữ liệu ảnh biểu diễn 2 điểm ảnh. Mỗi byte này lại được chia thành 4 bit cao và 4 bit thấp 8 bit Ảnh bitmap có tối đa 256 màu, bảng màu chứa 256 điểm vào. Trong trường hợp này, mỗi byte trong mảng biểu diễn 1 điểm ảnh đơn. 24 bit Ảnh bitmap có tối đa 2^24 màu, bảng màu rỗng. Cứ mỗi 3 byte liên tiếp trong mảng bitmap biểu diễn 1 điểm ảnh. Byte đầu tiên biểu diễn màu đỏ, byte thứ 2 biểu diễn màu lục, byte thứ 3 biểu diễn màu lam 3.1.3. Bảng màu typedef struct{ BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; }RGBQUAD; Giải thích Tên trường Kích thước tính theo byte Mô tả rbgBlue 1 Xác định cường độ của màu lam rbgGreen 1 Xác định cường độ của màu lục rbgRed 1 Xác định cường độ của màu đỏ rbgResrved 1 Không sử dụng, được đặt bằng 0 3.1.4. Dữ liêu ảnh Là một mảng chứa các byte của ảnh bitmap. Đây là dữ liệu ảnh thật, được biểu diễn bởi các hàng liên tiếp nhau hay còn gọi là những đường quét của ảnh bitmap. Mỗi đường quét chứa các byte liên tiếp nhau từ trái qua phải. Điểm ảnh được hiển thị trên màn hình ngược với điểm ảnh được lưu trong tệp tin bitmap. Số byte trong một hàng phải luôn luôn là bội của 4. Nếu một hàng mà tổng số byte chưa phải là bội của 4 thì các byte 00 sẽ được thêm vào cho đến khi là bội của 4. 3.2. Thủ tục hỗ trợ để triển khai chương trình 3.2.1. Cấu trúc ảnh struct image { long width; //Chiều rộng của ảnh long height; //Chiều cao của ảnh unsigned char **pix; //Dữ liệu ảnh long pal[256]; //Bảng màu } 3.1.2. Thủ tục hỗ trợ Ảnh khi sinh ra nó được lưu trên trên bộ nhớ, để có thể sử dụng được ảnh vừa sinh, thì cần phải có một thủ tục hỗ trợ, đó là thủ tục ghi ảnh từ bộ nhớ ra tệp. Có thể tóm tắt thủ tục đó như sau: Đầu vào: Cấu trúc ảnh Đầu ra: tệp tin chứa ảnh Các bước thực hiện Bước 1: Mở tệp tin để ghi theo kiểu nhị phân Bước 2: Ghi tiêu đề của ảnh bitmap vào tệp tin cần ghi Bước 3: Ghi thông tin ảnh của ảnh bitmap vào tệp tin Bước 4: Duyệt tất cả các điểm ảnh Bước 5: Ghi dữ liệu ảnh bitmap vào tệp tin Thuật toán có thể được viết lại bằng C như sau void SaveImageBmp(LPIMAGE img, LPCTSTR lpFileName) { FILE *file; //Mở tệp tin để ghi theo kiểu nhị phân file = fopen(lpFileName, "wb"); //Ghi tiêu đề của ảnh bitmap fwrite("BM", 2, 1, file); lbuf = 40+14+img->width*img->height*4;fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = 0; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = 40+14; fwrite(&lbuf, sizeof(lbuf), 1, file); //Ghi thông tin ảnh của ảnh bitmap lbuf = 40; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = img->width; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = img->height; fwrite(&lbuf, sizeof(lbuf), 1, file); sbuf = 1; fwrite(&sbuf, sizeof(sbuf), 1, file); sbuf = 32; fwrite(&sbuf, sizeof(sbuf), 1, file); lbuf = 0; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = img->width*img->height*4; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = 0; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = 0; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = 0; fwrite(&lbuf, sizeof(lbuf), 1, file); lbuf = 0; fwrite(&lbuf, sizeof(lbuf), 1, file); //Ghi dữ liệu ảnh for(i=img->height-1; i>=0; i--) for(k=0; kwidth; k++) fwrite(&img->a[i][k], sizeof(img->a[i][k]), 1, file); } 3.3. Tạo và sử dụng thành phần phục vụ 3.3.1. Định nghĩa ActiveX DLL DLL là tệp tin thư viện bên ngoài không bị rằng buộc với chương trình. Nó chứa ở một nơi sao cho tệp tin EXE có thể tìm ra và gửi thông điệp cho nó. Khi thi hành, các thông điệp này là những cuộc gọi đến các hàm/ thủ tục, yêu cầu chương trình của DLL được thi hành. ActiveX là một hệ thống tiêu chuẩn dùng để xây dựng các thành phần (component) trong môi trường Internet. Các thành phần này không những có khả năng vận hành một cách độc lập mà còn có thể được khai thác bởi các thành phần khác. Đây là những thành phần được viết bằng nhiều ngôn ngữ khác nhau và rất đa dạng, có thể là các ActiveX Control (điều khiển độc lập ) để nhúng vào chương trình khác từ lúc thiết kế chương trình, có thể là các ActiveX DLL (thư viện liên kết động) mà các chương trình khác tham chiếu đến,v.v... ActiveX được thiết kế đặc biệt thích hợp với những ứng dụng Internet và các phần mềm tuân theo COM (Component Object Model), là chuẩn công nghiệp do Microsoft khởi xướng. ActiveX là một đối tượng, nhưng không phải bất cứ đối tượng nào cũng là ActiveX mà nó phải tuân theo hai tiêu chuẩn chính: đó là đối tượng COM và có khả năng tự đăng ký. Nói một cách đơn giản: ta có thể hiểu ActiveX là những đoạn chương trình độc lập thực hiện một chức năng nào đó mà có thể được gọi bởi những ứng dụng bất kỳ khác. Khi xây dựng một ứng dụng, chúng ta nên sử dụng những ActiveX với chức năng phù hợp để tiết kiệm thời gian và công sức nhờ tận dụng được thành quả lao động của người khác, đã tạo nên bằng ActiveX. Với những sáng kiến hay, những ý đồ mới mà chúng ta muốn phổ biến rộng rãi cho nhiều người thì cách đơn giản và tiện lợi nhất là đưa ý tưởng đó thành ActiveX. Đồng thời phát triển dựa trên ActiveX đang là xu hướng của công nghệ phần mềm. Các ActiveX này, có thể được mọi người sử dụng khi xây dựng ứng dụng. Các đối tượng của ActiveX rất phong phú. ActiveX là đối tượng COM và có thể được xây dựng từ nhiều ngôn ngữ lập trình khác nhau. Vậy ActiveX DLL là thư viện DLL xây dựng theo chuẩn ActiveX. Các thư viện DLL theo chuẩn ActiveX có thể được dùng trong các trang Web. Việc kết hợp ActiveX (AX) vào các trang Web đã mở rộng khả năng cho người lập trình. Với AcrtiveX, trang Web trở nên tinh vi và đa năng hơn nhiều so với trang Web không sử dụng ActiveX. ActiveX cho khả năng xây dựng những trang Web chuyên nghiệp một cách không hạn chế. Tuy nhiên, nó cũng có thể bị lợi dụng để phá hoại hệ thống. Các trình duyệt có cơ chế bảo mật để phòng ngừa vấn đề đó. 3.3.2. Cách tạo ra thành phần phục vụ Định nghĩa Thành phần phục vụ (server component) là một phần mềm dạng thư viện liên kết động có thể nhúng trong các trang tài liệu HTML hoặc trang ASP. Bản thân thành phần phục vụ không chạy được như phần mềm, mà nó chỉ chạy khi được nhúng trong phần mềm khác. Để cài thành phần phục vụ, có hai cách, hoặc cài trên Visual Basic hoặc cài trên Visual C++. Chúng tôi sẽ giới thiệu cách tạo ra thành phần phục vụ bằng Visual Basic, cách cài đặt một thành phần phục vụ, và sử dụng thành phần phục vụ trong trang ASP. Tạo ra trình án (ImageProc.vbp) Tạo trình án kiểu ActiveX DLL với tên ImageProc Viết lớp phục vụ Image Tạo ra thư viện liên kết động (ImageProc.dll) Biên dịch tạo ra tập tin thư viện liên kết động (File -> Make) Cài đặt thành phần phục vụ (WebImageRegistry.bat) Để cài đặt thành phần phục vụ, chúng ta dùng chương trình regsvr32 với tên thư viện mà chúng ta tạo ra trong quá trình tạo thư viện trên. regsvr32 Chúng ta nên tạo ra tập tin bat để đăng ký tập tin để chạy cho nhanh. Tập tin bat đặt ngay cùng thư mục với thư viện. @echo off regsvr32 ImageProc.dll 3.3.3. Sử dụng thành phần trong trang tin Sau khi đã đăng ký thành phần vào hệ thống, chúng ta có thể sử dụng các thành phần với JavaScript. i = new ActiveXObject("ImageProc.Image"); i.GetImage(); i.GetString(); delete i; 3.4. Trang tin sử dụng thành phần 3.4.1. Cách viết trang đăng nhập Đăng nhập vào hệ thống Tên người dùng Dòng chữ xác thực (đánh lại dòng chữ trong ảnh phía dưới) <%set ie = Server.CreateObject("ImageProc.Image") Session("AnhXacThuc") = ie.GetImage() Session("ChuoiXacThuc") = ie.GetString() %> " width="300" height="120" alt="Anh xac thuc" style="background-color: #00FF00"> 3.4.2. Cách viết trang xử lý đăng nhập Session("ChuoiXacThuc") then%> Cách bạn đăng nhập giống như một chương trình đăng nhập tự động để dò mật khẩu. Bạn phải đánh đúng dòng chữ xuất hiện trong ảnh phía dưới. Ấn chuột vào đây để trở về màn hình đăng nhập Bạn đã đăng nhập thành công Chương 4: Thực nghiệm 4.1. Môi trường thực nghiệm Thư viện của chương trình được cài đặt trên ngôn ngữ Visual C++ 6.0. Sử dụng Visual Basic 6.0 để xây dựng thành phần phục vụ. Sử dụng ngôn ngữ ASP kết nối thành phần phục vụ để tạo ra trang tin thực nghiệm. Chương trình được thử nghiệm trên hệ điều hành Windows SP2, máy tính PC tốc độ 1.5 GHz, bộ nhớ 128 MB RAM. 4.2. Thực nghiệm và kết quả Chúng tôi đã xây dựng trang đăng nhập đơn giản có sử dụng ảnh xác nhận có giao diện như sau: Hình 27: Giao diện khi triển khai thành phần vào hệ thống đơn giản Qua quá trình thực nghiệm, chúng tôi thấy rằng thành phần sinh ảnh tự động đã hoạt động khá tốt. Mỗi lần đăng nhập, đều có một chuỗi ảnh ngẫu nhiên xuất hiện. Nếu nhập đúng tên mã xác nhận, hệ thống sẽ cho đăng nhập bằng cách thông báo đã đăng nhập thành công. Nếu nhập sai mã xác nhận, một chuỗi ảnh xác nhận mới sẽ sinh ra và người dùng phải nhập lại mã số xác nhận này. Hình 28: Giao diện trang thông báo khi người dùng đăng nhập thành công Mặc dù đã cho chương trình chạy thử nghiệm nhiều lần nhưng chúng tôi chưa thấy chuỗi ảnh nào bị lặp lại. Do đó chúng tôi nghĩ rằng thành phần sinh ảnh tự động mà chúng tôi xây dựng hoàn toàn ngăn chặn được các chương trình đăng nhập tự động 4.3. Các vấn đề phát sinh Cũng trong quá trình thực nghiệm, chúng tôi thấy rằng thỉng thoảng một số chuỗi ảnh được sinh ra, người dùng không thể xác định đúng hoàn toàn chuỗi ký tự mà hệ thống đã sinh ra bởi các đường gây nhiễu đã che mất một vài đặc điểm nhận dạng của một số ký tự. Mặt khác nhiều khi màu của nền và màu của các đường gây nhiễu gần giống với màu của chuỗi ảnh nên người dùng rất khó nhận biết chuỗi ảnh đã sinh ra Ví dụ trong hai hình dưới đây, một số ký tự có thể nhận biết được, còn một số khác rất khó xác định. Trong hình 29a, tại vị trí thứ 3 chúng tôi không thể nhận biết chính xác đó là chữ gì, chỉ có thể đoán đó là chữ “o” hoặc là chữ “c”. Tại vị trí thứ 6 cũng rất khó xác định đó là số “3” hoặc số “8”. Đồng thời, do sự biến đổi của chuỗi và việc gây nhiễu đôi khi có thể làm người dùng nhầm giữa các ký tự “0” và “o”, “1” và “7”, “f” và “t”, “fi” và “n”, “9” và “g”, “s” và “5”, “z” và “2”. Hình 29a: Minh hoạ ảnh người dùng không nhận dạng được Hình 29b: Minh hoạ ảnh người dùng không nhận dạng được Hình 29: Một số ảnh mà người dùng không nhận được Đối với hai hình trên, việc người dùng xác định chính xác chuỗi ảnh là rất khó. . Trong hình 29b, các đường thẳng gây nhiễu đã che khuất đặc điểm nhận dạng của các chữ tại vị trí 3, 4 và 6. Tại vị trí thứ 3 và 4, hoặc là chữ “e”, hoặc chữ “o” hoặc chữ “c”. Tại vị trí thứ 6, có thể là chữ “i”, hoặc chữ “l”, hoặc là chữ “n”. Vì vậy người dùng cũng không xác định được đúng chuỗi mà hệ thống đã sinh ra . Trong trường hợp này, người dùng cần phải thay thế bằng ảnh xác nhận mới. Kết luận Qua thời gian nghiên cứu và xây dựng thành phần sinh ảnh chống đăng nhập tự động chúng tôi đã đạt được một số kết quả như sau: Hiểu được thế nào là chương trình đăng nhập tự động và tác hại của nó khi nó đăng nhập được vào một hệ thống. Nắm được cách sinh các ảnh nền một cách tự động như sinh thác nước, sinh bàn cờ, sinh đá hoa cương…. Chúng tôi đã sinh chuỗi ngẫu nhiên và biến chuỗi đó thành ảnh. Nắm được các kỹ thuật về biến đổi ảnh như biến đổi ảnh theo dạng hình sin, hình bình hành, hình thang. Nắm được các thuật toán nhằm gây nhiễu cho bề mặt ảnh như gây nhiễu bằng điểm ảnh, gây nhiễu bằng các đường thẳng hay đường cong… Chúng tôi đã xây dựng thành công thành phần sinh ảnh chống đăng nhập tự động và thành phần này có khả năng gắn vào các hệ thống để hệ thống ngăn chặn các chương trình đăng nhập tự động. Chương trình của chúng tôi so với một số hệ thống đã triển khai thành phần sinh ảnh chống đăng nhập tự động như yahoo, hotmail, gmail thì chúng tôi đã đưa ra được một số cải tiến đáng kể đó là chúng tôi sinh được nhiều nền phức tạp hơn, có nhiều cách để biến đổi các chuỗi ảnh, có nhiều cách gây nhiễu khác nhau hơn và mức độ gây nhiễu cũng phức tạp hơn. Vì vậy chúng tôi nghĩ rằng thành phần mà chúng tôi xây dựng có thể ngăn chặn khá tốt các các chương trình nhận dạng để đăng nhập tự động. Bên cạnh những kết quả đã đạt được, còn có một số vấn đề mà chúng tôi chưa giải quyết được đó là xây dựng và triển khai trên cấu trúc của các loại ảnh khác như ảnh gif, ảnh jpeg. Trong thời gian tới chúng tôi sẽ tiếp tục nghiên cứu và xây dựng để giải quyết vấn đề trên. Tài liệu tham khảo Tài liệu tiếng Việt [1] Lương Mạnh Bá, “Nhập môn xử lý ảnh số”, NXB khoa học và kỹ thuật năm 2003. [2] Vũ Thị Đào, “Kỹ thuật cộng ảnh và ứng dụng”, Khoá luận tốt nghiệp năm 2005, ĐHCN, ĐHQGHN. [3] Thế Thị Hường, “Kỹ thuật trừ ảnh và ứng dụng”, Khoá luận tốt nghiệp năm 2005, ĐHCN, ĐHQGHN. [4] Lê Tấn Hùng, Huỳnh Quyết Thắng, “Kỹ thuật đồ hoạ”, NXB khoa học và kỹ thuật. Tài liệu tiếng Anh [5] Avi Rubin, Security Considerations for Remote Electronic Voting over the Internet. [6] David Jefferson, There are hazards in remote Net voting. [7] David Jefferson, Aviel D. Rubin, A Security Analysis of the Secure Electronic Registration and Voting Experiment. [8] Dwayne Phillips, Image Processing in C. [9] Frédéric Patin aka YOV408, An Introduction To Digital Image Processing. [10] Fundamentals of Image Processing. [11] Image Verification and Identification Application Programming Interface. [12] Laurent Deniau, Image Processing. [13] User Authentication With Image Verification. [14] Xin Li,Michael T. Orchard, New Edge-Directed Interpolation. [15] Word Verification [16] Website Image Processing Library / [17] Website [18] Website [19] Website verification/ [20] Website [21] Website [22] Website Phụ lục A – Danh mục các thuật toán Thuật toán sinh chuỗi ngẫu nhiên……………………………………………………...12 Kỹ thuật biến chuỗi thành ảnh…………………………………………………………13 Thuật toán sinh nền dải màu…………………………………………………………...14 Thuật toán sinh nền vải sợi…………………………………………………………….15 Thuật toán sinh nền bàn cờ…………………………………………………………….16 Thuật toán sinh nền tổ ong……………………………………………………………..18 Thuật toán sinh nền dạng sóng…………………………………………………………19 Thuật toán sinh nền hình chữ nhật……………………………………………………..20 Thuật toán sinh nền dạng đường tròn đồng tâm………………………………………..21 Thuật toán sinh nền dạng đường tròn ngẫu nhiên……………………………………...22 Thuật toán sinh đá hoa cương………………………………………………………….23 Thuật toán sinh thác nước……………………………………………………………...24 Thuật toán biến đổi hình sin……………………………………………………………25 Thuật toán biến đổi hình thang…………………………………………………………27 Thuật toán biến đổi hình bình hành…………………………………………………….29 Thuật toán gây nhiễu bằng các điểm ngẫu nhiên………………………………………30 Thuật toán gây nhiễu bằng đường thẳng ngẫu nhiên…………………………………..31 Thuật toán gây nhiễu bằng đường cong ngẫu nhiên…………………………………...33 Thuật toán gây nhiễu bằng đường tròn ngẫu nhiên ……………………………………34 Phụ lục B – Danh sách các hình Hình 1: Minh hoạ cho việc đăng nhập thông thường…………………………………...5 Hình 2: Giải pháp chống đăng nhập tự động……………………………………………5 Hình 3: Ví dụ về một ảnh xác nhận……………………………………………………..6 Hình 4: Ảnh xác nhận được Yahoo sử dụng khi người dùng đăng ký tài khoản mới….7 Hình 5: Ảnh xác nhận được Yahoo sử dụng mà người dùng vào hòm thư……………..8 Hình 6: Giải pháp của hotmail và gmail………………………………………………...9 Hình 7: Minh hoạ giải pháp được viết bằng PHP……………………………………...11 Hình 8: Ảnh nền dạng dải màu………………………………………………………...15 Hình 9: Ảnh nền dạng vải sợi………………………………………………………….16 Hình 10: Ảnh nền dạng bàn cờ………………………………………………………...17 Hình 11: Ảnh nền kiểu tổ ong………………………………………………………… 18 Hình 12: Ảnh nền dạng sóng…………………………………………………………..19 Hình 13: Ảnh nền dạng hình chữ nhật…………………………………………………20 Hình 14: Ảnh nền các đường tròn đồng tâm…………………………………………...21 Hình 15: Ảnh nền là các đường tròn ngẫu nhiên………………………………………22 Hình 16: Ảnh nền dạng đá hoa cương…………………………………………………23 Hình 17: Ảnh nền Waterfall……………………………………………………………24 Hình 18: Minh hoạ quá trình thực hiện biến đổi chuỗi ảnh theo hình sin……………...26 Hình 19: Chuỗi ảnh cong theo hình sin…………….…………………………………..27 Hình 20: Minh hoạ biến đổi theo hình thang……….………………………………….28 Hình 21: Minh hoạ biến đổi ảnh theo hình bình hành....................................................30 Hình 22: Gây nhiễu ảnh bằng các điểm ngẫu nhiên....................................................... 31 Hình 23: Gây nhiễu ảnh bằng các đường thẳng............................................................. 32 Hình 24: Gây nhiễu ảnh bằng các đường cong.............................................................. 34 Hình 25: Gây nhiễu ảnh bằng các đường tròn................................................................36 Hình 26: Minh hoạ kết hợp các kiểu gây nhiễu..............................................................37 Hình 27: Giao diện khi triển khai thành phần vào hệ thống đơn giản............................48 Hình 28: Giao diện trang thông báo khi người dùng đăng nhập thành công..................49 Hình 29: Một số ảnh mà người dùng không nhận được.................................................50 Mục lục

Các file đính kèm theo tài liệu này:

  • docKhoaluan.doc
  • docBia_Loicamon_Tomtat.doc