為了增強開發中的CPCMS framework的保安功能,除了加入一大堆加密函式之外,還要加入防止機械人的圖像驗證功能。在phpclasses.org找來了一個生成這種圖像的class - Captcha Numbers v2.1,但是它有兩個缺點,首先是它所生成的驗證字串包含一些容易令人混淆的字符,例如1, I, l, o, O, 0, Q。這個只要在產生了隨機字符之後加入ereg('^[01loIOQ]$', $char)來判別那是否容易被混淆的字符就可以了。

另一個問題是和顏色有關。有時候這個class所生成的字符顏色會使用些跟背景顏色很相近的色彩,如在白地上用上黃色和淺灰色。由於這種反機械人圖像上會有很多亂數點,有時連人類也難以分辨,所以便要避免使用灰度太低的顏色。為了解決問題,便得要知道class隨機選出的顏色灰度。

要從RGB顏色中知道那顏色的灰度,可以使用這條算式:

gray = 0.3 * red + 0.59 * green + 0.11 * blue

米奇就寫了一個method,加在captcha number class裡面,用來生成較易被人類看得到的顏色。如果因為難度太易而讓機械人也分辨得出的話,只要修改method中的$gray_threshold改為較大的數字就可以,上限自然是255了。

  1. // gray_threshold 設成180效果不錯
  2. function get_rgb($gray_threshold) {
  3. while (1) {
  4. $temp_r = mt_rand(0,255);
  5. $temp_g = mt_rand(0,250);
  6. $temp_b = mt_rand(0,250);
  7. $temp_gray = 0.3 * $temp_r + 0.59 * $temp_g + 0.11 * $temp_b;
  8. if ($temp_gray < $gray_threshold) break;
  9. }
  10. return array('red' => $temp_r, 'green' => $temp_g, 'blue' => $temp_b);
  11. }