PHP 隨機字串與SHA1加密生成CAPTCHA的小bug

在前陣子撰寫PHP隨機產生6個字的string用GD來生出有雜訊的圖片,

作為防止spam bot 的機制;類似一張圖片上面會有6個隨機的字母與

雜訊,讓正常的使用者可以透過人眼與大腦分辨是哪6個字母。在這

過程有個很有趣的小bug,不知道是因為我的nas問題還是怎樣(我試過

我自己的Synology跟某人的QNAP都有同樣的問題....)會有加密前後string

被修改的情況。

先來看一下程式碼:
------------------------------------------------------------------------------
$pass_phrase = '';
for($i = 0 ; $i < 6 ; $i++)
{
$pass_phrase .= chr( rand( 97, 122 ) );
}

這邊為隨機產生6個ASCII 小寫的a-z 的字母並組成一個字串,通常
在生成之後會做個簡單加密:如下

-------------------------------------------------------------------------------
 $_SESSION['pass_phrase'] = sha1($pass_phrase);

這邊我們透過SHA1加密將生成的字串加密並將結果透過Session傳遞,

接著在$pass_phrase 這個『原始』字串丟給GD去畫在記憶體的圖片內
EX:
------------------------------------------------------------------------------
imagettftext($img, 18,0 , 5,CAPTCHA_HEIGHT-5, $text_color,$font,$pass_phrase);

接著看你是要用header去傳圖片並透過 imagepng 等之類似的函式去生成圖片
的二進位檔案。

但是此時會發現圖片上面的字碼卻跟原始的6個字碼不同,反而變成一串很

長的亂碼,後來發現這串亂碼就是SHA1加密過後的亂碼!詭異的事你用echo 

去列印$pass_phrase 就沒有這個問題,但是丟到GD函式去生成就是一直抓到

加密後的亂碼!這真的不知道是哪邊的問題~同樣的名稱 echo 是抓到原始字串

imagettftext卻是去抓到加密後的亂碼..... 至於怎麼解決呢-----很簡單!

就是把加密隨機字串挪到 GD畫字串之後就可以。
EX:
-------------------------------------------------------------------------------------
$pass_phrase = '';
for($i = 0 ; $i < 6 ; $i++)
{
$pass_phrase .= chr( rand( 97, 122 ) );
}
........
.......
......
imagettftext($img, 18,0 , 5,CAPTCHA_HEIGHT-5, $text_color,$font,$pass_phrase);
........
.......
 $_SESSION['pass_phrase'] = sha1($pass_phrase);

讓做SHA1的動作在imagettftext之後就好了。


留言